diff --git a/.vpython b/.vpython
index d11e77f..8f66c0f 100644
--- a/.vpython
+++ b/.vpython
@@ -98,3 +98,10 @@
   name: "infra/python/wheels/boto-py2_py3"
   version: "version:2.48.0"
 >
+
+# Used by:
+#   testing/buildbot/generate_buildbot_json_coveragetest.py
+wheel: <
+  name: "infra/python/wheels/coverage/${vpython_platform}"
+  version: "version:4.3.4"
+>
diff --git a/DEPS b/DEPS
index 2148c4d..3a5fc5f 100644
--- a/DEPS
+++ b/DEPS
@@ -74,11 +74,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': '5031e5f8b77f9fedf7f0d662a0228bf423bcef71',
+  'skia_revision': '852ca318a16f9c455d2bed3efb2063dff0e4d068',
   # 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': 'b463eed75e8129843643189c0d08b3f9536faf66',
+  'v8_revision': '5929e23be66d807a0f6451d72b1ad05a78e86937',
   # 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.
@@ -86,7 +86,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '030017a4855c7b6e7f2ff8d9566c146f31eb301b',
+  'angle_revision': '58ba6bf5ecedaadbbe4d469545dca5017cf53034',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -98,7 +98,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': '7b0be4ced5f3687e922fc9ed11a4c49fe9848221',
+  'pdfium_revision': '93bb725b62f9779534c9444c1e1319fe8c28912e',
   # 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.
@@ -106,7 +106,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': '48eaa28a124e702edf373e212011cb283f0f0161',
+  'boringssl_revision': '296a61d6007688a1472798879b81517920e35dff',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -130,7 +130,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': 'db654910e39e4d8866a4eaf93167a24a41ceacdf',
+  'catapult_revision': '16753e0633fca8b91425bbf071447ec884228167',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -243,7 +243,7 @@
   },
 
   'src/media/cdm/api':
-    Var('chromium_git') + '/chromium/cdm.git' + '@' + 'ea5df8e78fbd0a4c24cc3a1f3faefefcd1b45237',
+    Var('chromium_git') + '/chromium/cdm.git' + '@' + 'eed9e92ec7789141c37ac0ee26b8bef4f2eb93e7',
 
   'src/native_client': {
       'url': Var('chromium_git') + '/native_client/src/native_client.git' + '@' + Var('nacl_revision'),
@@ -313,7 +313,7 @@
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
-      'url': Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '304b21ef6d9182ebb812cde8f04db17b070bd858',
+      'url': Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'caeea330067c6b166a877f1198cf9a7534c2a3d4',
       'condition': 'checkout_linux',
   },
 
@@ -404,7 +404,7 @@
     Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + 'a9bac57ce6c9d390a52ebaad3259f5fdb871210e',
 
   'src/third_party/icu':
-    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '741688ebf328da9adc52505248bf4e2ef868722c',
+    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '26f7d8ad2f7c6c902825a985146a1d9d68e783cb',
 
   'src/third_party/jsoncpp/source':
     Var('chromium_git') + '/external/github.com/open-source-parsers/jsoncpp.git' + '@' + 'f572e8e42e22cfcf5ab0aea26574f408943edfa4', # from svn 248
@@ -474,7 +474,7 @@
   },
 
   'src/third_party/libvpx/source/libvpx':
-    Var('chromium_git') + '/webm/libvpx.git' + '@' +  'cbe62b9c2d2b006aba52c8eebe7d842e59166fe4',
+    Var('chromium_git') + '/webm/libvpx.git' + '@' +  '14dbdd95e686eafbe556c154c9e0bd76fe1d2d1a',
 
   'src/third_party/libwebm/source':
     Var('chromium_git') + '/webm/libwebm.git' + '@' + '4956b2dec65352af32dc71bab553acb631c64177',
@@ -639,7 +639,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '05591bbeae6592fd924caec8e728a4ea86cbb8c9',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '40f0b37d3b9ad17fa19ddb27a7903990e355f0a8', # commit position 20628
+    Var('webrtc_git') + '/src.git' + '@' + 'e51f7850435adb3f9f64ba171fdd5e5fe311bf44', # commit position 20628
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/WATCHLISTS b/WATCHLISTS
index 06f2280..cccf96f3 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -974,9 +974,11 @@
     'ipc': {
       'filepath': 'ipc/ipc',
     },
+    'libaom': {
+      'filepath': 'third_party/libaom/',
+    },
     'libvpx': {
-      'filepath': 'third_party/libaom/|'\
-                  'third_party/libvpx/',
+      'filepath': 'third_party/libvpx/',
     },
     'libwebp': {
       'filepath': 'third_party/libwebp'
@@ -2079,10 +2081,16 @@
     'ios_web': ['ios-reviews+web@chromium.org',
                 'eugenebut@chromium.org'],
     'ipc': ['jam@chromium.org'],
-    'libvpx': ['fgalligan@chromium.org',
+    'libaom': ['fgalligan@chromium.org',
                'johannkoenig@chromium.org',
                'jzern@chromium.org',
                'tomfinegan@chromium.org'],
+    'libvpx': ['fgalligan@chromium.org',
+               'jianj@chromium.org',
+               'johannkoenig@chromium.org',
+               'jzern@chromium.org',
+               'marpan@chromium.org',
+               'tomfinegan@chromium.org'],
     'libwebp': ['jzern@chromium.org',
                 'skal@google.com',
                 'urvang@chromium.org'],
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 7c55671..eb82e9c 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -681,7 +681,6 @@
     "//components/crash/content/app",
     "//components/crash/content/browser",
     "//components/google/core/browser",
-    "//components/keyed_service/content",
     "//components/metrics",
     "//components/metrics:gpu",
     "//components/metrics:net",
@@ -689,9 +688,7 @@
     "//components/navigation_interception",
     "//components/network_session_configurator/common",
     "//components/policy:generated",
-    "//components/policy/content/",
     "//components/policy/core/browser",
-    "//components/policy/core/common",
     "//components/prefs",
     "//components/printing/browser",
     "//components/printing/common",
@@ -947,9 +944,7 @@
 }
 
 android_library("android_webview_commandline_java") {
-  java_files = [
-    "java/src/org/chromium/android_webview/command_line/CommandLineUtil.java",
-  ]
+  java_files = [ "java/src/org/chromium/android_webview/command_line/CommandLineUtil.java" ]
 
   deps = [
     "//base:base_java",
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index 709f0d8b..96eaa9b5 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -18,7 +18,6 @@
   "+components/navigation_interception",
   "+components/policy/core/browser",
   "+components/policy/core/common",
-  "+components/policy/content",
   "+components/pref_registry",
   "+components/printing/browser",
   "+components/printing/common",
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index 89c9844..34a4952 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -86,6 +86,24 @@
   return config_service;
 }
 
+bool OverrideBlacklistForURL(const GURL& url, bool* block, int* reason) {
+  // We don't have URLs that should never be blacklisted here.
+  return false;
+}
+
+policy::URLBlacklistManager* CreateURLBlackListManager(
+    PrefService* pref_service) {
+  scoped_refptr<base::SequencedTaskRunner> background_task_runner =
+      base::CreateSequencedTaskRunnerWithTraits(
+          {base::MayBlock(), base::TaskPriority::BACKGROUND});
+  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
+      BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+
+  return new policy::URLBlacklistManager(pref_service, background_task_runner,
+                                         io_task_runner,
+                                         base::Bind(OverrideBlacklistForURL));
+}
+
 std::unique_ptr<AwSafeBrowsingWhitelistManager>
 CreateSafeBrowsingWhitelistManager() {
   // Should not be called until the end of PreMainMessageLoopRun,
@@ -156,6 +174,8 @@
 
   EnsureResourceContextInitialized(this);
 
+  blacklist_manager_.reset(CreateURLBlackListManager(user_pref_service_.get()));
+
   AwMetricsServiceClient::GetInstance()->Initialize(
       user_pref_service_.get(),
       content::BrowserContext::GetDefaultStoragePartition(this)
@@ -349,6 +369,13 @@
   return NULL;
 }
 
+policy::URLBlacklistManager* AwBrowserContext::GetURLBlacklistManager() {
+  // Should not be called until the end of PreMainMessageLoopRun, where
+  // blacklist_manager_ is initialized.
+  DCHECK(blacklist_manager_);
+  return blacklist_manager_.get();
+}
+
 web_restrictions::WebRestrictionsClient*
 AwBrowserContext::GetWebRestrictionProvider() {
   DCHECK(web_restriction_provider_);
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index 1b104c4..4e4b42434 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -33,6 +33,7 @@
 }
 
 namespace policy {
+class URLBlacklistManager;
 class BrowserPolicyConnectorBase;
 }
 
@@ -84,6 +85,7 @@
   AwFormDatabaseService* GetFormDatabaseService();
   AwURLRequestContextGetter* GetAwURLRequestContext();
 
+  policy::URLBlacklistManager* GetURLBlacklistManager();
   web_restrictions::WebRestrictionsClient* GetWebRestrictionProvider();
 
   // content::BrowserContext implementation.
@@ -137,6 +139,8 @@
 
   std::unique_ptr<PrefService> user_pref_service_;
   std::unique_ptr<policy::BrowserPolicyConnectorBase> browser_policy_connector_;
+  std::unique_ptr<policy::URLBlacklistManager> blacklist_manager_;
+
   std::unique_ptr<AwSSLHostStateDelegate> ssl_host_state_delegate_;
   std::unique_ptr<content::PermissionManager> permission_manager_;
   std::unique_ptr<web_restrictions::WebRestrictionsClient>
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index b1f03bc8..a5a5673 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -41,7 +41,6 @@
 #include "components/cdm/browser/cdm_message_filter_android.h"
 #include "components/crash/content/browser/crash_dump_observer_android.h"
 #include "components/navigation_interception/intercept_navigation_delegate.h"
-#include "components/policy/content/policy_blacklist_navigation_throttle.h"
 #include "components/safe_browsing/browser/browser_url_loader_throttle.h"
 #include "components/safe_browsing/browser/mojo_safe_browsing_impl.h"
 #include "components/spellcheck/spellcheck_build_features.h"
@@ -518,8 +517,6 @@
     throttles.push_back(
         navigation_interception::InterceptNavigationDelegate::CreateThrottleFor(
             navigation_handle));
-    throttles.push_back(base::MakeUnique<PolicyBlacklistNavigationThrottle>(
-        navigation_handle, browser_context_.get()));
   }
   return throttles;
 }
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index 632a84b4..f73f97a 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -15,7 +15,7 @@
 #include "android_webview/public/browser/draw_gl.h"
 #include "base/trace_event/trace_event.h"
 #include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "ui/gfx/transform.h"
@@ -28,8 +28,8 @@
       last_egl_context_(eglGetCurrentContext()),
       surfaces_(SurfacesInstance::GetOrCreateInstance()),
       frame_sink_id_(surfaces_->AllocateFrameSinkId()),
-      local_surface_id_allocator_(
-          std::make_unique<viz::LocalSurfaceIdAllocator>()),
+      parent_local_surface_id_allocator_(
+          std::make_unique<viz::ParentLocalSurfaceIdAllocator>()),
       last_committed_layer_tree_frame_sink_id_(0u),
       last_submitted_layer_tree_frame_sink_id_(0u) {
   DCHECK(last_egl_context_);
@@ -168,7 +168,7 @@
 
 void HardwareRenderer::AllocateSurface() {
   DCHECK(!child_id_.is_valid());
-  child_id_ = local_surface_id_allocator_->GenerateId();
+  child_id_ = parent_local_surface_id_allocator_->GenerateId();
   surfaces_->AddChildId(viz::SurfaceId(frame_sink_id_, child_id_));
 }
 
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h
index 2294d06a..4f5a50a4d 100644
--- a/android_webview/browser/hardware_renderer.h
+++ b/android_webview/browser/hardware_renderer.h
@@ -19,7 +19,7 @@
 
 namespace viz {
 class CompositorFrameSinkSupport;
-class LocalSurfaceIdAllocator;
+class ParentLocalSurfaceIdAllocator;
 }
 
 namespace android_webview {
@@ -94,8 +94,8 @@
 
   const scoped_refptr<SurfacesInstance> surfaces_;
   viz::FrameSinkId frame_sink_id_;
-  const std::unique_ptr<viz::LocalSurfaceIdAllocator>
-      local_surface_id_allocator_;
+  const std::unique_ptr<viz::ParentLocalSurfaceIdAllocator>
+      parent_local_surface_id_allocator_;
   std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
   viz::LocalSurfaceId child_id_;
   CompositorID compositor_id_;
diff --git a/android_webview/browser/net/aw_network_delegate.cc b/android_webview/browser/net/aw_network_delegate.cc
index 7faf749..4474ef0 100644
--- a/android_webview/browser/net/aw_network_delegate.cc
+++ b/android_webview/browser/net/aw_network_delegate.cc
@@ -10,6 +10,7 @@
 #include "android_webview/browser/aw_cookie_access_policy.h"
 #include "android_webview/browser/net/aw_web_resource_request.h"
 #include "base/android/build_info.h"
+#include "components/policy/core/browser/url_blacklist_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/resource_request_info.h"
 #include "net/base/completion_callback.h"
@@ -41,11 +42,25 @@
 
 }  // namespace
 
-AwNetworkDelegate::AwNetworkDelegate() {}
+AwNetworkDelegate::AwNetworkDelegate() : url_blacklist_manager_(nullptr) {
+}
 
 AwNetworkDelegate::~AwNetworkDelegate() {
 }
 
+int AwNetworkDelegate::OnBeforeURLRequest(
+    net::URLRequest* request,
+    const net::CompletionCallback& callback,
+    GURL* new_url) {
+  if (!url_blacklist_manager_) {
+    url_blacklist_manager_ =
+        AwBrowserContext::GetDefault()->GetURLBlacklistManager();
+  }
+  if (url_blacklist_manager_->IsURLBlocked(request->url()))
+    return net::ERR_BLOCKED_BY_ADMINISTRATOR;
+  return net::OK;
+}
+
 int AwNetworkDelegate::OnBeforeStartTransaction(
     net::URLRequest* request,
     const net::CompletionCallback& callback,
diff --git a/android_webview/browser/net/aw_network_delegate.h b/android_webview/browser/net/aw_network_delegate.h
index 2ee2317..a3f0d984 100644
--- a/android_webview/browser/net/aw_network_delegate.h
+++ b/android_webview/browser/net/aw_network_delegate.h
@@ -12,6 +12,10 @@
 class URLRequest;
 }
 
+namespace policy {
+class URLBlacklistManager;
+}
+
 namespace android_webview {
 
 // WebView's implementation of the NetworkDelegate.
@@ -22,6 +26,9 @@
 
  private:
   // NetworkDelegate implementation.
+  int OnBeforeURLRequest(net::URLRequest* request,
+                         const net::CompletionCallback& callback,
+                         GURL* new_url) override;
   int OnBeforeStartTransaction(net::URLRequest* request,
                                const net::CompletionCallback& callback,
                                net::HttpRequestHeaders* headers) override;
@@ -55,6 +62,9 @@
                        const base::FilePath& original_path,
                        const base::FilePath& absolute_path) const override;
 
+  // Used to filter URL requests. Owned by AwBrowserContext.
+  const policy::URLBlacklistManager* url_blacklist_manager_;
+
   DISALLOW_COPY_AND_ASSIGN(AwNetworkDelegate);
 };
 
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc
index 4e2dfa00..5727a5b 100644
--- a/android_webview/browser/surfaces_instance.cc
+++ b/android_webview/browser/surfaces_instance.cc
@@ -16,7 +16,7 @@
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/common/quads/surface_draw_quad.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/display/display_scheduler.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
@@ -55,7 +55,8 @@
 
   frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>(
       viz::SurfaceManager::LifetimeType::SEQUENCES);
-  local_surface_id_allocator_.reset(new viz::LocalSurfaceIdAllocator());
+  parent_local_surface_id_allocator_.reset(
+      new viz::ParentLocalSurfaceIdAllocator());
 
   constexpr bool is_root = true;
   constexpr bool needs_sync_points = true;
@@ -153,7 +154,7 @@
 
   if (!root_id_.is_valid() || viewport != surface_size_ ||
       device_scale_factor != device_scale_factor_) {
-    root_id_ = local_surface_id_allocator_->GenerateId();
+    root_id_ = parent_local_surface_id_allocator_->GenerateId();
     surface_size_ = viewport;
     device_scale_factor_ = device_scale_factor;
     display_->SetLocalSurfaceId(root_id_, device_scale_factor);
diff --git a/android_webview/browser/surfaces_instance.h b/android_webview/browser/surfaces_instance.h
index 88d8baf..c04d1cf 100644
--- a/android_webview/browser/surfaces_instance.h
+++ b/android_webview/browser/surfaces_instance.h
@@ -26,7 +26,7 @@
 class CompositorFrameSinkSupport;
 class Display;
 class FrameSinkManagerImpl;
-class LocalSurfaceIdAllocator;
+class ParentLocalSurfaceIdAllocator;
 }  // namespace viz
 
 namespace android_webview {
@@ -64,6 +64,8 @@
       bool will_draw_and_swap,
       const viz::RenderPassList& render_passes) override {}
   void DisplayDidDrawAndSwap() override {}
+  void DisplayDidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) override {}
 
   // viz::mojom::CompositorFrameSinkClient implementation.
   void DidReceiveCompositorFrameAck(
@@ -87,7 +89,8 @@
   std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_;
   std::unique_ptr<viz::BeginFrameSource> begin_frame_source_;
   std::unique_ptr<viz::Display> display_;
-  std::unique_ptr<viz::LocalSurfaceIdAllocator> local_surface_id_allocator_;
+  std::unique_ptr<viz::ParentLocalSurfaceIdAllocator>
+      parent_local_surface_id_allocator_;
   std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
 
   viz::LocalSurfaceId root_id_;
diff --git a/android_webview/common/crash_reporter/crash_keys.cc b/android_webview/common/crash_reporter/crash_keys.cc
index f10a24255..24b0065 100644
--- a/android_webview/common/crash_reporter/crash_keys.cc
+++ b/android_webview/common/crash_reporter/crash_keys.cc
@@ -16,8 +16,6 @@
 
 const char kActiveURL[] = "url-chunk";
 
-const char kFontKeyName[] = "font_key_name";
-
 const char kShutdownType[] = "shutdown-type";
 const char kBrowserUnpinTrace[] = "browser-unpin-trace";
 
@@ -26,8 +24,6 @@
 
 const char kAndroidSdkInt[] = "android-sdk-int";
 
-const char kInputEventFilterSendFailure[] = "input-event-filter-send-failure";
-
 const char kViewCount[] = "view-count";
 
 const char kZeroEncodeDetails[] = "zero-encode-details";
@@ -56,15 +52,10 @@
       {gpu::crash_keys::kGPUGLContextIsVirtual, kSmallSize},
 
       // content/:
-      {"bad_message_reason", kSmallSize},
       {"discardable-memory-allocated", kSmallSize},
       {"discardable-memory-free", kSmallSize},
-      {kFontKeyName, kSmallSize},
-      {"mojo-message-error", kMediumSize},
-      {"ppapi_path", kMediumSize},
       {"subresource_url", kLargeSize},
       {"total-discardable-memory-allocated", kSmallSize},
-      {kInputEventFilterSendFailure, kSmallSize},
       {kViewCount, kSmallSize},
 
       // media/:
@@ -85,10 +76,6 @@
 
       // TODO(sunnyps): Remove after fixing crbug.com/724999.
       {"gl-context-set-current-stack-trace", kMediumSize},
-
-      // Accessibility keys. Temporary for http://crbug.com/765490.
-      {"ax_tree_error", kSmallSize},
-      {"ax_tree_update", kMediumSize},
   };
 
   // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
index 6a88221..000273e 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
@@ -188,8 +188,9 @@
     }
 
     @Test
-    @MediumTest
-    @Feature({"AndroidWebView"})
+    //@MediumTest
+    //@Feature({"AndroidWebView"})
+    @DisabledTest(message = "crbug.com/789306")
     public void testExitFullscreenEndsIfAppInvokesCallbackFromOnHideCustomView() throws Throwable {
         mContentsClient.setOnHideCustomViewRunnable(
                 () -> mContentsClient.getExitCallback().onCustomViewHidden());
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index c181287..a8c725d 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -23,6 +23,7 @@
 #include "ash/media_controller.h"
 #include "ash/multi_profile_uma.h"
 #include "ash/new_window_controller.h"
+#include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/config.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/root_window_controller.h"
@@ -648,6 +649,8 @@
 }
 
 bool CanHandleMoveWindowBetweenDisplays() {
+  if (!switches::IsDisplayMoveWindowAccelsEnabled())
+    return false;
   display::DisplayManager* display_manager = Shell::Get()->display_manager();
   // Accelerators to move window between displays on unified desktop mode and
   // mirror mode is disabled.
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc
index 67adce7..35605fe 100644
--- a/ash/app_list/app_list_presenter_delegate_unittest.cc
+++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -7,7 +7,6 @@
 #include "ash/app_list/model/app_list_view_state.h"
 #include "ash/app_list/test_app_list_presenter_impl.h"
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/cpp/config.h"
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/shelf/shelf.h"
@@ -654,10 +653,6 @@
 // alignment.
 TEST_F(AppListPresenterDelegateTest,
        ShelfBackgroundRespondsToAppListBeingShown) {
-  // TODO(newcomer): Investigate mash failures crbug.com/726838
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   GetPrimaryShelf()->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
 
   // Show the app list, the shelf background should be transparent.
diff --git a/ash/autoclick/autoclick_unittest.cc b/ash/autoclick/autoclick_unittest.cc
index f616c61..92231c2 100644
--- a/ash/autoclick/autoclick_unittest.cc
+++ b/ash/autoclick/autoclick_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "ash/autoclick/autoclick_controller.h"
-#include "ash/public/cpp/config.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ui/aura/test/test_window_delegate.h"
@@ -71,8 +70,7 @@
 
     // Make sure the display is initialized so we don't fail the test due to any
     // input events caused from creating the display.
-    if (Shell::GetAshConfig() != Config::MASH)
-      Shell::Get()->display_manager()->UpdateDisplays();
+    Shell::Get()->display_manager()->UpdateDisplays();
     RunAllPendingInMessageLoop();
   }
 
diff --git a/ash/display/display_configuration_controller_unittest.cc b/ash/display/display_configuration_controller_unittest.cc
index f192baa..bd2c5a09 100644
--- a/ash/display/display_configuration_controller_unittest.cc
+++ b/ash/display/display_configuration_controller_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "ash/display/display_configuration_controller_test_api.h"
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/cpp/config.h"
 #include "ash/rotator/screen_rotation_animator.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
@@ -44,11 +43,6 @@
 using DisplayConfigurationControllerTest = AshTestBase;
 
 TEST_F(DisplayConfigurationControllerTest, OnlyHasOneAnimator) {
-  // TODO(wutao): needs display_configuration_controller
-  // http://crbug.com/686839.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
   DisplayConfigurationControllerTestApi testapi(
       Shell::Get()->display_configuration_controller());
diff --git a/ash/message_center/message_center_button_bar.cc b/ash/message_center/message_center_button_bar.cc
index a8e4c101..2433770 100644
--- a/ash/message_center/message_center_button_bar.cc
+++ b/ash/message_center/message_center_button_bar.cc
@@ -8,6 +8,7 @@
 #include "ash/message_center/message_center_view.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/strings/grit/ash_strings.h"
+#include "ash/system/tray/tray_popup_utils.h"
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -21,6 +22,10 @@
 #include "ui/message_center/notifier_id.h"
 #include "ui/message_center/public/cpp/message_center_constants.h"
 #include "ui/resources/grit/ui_resources.h"
+#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
+#include "ui/views/animation/ink_drop_highlight.h"
+#include "ui/views/animation/ink_drop_impl.h"
+#include "ui/views/animation/ink_drop_mask.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/image_button.h"
@@ -47,15 +52,43 @@
 constexpr gfx::Insets kSeparatorPadding(12, 0, 12, 0);
 constexpr gfx::Insets kButtonBarBorder(4, 18, 4, 0);
 
-void SetDefaultButtonStyle(views::Button* button) {
-  button->SetFocusForPlatform();
-  button->SetFocusPainter(views::Painter::CreateSolidFocusPainter(
-      message_center::kFocusBorderColor, gfx::Insets(1, 2, 2, 2)));
-  button->SetBorder(
-      views::CreateEmptyBorder(message_center_style::kActionIconPadding));
+// A ToggleImageButton that implements system menu style ink drop animation.
+class MessageCenterButton : public views::ToggleImageButton {
+ public:
+  MessageCenterButton(views::ButtonListener* listener)
+      : ToggleImageButton(listener) {
+    SetBorder(
+        views::CreateEmptyBorder(message_center_style::kActionIconPadding));
+    set_animate_on_state_change(true);
 
-  // TODO(tetsui): Add ripple effect to the buttons.
-}
+    TrayPopupUtils::ConfigureTrayPopupButton(this);
+  }
+
+  std::unique_ptr<views::InkDrop> CreateInkDrop() override {
+    return TrayPopupUtils::CreateInkDrop(TrayPopupInkDropStyle::HOST_CENTERED,
+                                         this);
+  }
+
+  std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override {
+    return TrayPopupUtils::CreateInkDropRipple(
+        TrayPopupInkDropStyle::HOST_CENTERED, this,
+        GetInkDropCenterBasedOnLastEvent());
+  }
+
+  std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight()
+      const override {
+    return TrayPopupUtils::CreateInkDropHighlight(
+        TrayPopupInkDropStyle::HOST_CENTERED, this);
+  }
+
+  std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override {
+    return TrayPopupUtils::CreateInkDropMask(
+        TrayPopupInkDropStyle::HOST_CENTERED, this);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MessageCenterButton);
+};
 
 views::Separator* CreateVerticalSeparator() {
   views::Separator* separator = new views::Separator;
@@ -102,7 +135,7 @@
       views::CreateSolidBackground(message_center_style::kBackgroundColor));
   button_container_->SetLayoutManager(
       new views::BoxLayout(views::BoxLayout::kHorizontal));
-  close_all_button_ = new views::ImageButton(this);
+  close_all_button_ = new MessageCenterButton(this);
   close_all_button_->SetImage(
       views::Button::STATE_NORMAL,
       gfx::CreateVectorIcon(kNotificationCenterClearAllIcon,
@@ -115,11 +148,10 @@
                             message_center_style::kInactiveButtonColor));
   close_all_button_->SetTooltipText(l10n_util::GetStringUTF16(
       IDS_ASH_MESSAGE_CENTER_CLEAR_ALL_BUTTON_TOOLTIP));
-  SetDefaultButtonStyle(close_all_button_);
   button_container_->AddChildView(close_all_button_);
   button_container_->AddChildView(CreateVerticalSeparator());
 
-  quiet_mode_button_ = new views::ToggleImageButton(this);
+  quiet_mode_button_ = new MessageCenterButton(this);
   quiet_mode_button_->SetImage(
       views::Button::STATE_NORMAL,
       gfx::CreateVectorIcon(kNotificationCenterDoNotDisturbOffIcon,
@@ -134,11 +166,10 @@
   quiet_mode_button_->SetTooltipText(l10n_util::GetStringUTF16(
       IDS_ASH_MESSAGE_CENTER_QUIET_MODE_BUTTON_TOOLTIP));
   SetQuietModeState(message_center->IsQuietMode());
-  SetDefaultButtonStyle(quiet_mode_button_);
   button_container_->AddChildView(quiet_mode_button_);
   button_container_->AddChildView(CreateVerticalSeparator());
 
-  collapse_button_ = new views::ImageButton(this);
+  collapse_button_ = new MessageCenterButton(this);
   collapse_button_->SetBackground(
       views::CreateSolidBackground(message_center_style::kBackgroundColor));
   collapse_button_->SetPaintToLayer();
@@ -149,10 +180,9 @@
                             message_center_style::kActiveButtonColor));
   collapse_button_->SetTooltipText(l10n_util::GetStringUTF16(
       IDS_ASH_MESSAGE_CENTER_COLLAPSE_BUTTON_TOOLTIP));
-  SetDefaultButtonStyle(collapse_button_);
   AddChildView(collapse_button_);
 
-  settings_button_ = new views::ImageButton(this);
+  settings_button_ = new MessageCenterButton(this);
   settings_button_->SetImage(
       views::Button::STATE_NORMAL,
       gfx::CreateVectorIcon(kNotificationCenterSettingsIcon,
@@ -160,7 +190,6 @@
                             message_center_style::kActiveButtonColor));
   settings_button_->SetTooltipText(l10n_util::GetStringUTF16(
       IDS_ASH_MESSAGE_CENTER_SETTINGS_BUTTON_TOOLTIP));
-  SetDefaultButtonStyle(settings_button_);
   button_container_->AddChildView(settings_button_);
 
   AddChildView(button_container_);
@@ -293,8 +322,19 @@
   if (sender == close_all_button_) {
     message_center_view()->ClearAllClosableNotifications();
   } else if (sender == settings_button_) {
+    // In order to implement a bit tricky animation specified in UX mock, it
+    // calls ACTION_TRIGGERED of |collapse_button_| on |settings_button_| click.
+    // ACTION_TRIGGERED of |settings_button_| was already called by
+    // has_ink_drop_action_on_click().
+    // |settings_button_| and |collapse_button_| are in the same position,
+    // and SetSettingsVisible() below triggers cross-fading between them.
+    collapse_button_->AnimateInkDrop(views::InkDropState::ACTION_TRIGGERED,
+                                     nullptr);
     message_center_view()->SetSettingsVisible(true);
   } else if (sender == collapse_button_) {
+    // Same as above.
+    settings_button_->AnimateInkDrop(views::InkDropState::ACTION_TRIGGERED,
+                                     nullptr);
     message_center_view()->SetSettingsVisible(false);
   } else if (sender == quiet_mode_button_) {
     if (message_center()->IsQuietMode())
diff --git a/ash/message_center/message_center_button_bar.h b/ash/message_center/message_center_button_bar.h
index cc0d1662..e45c1211 100644
--- a/ash/message_center/message_center_button_bar.h
+++ b/ash/message_center/message_center_button_bar.h
@@ -84,10 +84,10 @@
   // Sub-views of the button bar.
   views::Label* notification_label_;
   views::View* button_container_;
-  views::ImageButton* close_all_button_;
-  views::ImageButton* settings_button_;
+  views::ToggleImageButton* close_all_button_;
+  views::ToggleImageButton* settings_button_;
   views::ToggleImageButton* quiet_mode_button_;
-  views::ImageButton* collapse_button_;
+  views::ToggleImageButton* collapse_button_;
 
   bool collapse_button_visible_ = false;
 
diff --git a/ash/mus/window_manager_unittest.cc b/ash/mus/window_manager_unittest.cc
deleted file mode 100644
index 96ecc6d..0000000
--- a/ash/mus/window_manager_unittest.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "ash/mus/window_manager.h"
-#include "ash/mus/window_manager_service.h"
-#include "ash/public/cpp/window_properties.h"
-#include "ash/public/interfaces/constants.mojom.h"
-#include "ash/public/interfaces/window_properties.mojom.h"
-#include "ash/session/test_session_controller_client.h"
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/test/ash_test_helper.h"
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "components/session_manager/session_manager_types.h"
-#include "services/service_manager/public/cpp/service_test.h"
-#include "services/ui/public/cpp/property_type_converters.h"
-#include "services/ui/public/interfaces/window_manager_constants.mojom.h"
-#include "services/ui/public/interfaces/window_tree.mojom.h"
-#include "ui/aura/env.h"
-#include "ui/aura/mus/property_converter.h"
-#include "ui/aura/mus/window_tree_client.h"
-#include "ui/aura/mus/window_tree_client_delegate.h"
-#include "ui/aura/mus/window_tree_host_mus.h"
-#include "ui/aura/mus/window_tree_host_mus_init_params.h"
-#include "ui/aura/test/env_test_helper.h"
-#include "ui/aura/window.h"
-#include "ui/display/display.h"
-#include "ui/display/display_list.h"
-#include "ui/display/screen_base.h"
-#include "ui/wm/core/capture_controller.h"
-#include "ui/wm/core/wm_state.h"
-
-namespace ash {
-
-class WindowTreeClientDelegate : public aura::WindowTreeClientDelegate {
- public:
-  WindowTreeClientDelegate() {}
-  ~WindowTreeClientDelegate() override {}
-
-  void WaitForEmbed() { run_loop_.Run(); }
-
-  void DestroyWindowTreeHost() { window_tree_host_.reset(); }
-
- private:
-  // aura::WindowTreeClientDelegate:
-  void OnEmbed(
-      std::unique_ptr<aura::WindowTreeHostMus> window_tree_host) override {
-    window_tree_host_ = std::move(window_tree_host);
-    run_loop_.Quit();
-  }
-  void OnEmbedRootDestroyed(
-      aura::WindowTreeHostMus* window_tree_host) override {}
-  void OnLostConnection(aura::WindowTreeClient* client) override {}
-  void OnPointerEventObserved(const ui::PointerEvent& event,
-                              aura::Window* target) override {}
-  aura::PropertyConverter* GetPropertyConverter() override {
-    return &property_converter_;
-  }
-
-  base::RunLoop run_loop_;
-  ::wm::WMState wm_state_;
-  aura::PropertyConverter property_converter_;
-  std::unique_ptr<aura::WindowTreeHostMus> window_tree_host_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowTreeClientDelegate);
-};
-
-class WindowManagerServiceTest : public service_manager::test::ServiceTest {
- public:
-  WindowManagerServiceTest()
-      : service_manager::test::ServiceTest("mash_unittests") {}
-  ~WindowManagerServiceTest() override {}
-
-  void TearDown() override {
-    // Unset the screen installed by the test.
-    display::Screen::SetScreenInstance(nullptr);
-    service_manager::test::ServiceTest::TearDown();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerServiceTest);
-};
-
-void OnEmbed(bool success) {
-  ASSERT_TRUE(success);
-}
-
-TEST_F(WindowManagerServiceTest, OpenWindow) {
-  display::ScreenBase screen;
-  screen.display_list().AddDisplay(
-      display::Display(1, gfx::Rect(0, 0, 200, 200)),
-      display::DisplayList::Type::PRIMARY);
-  display::Screen::SetScreenInstance(&screen);
-
-  WindowTreeClientDelegate window_tree_delegate;
-
-  connector()->StartService(mojom::kServiceName);
-
-  // Connect to mus and create a new top level window. The request goes to
-  // |ash|, but is async.
-  aura::WindowTreeClient client(connector(), &window_tree_delegate, nullptr,
-                                nullptr, nullptr, false);
-  client.ConnectViaWindowTreeFactory();
-  aura::test::EnvWindowTreeClientSetter env_window_tree_client_setter(&client);
-  std::map<std::string, std::vector<uint8_t>> properties;
-  properties[ui::mojom::WindowManager::kWindowType_InitProperty] =
-      mojo::ConvertTo<std::vector<uint8_t>>(
-          static_cast<int32_t>(ui::mojom::WindowType::WINDOW));
-  aura::WindowTreeHostMus window_tree_host_mus(
-      aura::CreateInitParamsForTopLevel(&client, std::move(properties)));
-  window_tree_host_mus.InitHost();
-  aura::Window* child_window = new aura::Window(nullptr);
-  child_window->Init(ui::LAYER_NOT_DRAWN);
-  window_tree_host_mus.window()->AddChild(child_window);
-
-  // Create another WindowTreeClient by way of embedding in
-  // |child_window|. This blocks until it succeeds.
-  ui::mojom::WindowTreeClientPtr tree_client;
-  auto tree_client_request = MakeRequest(&tree_client);
-  client.Embed(child_window, std::move(tree_client), 0u, base::Bind(&OnEmbed));
-  aura::WindowTreeClient child_client(connector(), &window_tree_delegate,
-                                      nullptr, std::move(tree_client_request),
-                                      nullptr, false);
-  window_tree_delegate.WaitForEmbed();
-  ASSERT_TRUE(!child_client.GetRoots().empty());
-  window_tree_delegate.DestroyWindowTreeHost();
-}
-
-using WindowManagerTest = AshTestBase;
-
-TEST_F(WindowManagerTest, SystemModalLockIsntReparented) {
-  ash_test_helper()->test_session_controller_client()->SetSessionState(
-      session_manager::SessionState::LOCKED);
-  std::unique_ptr<aura::Window> window = CreateTestWindow();
-  aura::Window* system_modal_container = Shell::GetContainer(
-      Shell::GetPrimaryRootWindow(), kShellWindowId_LockSystemModalContainer);
-  system_modal_container->AddChild(window.get());
-  aura::WindowManagerDelegate* window_manager_delegate =
-      ash_test_helper()->window_manager_service()->window_manager();
-  window_manager_delegate->OnWmSetModalType(window.get(),
-                                            ui::MODAL_TYPE_SYSTEM);
-  ASSERT_TRUE(window->parent());
-  // Setting to system modal should not reparent.
-  EXPECT_EQ(kShellWindowId_LockSystemModalContainer, window->parent()->id());
-}
-
-TEST_F(WindowManagerTest, CanConsumeSystemKeysFromContentBrowser) {
-  std::map<std::string, std::vector<uint8_t>> properties;
-  properties[ash::mojom::kCanConsumeSystemKeys_Property] =
-      mojo::ConvertTo<std::vector<uint8_t>>(static_cast<int64_t>(true));
-
-  aura::WindowManagerDelegate* window_manager_delegate =
-      ash_test_helper()->window_manager_service()->window_manager();
-  aura::Window* window = window_manager_delegate->OnWmCreateTopLevelWindow(
-      ui::mojom::WindowType::WINDOW, &properties);
-
-  EXPECT_EQ(true, window->GetProperty(kCanConsumeSystemKeysKey));
-}
-
-}  // namespace ash
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc
index 4248252b..1c1db2dc 100644
--- a/ash/public/cpp/ash_switches.cc
+++ b/ash/public/cpp/ash_switches.cc
@@ -47,6 +47,11 @@
 // TODO(oshima): Remove this once the feature is launched. crbug.com/749713.
 const char kAshEnableV1AppBackButton[] = "ash-enable-v1-app-back-button";
 
+// Enables move window between displays accelerators.
+// TODO(warx): Remove this once the feature is launched. crbug.com/773749.
+const char kAshEnableDisplayMoveWindowAccels[] =
+    "ash-enable-display-move-window-accels";
+
 // Enables keyboard shortcut viewer.
 // TODO(wutao): Remove this once the feature is launched. crbug.com/768932.
 const char kAshEnableKeyboardShortcutViewer[] =
@@ -161,6 +166,11 @@
 // enables the IME service (i.e. InputMethodMus) instead.
 const char kUseIMEService[] = "use-ime-service";
 
+bool IsDisplayMoveWindowAccelsEnabled() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      kAshEnableDisplayMoveWindowAccels);
+}
+
 bool IsNightLightEnabled() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
       kAshEnableNightLight);
diff --git a/ash/public/cpp/ash_switches.h b/ash/public/cpp/ash_switches.h
index 760e9627..cc441c5 100644
--- a/ash/public/cpp/ash_switches.h
+++ b/ash/public/cpp/ash_switches.h
@@ -25,6 +25,7 @@
 ASH_PUBLIC_EXPORT extern const char kAshDisableTabletAutohideTitlebars[];
 ASH_PUBLIC_EXPORT extern const char kAshDisableTouchExplorationMode[];
 ASH_PUBLIC_EXPORT extern const char kAshEnableV1AppBackButton[];
+ASH_PUBLIC_EXPORT extern const char kAshEnableDisplayMoveWindowAccels[];
 ASH_PUBLIC_EXPORT extern const char kAshEnableKeyboardShortcutViewer[];
 ASH_PUBLIC_EXPORT extern const char kAshEnableMagnifierKeyScroller[];
 ASH_PUBLIC_EXPORT extern const char kAshEnableNightLight[];
@@ -63,6 +64,7 @@
 ASH_PUBLIC_EXPORT extern const char kTouchscreenUsableWhileScreenOff[];
 ASH_PUBLIC_EXPORT extern const char kUseIMEService[];
 
+ASH_PUBLIC_EXPORT bool IsDisplayMoveWindowAccelsEnabled();
 ASH_PUBLIC_EXPORT bool IsNightLightEnabled();
 ASH_PUBLIC_EXPORT bool IsSidebarEnabled();
 ASH_PUBLIC_EXPORT bool IsUsingViewsLogin();
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index 3716fc7..0a49cc0c 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "ash/public/cpp/config.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/session/session_controller.h"
 #include "ash/session/test_session_controller_client.h"
@@ -721,10 +720,6 @@
 // a display which has touch capability.
 TEST_F(VirtualKeyboardRootWindowControllerTest,
        VirtualKeyboardOnTouchableDisplayOnly) {
-  // TODO: investigate failure in mash. http://crbug.com/695640.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   UpdateDisplay("500x500,500x500");
   display::Display secondary_display =
       Shell::Get()->display_manager()->GetSecondaryDisplay();
@@ -777,10 +772,6 @@
 // Test for http://crbug.com/303429. If both of displays have touch capability,
 // virtual keyboard follows the input focus.
 TEST_F(VirtualKeyboardRootWindowControllerTest, FollowInputFocus) {
-  // TODO: investigate failure in mash. http://crbug.com/695640.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   UpdateDisplay("500x500,500x500");
   const int64_t primary_display_id =
       display::Screen::GetScreen()->GetPrimaryDisplay().id();
@@ -849,10 +840,6 @@
 // capability, the virtual keyboard shows up on the specified display.
 TEST_F(VirtualKeyboardRootWindowControllerTest,
        VirtualKeyboardShowOnSpecifiedDisplay) {
-  // TODO: fails in mash. http://crbug.com/695640.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   UpdateDisplay("500x500,500x500");
   display::Display secondary_display = GetSecondaryDisplay();
 
@@ -1043,10 +1030,6 @@
 
 TEST_F(VirtualKeyboardRootWindowControllerTest,
        EnsureCaretInWorkAreaWithMultipleDisplays) {
-  // TODO: fails in mash. http://crbug.com/695640.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   UpdateDisplay("500x500,600x600");
   const int64_t primary_display_id =
       display::Screen::GetScreen()->GetPrimaryDisplay().id();
diff --git a/ash/rotator/screen_rotation_animator_unittest.cc b/ash/rotator/screen_rotation_animator_unittest.cc
index 98c6127..d1a2e5a 100644
--- a/ash/rotator/screen_rotation_animator_unittest.cc
+++ b/ash/rotator/screen_rotation_animator_unittest.cc
@@ -11,7 +11,6 @@
 #include "ash/display/screen_orientation_controller_test_api.h"
 #include "ash/display/window_tree_host_manager.h"
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/cpp/config.h"
 #include "ash/rotator/screen_rotation_animator_observer.h"
 #include "ash/rotator/screen_rotation_animator_test_api.h"
 #include "ash/shell.h"
@@ -396,11 +395,6 @@
 // Test enable smooth screen rotation code path.
 TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
        RotatesToDifferentRotationWithCopyCallback) {
-  // TODO(sky): remove this, temporary until mash_unittests as a separate
-  // executable is nuked. http://crbug.com/729810.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   const int64_t display_id = display_manager()->GetDisplayAt(0).id();
   SetScreenRotationAnimator(
       Shell::GetRootWindowForDisplayId(display_id),
@@ -484,11 +478,6 @@
 // request callback called, it should stop rotating.
 TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
        RemoveExternalSecondaryDisplayBeforeSecondCopyCallback) {
-  // TODO(sky): remove this, temporary until mash_unittests as a separate
-  // executable is nuked. http://crbug.com/729810.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   UpdateDisplay("640x480,800x600");
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
 
@@ -513,11 +502,6 @@
 // request callback called, it should stop rotating.
 TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
        RemoveExternalPrimaryDisplayBeforeSecondCopyCallback) {
-  // TODO(sky): remove this, temporary until mash_unittests as a separate
-  // executable is nuked. http://crbug.com/729810.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   UpdateDisplay("640x480,800x600");
   EXPECT_EQ(2U, display_manager()->GetNumDisplays());
 
@@ -572,11 +556,6 @@
 // The OverviewButton should be hidden.
 TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
        OverviewButtonTrayHideAnimationAlwaysCompletes) {
-  // TODO(sky): remove this, temporary until mash_unittests as a separate
-  // executable is nuked. http://crbug.com/729810.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
 
   // Long duration for hide animation, to allow it to be interrupted.
@@ -608,11 +587,6 @@
 // recreated.
 TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
        ShouldRotateAfterRecreateLayers) {
-  // TODO(sky): remove this, temporary until mash_unittests as a separate
-  // executable is nuked. http://crbug.com/729810.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   const int64_t display_id = display_manager()->GetDisplayAt(0).id();
   aura::Window* root_window = Shell::GetRootWindowForDisplayId(display_id);
   SetScreenRotationAnimator(
@@ -649,10 +623,6 @@
 }
 
 TEST_F(ScreenRotationAnimatorSmoothAnimationTest, DisplayChangeDuringCopy) {
-  // TODO(sky): remove this, temporary until mash_unittests as a separate
-  // executable is nuked. http://crbug.com/729810.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
   const int64_t internal_display_id =
       display::test::DisplayManagerTestApi(display_manager())
           .SetFirstDisplayAsInternalDisplay();
diff --git a/ash/screen_util_unittest.cc b/ash/screen_util_unittest.cc
index d6bf080c..ec9a64cd 100644
--- a/ash/screen_util_unittest.cc
+++ b/ash/screen_util_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ash/screen_util.h"
 
-#include "ash/public/cpp/config.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/window_util.h"
@@ -131,10 +130,6 @@
 }
 
 TEST_F(ScreenUtilTest, ShelfDisplayBoundsInUnifiedDesktopGrid) {
-  // TODO: requires unified desktop mode. http://crbug.com/581462.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   UpdateDisplay("500x400,400x600,300x600,200x300,600x200,350x400");
   display_manager()->SetUnifiedDesktopEnabled(true);
 
diff --git a/ash/shelf/shelf_window_watcher_unittest.cc b/ash/shelf/shelf_window_watcher_unittest.cc
index aff1f778..24ce3219 100644
--- a/ash/shelf/shelf_window_watcher_unittest.cc
+++ b/ash/shelf/shelf_window_watcher_unittest.cc
@@ -137,10 +137,6 @@
 }
 
 TEST_F(ShelfWindowWatcherTest, CreateAndRemoveShelfItemProperties) {
-  // TODO: investigate failure in mash. http://crbug.com/695562.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   // Creating windows without a valid ShelfItemType does not add items.
   EXPECT_EQ(1, model_->item_count());
   std::unique_ptr<views::Widget> widget1 =
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc
index 9fe1bfc7..06498b7 100644
--- a/ash/shell_unittest.cc
+++ b/ash/shell_unittest.cc
@@ -487,10 +487,6 @@
 // Tests that the cursor-filter is ahead of the drag-drop controller in the
 // pre-target list.
 TEST_F(ShellTest, TestPreTargetHandlerOrder) {
-  // TODO: investigate failure in mash, http://crbug.com/695758.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   Shell* shell = Shell::Get();
   ui::EventTargetTestApi test_api(shell);
   ShellTestApi shell_test_api(shell);
@@ -517,8 +513,6 @@
 
 // Verifies keyboard is re-created on proper timing.
 TEST_F(ShellTest, KeyboardCreation) {
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       keyboard::switches::kEnableVirtualKeyboard);
 
diff --git a/ash/sticky_keys/sticky_keys_overlay_unittest.cc b/ash/sticky_keys/sticky_keys_overlay_unittest.cc
index f9ff7ae..36e8cd0 100644
--- a/ash/sticky_keys/sticky_keys_overlay_unittest.cc
+++ b/ash/sticky_keys/sticky_keys_overlay_unittest.cc
@@ -45,20 +45,12 @@
 // This test addresses the crash report at crbug.com/435600, speculated to be
 // caused by using sticky keys with multiple displays.
 TEST_F(StickyKeysOverlayTest, OverlayNotDestroyedAfterDisplayRemoved) {
-  // TODO: investigate failure in mash, http://crbug.com/696006.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   // Add a secondary display to the left of the primary one.
   UpdateDisplay("1280x1024,1980x1080");
   display::DisplayIdList display_ids =
       display_manager()->GetCurrentDisplayIdList();
   int64_t primary_display_id = display_ids[0];
   int64_t secondary_display_id = display_ids[1];
-  // TODO: disabled as ScreenRotationAnimator does not work in mash,
-  // http://crbug.com/696754.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
   display_manager()->SetLayoutForCurrentDisplays(
       display::test::CreateDisplayLayout(display_manager(),
                                          display::DisplayPlacement::LEFT, 0));
diff --git a/ash/system/network/vpn_list_view.cc b/ash/system/network/vpn_list_view.cc
index 236d8c7..84838d65 100644
--- a/ash/system/network/vpn_list_view.cc
+++ b/ash/system/network/vpn_list_view.cc
@@ -61,14 +61,12 @@
   if (network.vpn_provider_type() == shill::kProviderArcVpn) {
     return provider.provider_type == VPNProvider::ARC_VPN &&
            network.vpn_provider_id() == provider.package_name;
+  } else if (network.vpn_provider_type() == shill::kProviderThirdPartyVpn) {
+    return provider.provider_type == VPNProvider::THIRD_PARTY_VPN &&
+           network.vpn_provider_id() == provider.app_id;
+  } else {
+    return provider.provider_type == VPNProvider::BUILT_IN_VPN;
   }
-
-  const bool network_uses_third_party_provider =
-      network.vpn_provider_type() == shill::kProviderThirdPartyVpn;
-  if (provider.provider_type != VPNProvider::THIRD_PARTY_VPN)
-    return !network_uses_third_party_provider;
-  return network_uses_third_party_provider &&
-         network.vpn_provider_id() == provider.app_id;
 }
 
 // A list entry that represents a VPN provider.
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc
index 27be1d4..7341bfdb 100644
--- a/ash/system/overview/overview_button_tray_unittest.cc
+++ b/ash/system/overview/overview_button_tray_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "ash/display/window_tree_host_manager.h"
 #include "ash/login_status.h"
-#include "ash/public/cpp/config.h"
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/root_window_controller.h"
 #include "ash/rotator/screen_rotation_animator.h"
@@ -167,10 +166,6 @@
 
 // Tests that tapping on the control will record the user action Tray_Overview.
 TEST_F(OverviewButtonTrayTest, TrayOverviewUserAction) {
-  // TODO: investigate failure in mash, http://crbug.com/698129.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   ASSERT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting());
 
   // Tapping on the control when there are no windows (and thus the user cannot
diff --git a/ash/system/user/user_card_view.cc b/ash/system/user/user_card_view.cc
index 5848f85..b3159cd 100644
--- a/ash/system/user/user_card_view.cc
+++ b/ash/system/user/user_card_view.cc
@@ -159,7 +159,7 @@
   gfx::Point position = contents_area.origin();
   gfx::Range display_name(gfx::Range::InvalidRange());
   for (auto it = lines.begin(); it != lines.end(); ++it) {
-    auto line = base::WrapUnique(gfx::RenderText::CreateInstance());
+    auto line = gfx::RenderText::CreateHarfBuzzInstance();
     line->SetDirectionalityMode(gfx::DIRECTIONALITY_FROM_UI);
     line->SetText(*it);
     const gfx::Size size(contents_area.width(), line->GetStringSize().height());
diff --git a/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc b/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc
index ad0b6fe..b199d07 100644
--- a/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc
+++ b/ash/system/web_notification/ash_popup_alignment_delegate_unittest.cc
@@ -8,7 +8,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/public/cpp/config.h"
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/root_window_controller.h"
@@ -166,10 +165,6 @@
 }
 
 TEST_F(AshPopupAlignmentDelegateTest, DockedMode) {
-  // TODO: needs unified mode. http://crbug.com/698024.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   const gfx::Rect toast_size(0, 0, 10, 10);
   UpdateDisplay("600x600");
   int origin_x = alignment_delegate()->GetToastOriginX(toast_size);
@@ -220,10 +215,6 @@
 }
 
 TEST_F(AshPopupAlignmentDelegateTest, Unified) {
-  // TODO: needs unified mode. http://crbug.com/698024.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   display_manager()->SetUnifiedDesktopEnabled(true);
 
   // Reset the delegate as the primary display's shelf will be destroyed during
diff --git a/ash/system/web_notification/web_notification_tray_unittest.cc b/ash/system/web_notification/web_notification_tray_unittest.cc
index fb7a577..dcf9e03 100644
--- a/ash/system/web_notification/web_notification_tray_unittest.cc
+++ b/ash/system/web_notification/web_notification_tray_unittest.cc
@@ -250,10 +250,6 @@
 
 // Verifies if the notification appears on both displays when extended mode.
 TEST_F(WebNotificationTrayTest, PopupShownOnBothDisplays) {
-  // TODO: needs ScreenLayoutObserver, http://crbug.com/696752.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   Shell::Get()->screen_layout_observer()->set_show_notifications_for_testing(
       true);
   UpdateDisplay("400x400,200x200");
diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc
index 3249f97a..2e4c7670 100644
--- a/ash/tooltips/tooltip_controller_unittest.cc
+++ b/ash/tooltips/tooltip_controller_unittest.cc
@@ -112,10 +112,6 @@
   // Mouse event triggers tooltip update so it becomes visible.
   EXPECT_TRUE(helper_->IsTooltipVisible());
 
-  // TODO: CursorManager not created in mash. http://crbug.com/631103.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   // Disable mouse event which hides the cursor and check again.
   ash::Shell::Get()->cursor_manager()->DisableMouseEvents();
   RunAllPendingInMessageLoop();
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index e6ecc31..8aac339 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -457,13 +457,10 @@
   EXPECT_EQ("1000x300",
             WallpaperController::GetMaxDisplaySizeInNative().ToString());
 
-  // TODO: mash doesn't support rotation yet, http://crbug.com/695556.
-  if (Shell::GetAshConfig() != Config::MASH) {
-    // Rotated display should return the rotated size.
-    UpdateDisplay("1000x300*2/r");
-    EXPECT_EQ("300x1000",
-              WallpaperController::GetMaxDisplaySizeInNative().ToString());
-  }
+  // Rotated display should return the rotated size.
+  UpdateDisplay("1000x300*2/r");
+  EXPECT_EQ("300x1000",
+            WallpaperController::GetMaxDisplaySizeInNative().ToString());
 
   // UI Scaling shouldn't affect the native size.
   UpdateDisplay("1000x300*2@1.5");
diff --git a/ash/window_manager_common_unittests.cc b/ash/window_manager_common_unittests.cc
index 3d669f8..89c5cbb 100644
--- a/ash/window_manager_common_unittests.cc
+++ b/ash/window_manager_common_unittests.cc
@@ -11,13 +11,11 @@
 #include "ui/aura/test/mus/test_window_tree_client_setup.h"
 #include "ui/aura/window.h"
 
-// The tests in this file are in all configs of ash, where as those in
-// window_manager_unittest.cc is only run in Config::MASH.
-
 namespace ash {
 
 using WindowManagerCommonTest = AshTestBase;
 
+// TODO(jamescook): Move into one of the existing WindowManager test suites.
 TEST_F(WindowManagerCommonTest, Focus) {
   if (Shell::GetAshConfig() == Config::CLASSIC)
     return;
diff --git a/ash/wm/panels/panel_layout_manager_unittest.cc b/ash/wm/panels/panel_layout_manager_unittest.cc
index debdc9b..b57c0c2b 100644
--- a/ash/wm/panels/panel_layout_manager_unittest.cc
+++ b/ash/wm/panels/panel_layout_manager_unittest.cc
@@ -300,11 +300,6 @@
 // Tests for crashes during undocking.
 // See https://crbug.com/632755
 TEST_F(PanelLayoutManagerTest, UndockTest) {
-  // TODO: mash doesn't support SetFirstDisplayAsInternalDisplay().
-  // http://crbug.com/698091.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   std::vector<display::ManagedDisplayInfo> info_list;
 
   const int64_t internal_display_id =
@@ -336,11 +331,6 @@
 // Tests for any crash during docking and then undocking.
 // See https://crbug.com/632755
 TEST_F(PanelLayoutManagerTest, DockUndockTest) {
-  // TODO: mash doesn't support SetFirstDisplayAsInternalDisplay().
-  // http://crbug.com/698091.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   std::vector<display::ManagedDisplayInfo> info_list;
 
   const int64_t internal_display_id =
diff --git a/ash/wm/window_manager_unittest.cc b/ash/wm/window_manager_unittest.cc
index 206f66e..8feeb5a0 100644
--- a/ash/wm/window_manager_unittest.cc
+++ b/ash/wm/window_manager_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/public/cpp/config.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
@@ -508,10 +507,6 @@
 }
 
 TEST_F(WindowManagerTest, MouseEventCursors) {
-  // TODO: investigate failure in mash. http://crbug.com/698895.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   aura::Window* root_window = Shell::GetPrimaryRootWindow();
 
   // Create a window.
@@ -751,10 +746,6 @@
 
 // Touch visually hides the cursor.
 TEST_F(WindowManagerTest, UpdateCursorVisibility) {
-  // TODO: mash doesn't support CursorManager. http://crbug.com/631103.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   ui::test::EventGenerator& generator = GetEventGenerator();
   ::wm::CursorManager* cursor_manager = ash::Shell::Get()->cursor_manager();
 
@@ -774,10 +765,6 @@
 
 // Tests cursor visibility on key pressed event.
 TEST_F(WindowManagerTest, UpdateCursorVisibilityOnKeyEvent) {
-  // TODO: mash doesn't support CursorManager. http://crbug.com/631103.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   ui::test::EventGenerator& generator = GetEventGenerator();
   ::wm::CursorManager* cursor_manager = ash::Shell::Get()->cursor_manager();
 
@@ -806,10 +793,6 @@
 
 // Test that pressing an accelerator does not hide the cursor.
 TEST_F(WindowManagerTest, UpdateCursorVisibilityAccelerator) {
-  // TODO: mash doesn't support CursorManager. http://crbug.com/631103.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   ui::test::EventGenerator& generator = GetEventGenerator();
   ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
 
@@ -831,10 +814,6 @@
 }
 
 TEST_F(WindowManagerTest, TestCursorClientObserver) {
-  // TODO: mash doesn't support CursorManager. http://crbug.com/631103.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   ui::test::EventGenerator& generator = GetEventGenerator();
   ::wm::CursorManager* cursor_manager = ash::Shell::Get()->cursor_manager();
 
diff --git a/ash/wm/window_positioner.cc b/ash/wm/window_positioner.cc
index be12bcd..691c1691 100644
--- a/ash/wm/window_positioner.cc
+++ b/ash/wm/window_positioner.cc
@@ -20,21 +20,10 @@
 #include "ui/wm/core/window_util.h"
 
 namespace ash {
-
-// The number of pixels which are kept free top, left and right when a window
-// gets positioned to its default location.
-// static
-const int WindowPositioner::kDesktopBorderSize = 16;
-
-// Maximum width of a window even if there is more room on the desktop.
-// static
-const int WindowPositioner::kMaximumWindowWidth = 1100;
-
 namespace {
 
 // When a window gets opened in default mode and the screen is less than or
-// equal to this width, the window will get opened in tablet mode. This value
-// can be reduced to a "tame" number if the feature is disabled.
+// equal to this width, the window opens with show state maximized.
 const int kForceMaximizeWidthLimit = 1366;
 
 // The time in milliseconds which should be used to visually move a window
@@ -395,25 +384,6 @@
 
 WindowPositioner::~WindowPositioner() = default;
 
-gfx::Rect WindowPositioner::GetDefaultWindowBounds(
-    const display::Display& display) {
-  const gfx::Rect work_area = display.work_area();
-  // There should be a 'desktop' border around the window at the left and right
-  // side.
-  int default_width = work_area.width() - 2 * kDesktopBorderSize;
-  // There should also be a 'desktop' border around the window at the top.
-  // Since the workspace excludes the tray area we only need one border size.
-  int default_height = work_area.height() - kDesktopBorderSize;
-  int offset_x = kDesktopBorderSize;
-  if (default_width > kMaximumWindowWidth) {
-    // The window should get centered on the screen and not follow the grid.
-    offset_x = (work_area.width() - kMaximumWindowWidth) / 2;
-    default_width = kMaximumWindowWidth;
-  }
-  return gfx::Rect(work_area.x() + offset_x, work_area.y() + kDesktopBorderSize,
-                   default_width, default_height);
-}
-
 gfx::Rect WindowPositioner::GetPopupPosition(const gfx::Size& popup_size) {
   if (!has_last_popup_position_) {
     // Start with the initial offset.
diff --git a/ash/wm/window_positioner.h b/ash/wm/window_positioner.h
index 228b3fd85..fe8ce9c 100644
--- a/ash/wm/window_positioner.h
+++ b/ash/wm/window_positioner.h
@@ -13,10 +13,6 @@
 class Window;
 }
 
-namespace display {
-class Display;
-}
-
 namespace gfx {
 class Rect;
 class Size;
@@ -32,13 +28,6 @@
   // will default to maximized.
   static int GetForceMaximizedWidthLimit();
 
-  // The number of pixels which are kept free top, left and right when a window
-  // gets positioned to its default location.
-  static const int kDesktopBorderSize;
-
-  // Maximum width of a window even if there is more room on the desktop.
-  static const int kMaximumWindowWidth;
-
   // Computes and returns the bounds and show state for new window
   // based on the parameter passed AND existing windows. |window| is
   // the one this function will generate a bounds for and used to
@@ -53,9 +42,6 @@
       gfx::Rect* bounds_in_out,
       ui::WindowShowState* show_state_out);
 
-  // Returns the default bounds for a window to be created in the |display|.
-  static gfx::Rect GetDefaultWindowBounds(const display::Display& display);
-
   // Check if after removal or hide of the given |removed_window| an
   // automated desktop location management can be performed and
   // rearrange accordingly.
diff --git a/ash/wm/workspace/workspace_event_handler_unittest.cc b/ash/wm/workspace/workspace_event_handler_unittest.cc
index c0f39fc3..31d7212 100644
--- a/ash/wm/workspace/workspace_event_handler_unittest.cc
+++ b/ash/wm/workspace/workspace_event_handler_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ash/wm/workspace/workspace_event_handler.h"
 
-#include "ash/public/cpp/config.h"
 #include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
@@ -95,10 +94,6 @@
 };
 
 TEST_F(WorkspaceEventHandlerTest, DoubleClickSingleAxisResizeEdge) {
-  // TODO: investigate failure. http://crbug.com/699175.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   // Double clicking the vertical resize edge of a window should maximize it
   // vertically.
   gfx::Rect restored_bounds(10, 10, 50, 50);
@@ -205,10 +200,6 @@
 
 // Tests the behavior when double clicking the border of a side snapped window.
 TEST_F(WorkspaceEventHandlerTest, DoubleClickSingleAxisWhenSideSnapped) {
-  // TODO: investigate failure. http://crbug.com/699175.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   gfx::Rect restored_bounds(10, 10, 50, 50);
   aura::test::TestWindowDelegate delegate;
   std::unique_ptr<aura::Window> window(
@@ -324,10 +315,6 @@
 
 // Test the behavior as a result of double clicking the window header.
 TEST_F(WorkspaceEventHandlerTest, DoubleClickCaptionTogglesMaximize) {
-  // TODO: investigate failure. http://crbug.com/699175.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   aura::test::TestWindowDelegate delegate;
   std::unique_ptr<aura::Window> window(
       CreateTestWindow(&delegate, gfx::Rect(1, 2, 30, 40)));
@@ -407,10 +394,6 @@
 }
 
 TEST_F(WorkspaceEventHandlerTest, DoubleTapCaptionTogglesMaximize) {
-  // TODO: investigate failure. http://crbug.com/699175.
-  if (Shell::GetAshConfig() == Config::MASH)
-    return;
-
   aura::test::TestWindowDelegate delegate;
   gfx::Rect bounds(10, 20, 30, 40);
   std::unique_ptr<aura::Window> window(CreateTestWindow(&delegate, bounds));
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index b24cc0d4..755611b7 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -191,11 +191,6 @@
   UpdateDisplay("300x400,400x500");
   aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
 
-  if (Shell::GetAshConfig() != Config::CLASSIC) {
-    // TODO(sky): should work for mus/mash once http://crbug.com/706589 is
-    // fixed.
-    return;
-  }
   Shell::Get()->display_manager()->SetLayoutForCurrentDisplays(
       display::test::CreateDisplayLayout(Shell::Get()->display_manager(),
                                          display::DisplayPlacement::TOP, 0));
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 26acacb7..b7a4775 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -265,6 +265,7 @@
     "containers/span.h",
     "containers/stack.h",
     "containers/stack_container.h",
+    "containers/unique_ptr_comparator.h",
     "containers/vector_buffer.h",
     "cpu.cc",
     "cpu.h",
@@ -2045,6 +2046,7 @@
     "containers/small_map_unittest.cc",
     "containers/span_unittest.cc",
     "containers/stack_container_unittest.cc",
+    "containers/unique_ptr_comparator_unittest.cc",
     "containers/vector_buffer_unittest.cc",
     "cpu_unittest.cc",
     "debug/activity_analyzer_unittest.cc",
diff --git a/base/android/java/src/org/chromium/base/SysUtils.java b/base/android/java/src/org/chromium/base/SysUtils.java
index a5bbc08..d4eb30d 100644
--- a/base/android/java/src/org/chromium/base/SysUtils.java
+++ b/base/android/java/src/org/chromium/base/SysUtils.java
@@ -33,6 +33,8 @@
     private static final String TAG = "SysUtils";
 
     private static Boolean sLowEndDevice;
+    private static Integer sAmountOfPhysicalMemoryKB;
+
     private static CachedMetrics.BooleanHistogramSample sLowEndMatches =
             new CachedMetrics.BooleanHistogramSample("Android.SysUtilsLowEndMatches");
 
@@ -43,7 +45,7 @@
      * @return Amount of physical memory in kilobytes, or 0 if there was
      *         an error trying to access the information.
      */
-    private static int amountOfPhysicalMemoryKB() {
+    private static int detectAmountOfPhysicalMemoryKB() {
         // Extract total memory RAM size by parsing /proc/meminfo, note that
         // this is exactly what the implementation of sysconf(_SC_PHYS_PAGES)
         // does. However, it can't be called because this method must be
@@ -111,10 +113,20 @@
     }
 
     /**
+     * @return Whether or not this device should be considered a low end device.
+     */
+    public static int amountOfPhysicalMemoryKB() {
+        if (sAmountOfPhysicalMemoryKB == null) {
+            sAmountOfPhysicalMemoryKB = detectAmountOfPhysicalMemoryKB();
+        }
+        return sAmountOfPhysicalMemoryKB.intValue();
+    }
+
+    /**
      * @return Whether or not the system has low available memory.
      */
     @CalledByNative
-    private static boolean isCurrentlyLowMemory() {
+    public static boolean isCurrentlyLowMemory() {
         ActivityManager am =
                 (ActivityManager) ContextUtils.getApplicationContext().getSystemService(
                         Context.ACTIVITY_SERVICE);
@@ -127,8 +139,9 @@
      * Resets the cached value, if any.
      */
     @VisibleForTesting
-    public static void reset() {
+    public static void resetForTesting() {
         sLowEndDevice = null;
+        sAmountOfPhysicalMemoryKB = null;
     }
 
     public static boolean hasCamera(final Context context) {
@@ -151,14 +164,14 @@
             return false;
         }
 
-        int ramSizeKB = amountOfPhysicalMemoryKB();
+        sAmountOfPhysicalMemoryKB = detectAmountOfPhysicalMemoryKB();
         boolean isLowEnd = true;
-        if (ramSizeKB <= 0) {
+        if (sAmountOfPhysicalMemoryKB <= 0) {
             isLowEnd = false;
         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            isLowEnd = ramSizeKB / 1024 <= ANDROID_O_LOW_MEMORY_DEVICE_THRESHOLD_MB;
+            isLowEnd = sAmountOfPhysicalMemoryKB / 1024 <= ANDROID_O_LOW_MEMORY_DEVICE_THRESHOLD_MB;
         } else {
-            isLowEnd = ramSizeKB / 1024 <= ANDROID_LOW_MEMORY_DEVICE_THRESHOLD_MB;
+            isLowEnd = sAmountOfPhysicalMemoryKB / 1024 <= ANDROID_LOW_MEMORY_DEVICE_THRESHOLD_MB;
         }
 
         // For evaluation purposes check whether our computation agrees with Android API value.
diff --git a/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java b/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
index b6660423..53c4e10 100644
--- a/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
+++ b/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
@@ -163,11 +163,11 @@
     }
 
     /**
-    * Records a sparse histogram. This is the Java equivalent of UMA_HISTOGRAM_SPARSE_SLOWLY.
-    * @param name name of the histogram
-    * @param sample sample to be recorded. All values of |sample| are valid, including negative
-    *        values.
-    */
+     * Records a sparse histogram. This is the Java equivalent of UmaHistogramSparse.
+     * @param name name of the histogram
+     * @param sample sample to be recorded. All values of |sample| are valid, including negative
+     *        values.
+     */
     public static void recordSparseSlowlyHistogram(String name, int sample) {
         if (sDisabledBy != null) return;
         long key = getCachedHistogramKey(name);
diff --git a/base/android/library_loader/library_loader_hooks.cc b/base/android/library_loader/library_loader_hooks.cc
index 09d681d..4e5828fa 100644
--- a/base/android/library_loader/library_loader_hooks.cc
+++ b/base/android/library_loader/library_loader_hooks.cc
@@ -11,6 +11,7 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/metrics/histogram.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "jni/LibraryLoader_jni.h"
 
@@ -79,9 +80,8 @@
 
 void RecordLibraryPreloaderRendereHistogram() {
   if (g_library_preloader_renderer_histogram_code_registered) {
-    UMA_HISTOGRAM_SPARSE_SLOWLY(
-        "Android.NativeLibraryPreloader.Result.Renderer",
-        g_library_preloader_renderer_histogram_code);
+    UmaHistogramSparse("Android.NativeLibraryPreloader.Result.Renderer",
+                       g_library_preloader_renderer_histogram_code);
   }
 }
 
@@ -139,9 +139,7 @@
     JNIEnv* env,
     const JavaParamRef<jobject>& jcaller,
     jint status) {
-  UMA_HISTOGRAM_SPARSE_SLOWLY(
-      "Android.NativeLibraryPreloader.Result.Browser",
-      status);
+  UmaHistogramSparse("Android.NativeLibraryPreloader.Result.Browser", status);
 }
 
 static void JNI_LibraryLoader_RegisterLibraryPreloaderRendererHistogram(
diff --git a/base/base_paths_win.cc b/base/base_paths_win.cc
index 62e1972..4029a49 100644
--- a/base/base_paths_win.cc
+++ b/base/base_paths_win.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <windows.h>
+#include <KnownFolders.h>
 #include <shlobj.h>
 
 #include "base/base_paths.h"
diff --git a/base/containers/README.md b/base/containers/README.md
index 59dd935..092a264 100644
--- a/base/containers/README.md
+++ b/base/containers/README.md
@@ -46,7 +46,7 @@
   * **base::small\_map** has better runtime memory usage without the poor
     mutation performance of large containers that base::flat\_map has. But this
     advantage is partially offset by additional code size. Prefer in cases
-    where you make many objects so that the code/heap tradeoff is good.
+    where you make many objects so that the code/heap tradeoff is good.
 
   * Use **std::map** and **std::set** if you can't decide. Even if they're not
     great, they're unlikely to be bad or surprising.
@@ -136,31 +136,10 @@
 Example, smart pointer set:
 
 ```cpp
-// Define a custom comparator.
-struct UniquePtrComparator {
-  // Mark your comparison as transparent.
-  using is_transparent = int;
-
-  template <typename T>
-  bool operator()(const std::unique_ptr<T>& lhs,
-                  const std::unique_ptr<T>& rhs) const {
-    return lhs < rhs;
-  }
-
-  template <typename T>
-  bool operator()(const T* lhs, const std::unique_ptr<T>& rhs) const {
-    return lhs < rhs.get();
-  }
-
-  template <typename T>
-  bool operator()(const std::unique_ptr<T>& lhs, const T* rhs) const {
-    return lhs.get() < rhs;
-  }
-};
-
-// Declare a typedef.
+// Declare a type alias using base::UniquePtrComparator.
 template <typename T>
-using UniquePtrSet = base::flat_set<std::unique_ptr<T>, UniquePtrComparator>;
+using UniquePtrSet = base::flat_set<std::unique_ptr<T>,
+                                    base::UniquePtrComparator>;
 
 // ...
 // Collect data.
diff --git a/base/containers/unique_ptr_comparator.h b/base/containers/unique_ptr_comparator.h
new file mode 100644
index 0000000..ceb1aa8
--- /dev/null
+++ b/base/containers/unique_ptr_comparator.h
@@ -0,0 +1,49 @@
+// 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 BASE_CONTAINERS_UNIQUE_PTR_COMPARATOR_H_
+#define BASE_CONTAINERS_UNIQUE_PTR_COMPARATOR_H_
+
+#include <memory>
+
+namespace base {
+
+// This transparent comparator allows to lookup by raw pointer in
+// a container of unique pointers. This functionality is based on C++14
+// extensions to std::set/std::map interface, and can also be used
+// with base::flat_set/base::flat_map.
+//
+// Example usage:
+//   Foo* foo = ...
+//   std::set<std::unique_ptr<Foo>, base::UniquePtrComparator> set;
+//   set.insert(std::unique_ptr<Foo>(foo));
+//   ...
+//   auto it = set.find(foo);
+//   EXPECT_EQ(foo, it->get());
+//
+// You can find more information about transparent comparisons here:
+// http://en.cppreference.com/w/cpp/utility/functional/less_void
+struct UniquePtrComparator {
+  using is_transparent = int;
+
+  template <typename T>
+  bool operator()(const std::unique_ptr<T>& lhs,
+                  const std::unique_ptr<T>& rhs) const {
+    return lhs < rhs;
+  }
+
+  template <typename T>
+  bool operator()(const T* lhs, const std::unique_ptr<T>& rhs) const {
+    return lhs < rhs.get();
+  }
+
+  template <typename T>
+  bool operator()(const std::unique_ptr<T>& lhs, const T* rhs) const {
+    return lhs.get() < rhs;
+  }
+};
+
+}  // namespace base
+
+#endif  // BASE_CONTAINERS_UNIQUE_PTR_COMPARATOR_H_
diff --git a/base/containers/unique_ptr_comparator_unittest.cc b/base/containers/unique_ptr_comparator_unittest.cc
new file mode 100644
index 0000000..e019419
--- /dev/null
+++ b/base/containers/unique_ptr_comparator_unittest.cc
@@ -0,0 +1,66 @@
+// 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/containers/unique_ptr_comparator.h"
+#include <memory>
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace {
+
+class Foo {
+ public:
+  Foo() { instance_count++; }
+  ~Foo() { instance_count--; }
+  static int instance_count;
+};
+
+int Foo::instance_count = 0;
+
+TEST(UniquePtrComparatorTest, Basic) {
+  std::set<std::unique_ptr<Foo>, UniquePtrComparator> set;
+  Foo* foo1 = new Foo();
+  Foo* foo2 = new Foo();
+  Foo* foo3 = new Foo();
+  EXPECT_EQ(3, Foo::instance_count);
+
+  set.emplace(foo1);
+  set.emplace(foo2);
+
+  auto it1 = set.find(foo1);
+  EXPECT_TRUE(it1 != set.end());
+  EXPECT_EQ(foo1, it1->get());
+
+  {
+    auto it2 = set.find(foo2);
+    EXPECT_TRUE(it2 != set.end());
+    EXPECT_EQ(foo2, it2->get());
+  }
+
+  EXPECT_TRUE(set.find(foo3) == set.end());
+
+  set.erase(it1);
+  EXPECT_EQ(2, Foo::instance_count);
+
+  EXPECT_TRUE(set.find(foo1) == set.end());
+
+  {
+    auto it2 = set.find(foo2);
+    EXPECT_TRUE(it2 != set.end());
+    EXPECT_EQ(foo2, it2->get());
+  }
+
+  set.clear();
+  EXPECT_EQ(1, Foo::instance_count);
+
+  EXPECT_TRUE(set.find(foo1) == set.end());
+  EXPECT_TRUE(set.find(foo2) == set.end());
+  EXPECT_TRUE(set.find(foo3) == set.end());
+
+  delete foo3;
+  EXPECT_EQ(0, Foo::instance_count);
+}
+
+}  // namespace
+}  // namespace base
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index 4dede57f..ef0ab6a2 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -11,7 +11,7 @@
 #include <unistd.h>
 
 #include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
@@ -421,8 +421,7 @@
       return FILE_ERROR_NOT_A_DIRECTORY;
     default:
 #if !defined(OS_NACL)  // NaCl build has no metrics code.
-      UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix",
-                                  saved_errno);
+      UmaHistogramSparse("PlatformFile.UnknownErrors.Posix", saved_errno);
 #endif
       // This function should only be called for errors.
       DCHECK_NE(0, saved_errno);
diff --git a/base/files/file_win.cc b/base/files/file_win.cc
index 5f897946..1bf51d2 100644
--- a/base/files/file_win.cc
+++ b/base/files/file_win.cc
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/threading/thread_restrictions.h"
 
 namespace base {
@@ -310,8 +310,7 @@
     case ERROR_DISK_CORRUPT:
       return FILE_ERROR_IO;
     default:
-      UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Windows",
-                                  last_error);
+      UmaHistogramSparse("PlatformFile.UnknownErrors.Windows", last_error);
       // This function should only be called for errors.
       DCHECK_NE(static_cast<DWORD>(ERROR_SUCCESS), last_error);
       return FILE_ERROR_FAILED;
diff --git a/base/memory/OWNERS b/base/memory/OWNERS
index bcaf778a..9b7cbb1 100644
--- a/base/memory/OWNERS
+++ b/base/memory/OWNERS
@@ -1,2 +1,4 @@
 per-file *chromeos*=skuhne@chromium.org
 per-file *chromeos*=oshima@chromium.org
+per-file *shared_memory*=set noparent
+per-file *shared_memory*=file://ipc/SECURITY_OWNERS
diff --git a/base/memory/shared_memory_win.cc b/base/memory/shared_memory_win.cc
index 942d9ea8..88771bc 100644
--- a/base/memory/shared_memory_win.cc
+++ b/base/memory/shared_memory_win.cc
@@ -10,12 +10,14 @@
 
 #include "base/logging.h"
 #include "base/memory/shared_memory_tracker.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/rand_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/unguessable_token.h"
 
+namespace base {
 namespace {
 
 // Errors that can occur during Shared Memory construction.
@@ -41,7 +43,7 @@
                             CREATE_ERROR_LAST + 1);
   static_assert(ERROR_SUCCESS == 0, "Windows error code changed!");
   if (winerror != ERROR_SUCCESS)
-    UMA_HISTOGRAM_SPARSE_SLOWLY("SharedMemory.CreateWinError", winerror);
+    UmaHistogramSparse("SharedMemory.CreateWinError", winerror);
 }
 
 typedef enum _SECTION_INFORMATION_CLASS {
@@ -135,8 +137,6 @@
 
 }  // namespace.
 
-namespace base {
-
 SharedMemory::SharedMemory() {}
 
 SharedMemory::SharedMemory(const string16& name) : name_(name) {}
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index 02ac860..488facd 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -21,7 +21,7 @@
 #include "base/debug/alias.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/metrics_hashes.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/persistent_memory_allocator.h"
@@ -437,8 +437,8 @@
   }
 
   if (!check_okay) {
-    UMA_HISTOGRAM_SPARSE_SLOWLY("Histogram.BadConstructionArguments",
-                                static_cast<Sample>(HashMetricName(name)));
+    UmaHistogramSparse("Histogram.BadConstructionArguments",
+                       static_cast<Sample>(HashMetricName(name)));
   }
 
   return check_okay;
diff --git a/base/metrics/histogram_functions.cc b/base/metrics/histogram_functions.cc
index 4c1a4b57..47eec7d 100644
--- a/base/metrics/histogram_functions.cc
+++ b/base/metrics/histogram_functions.cc
@@ -6,13 +6,14 @@
 
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_base.h"
+#include "base/metrics/sparse_histogram.h"
 #include "base/time/time.h"
 
 namespace base {
 
 void UmaHistogramBoolean(const std::string& name, bool sample) {
   HistogramBase* histogram = BooleanHistogram::FactoryGet(
-      name, base::HistogramBase::kUmaTargetedHistogramFlag);
+      name, HistogramBase::kUmaTargetedHistogramFlag);
   histogram->Add(sample);
 }
 
@@ -100,4 +101,10 @@
   UmaHistogramCustomCounts(name, sample, 1, 64000, 100);
 }
 
+void UmaHistogramSparse(const std::string& name, int sample) {
+  HistogramBase* histogram = SparseHistogram::FactoryGet(
+      name, HistogramBase::kUmaTargetedHistogramFlag);
+  histogram->Add(sample);
+}
+
 }  // namespace base
diff --git a/base/metrics/histogram_functions.h b/base/metrics/histogram_functions.h
index 4698628..c9632fa2 100644
--- a/base/metrics/histogram_functions.h
+++ b/base/metrics/histogram_functions.h
@@ -110,6 +110,35 @@
 // Used to measure common MB-granularity memory stats. Range is up to ~64G.
 BASE_EXPORT void UmaHistogramMemoryLargeMB(const std::string& name, int sample);
 
+// For recording sparse histograms.
+// The |sample| can be a negative or non-negative number.
+//
+// Sparse histograms are well suited for recording counts of exact sample values
+// that are sparsely distributed over a relatively large range, in cases where
+// ultra-fast performance is not critical. For instance, Sqlite.Version.* are
+// sparse because for any given database, there's going to be exactly one
+// version logged.
+//
+// Performance:
+// ------------
+// Sparse histograms are typically more memory-efficient but less time-efficient
+// than other histograms. Essentially, they sparse histograms use a map rather
+// than a vector for their backing storage; they also require lock acquisition
+// to increment a sample, whereas other histogram do not. Hence, each increment
+// operation is a bit slower than for other histograms. But, if the data is
+// sparse, then they use less memory client-side, because they allocate buckets
+// on demand rather than preallocating.
+//
+// Data size:
+// ----------
+// Note that server-side, we still need to load all buckets, across all users,
+// at once. Thus, please avoid exploding such histograms, i.e. uploading many
+// many distinct values to the server (across all users). Concretely, keep the
+// number of distinct values <= 100 ideally, definitely <= 1000. If you have no
+// guarantees on the range of your data, use clamping, e.g.:
+//   UmaHistogramSparse("MyHistogram", ClampToRange(value, 0, 200));
+BASE_EXPORT void UmaHistogramSparse(const std::string& name, int sample);
+
 }  // namespace base
 
 #endif  // BASE_METRICS_HISTOGRAM_FUNCTIONS_H_
diff --git a/base/metrics/histogram_functions_unittest.cc b/base/metrics/histogram_functions_unittest.cc
index 7bfd202e..372067475 100644
--- a/base/metrics/histogram_functions_unittest.cc
+++ b/base/metrics/histogram_functions_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/test/histogram_tester.h"
 #include "base/time/time.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -17,7 +18,7 @@
   UMA_HISTOGRAM_TESTING_ENUM_THIRD
 };
 
-TEST(HistogramFunctionsTest, HistogramExactLinear) {
+TEST(HistogramFunctionsTest, ExactLinear) {
   std::string histogram("Testing.UMA.HistogramExactLinear");
   HistogramTester tester;
   UmaHistogramExactLinear(histogram, 10, 100);
@@ -37,7 +38,7 @@
   tester.ExpectTotalCount(histogram, 5);
 }
 
-TEST(HistogramFunctionsTest, HistogramEnumeration) {
+TEST(HistogramFunctionsTest, Enumeration) {
   std::string histogram("Testing.UMA.HistogramEnumeration");
   HistogramTester tester;
   UmaHistogramEnumeration(histogram, UMA_HISTOGRAM_TESTING_ENUM_FIRST,
@@ -53,7 +54,7 @@
   tester.ExpectTotalCount(histogram, 2);
 }
 
-TEST(HistogramFunctionsTest, HistogramBoolean) {
+TEST(HistogramFunctionsTest, Boolean) {
   std::string histogram("Testing.UMA.HistogramBoolean");
   HistogramTester tester;
   UmaHistogramBoolean(histogram, true);
@@ -63,7 +64,7 @@
   tester.ExpectTotalCount(histogram, 2);
 }
 
-TEST(HistogramFunctionsTest, HistogramPercentage) {
+TEST(HistogramFunctionsTest, Percentage) {
   std::string histogram("Testing.UMA.HistogramPercentage");
   HistogramTester tester;
   UmaHistogramPercentage(histogram, 50);
@@ -74,7 +75,7 @@
   tester.ExpectTotalCount(histogram, 2);
 }
 
-TEST(HistogramFunctionsTest, HistogramCounts) {
+TEST(HistogramFunctionsTest, Counts) {
   std::string histogram("Testing.UMA.HistogramCount.Custom");
   HistogramTester tester;
   UmaHistogramCustomCounts(histogram, 10, 1, 100, 10);
@@ -89,7 +90,7 @@
   tester.ExpectTotalCount(histogram, 5);
 }
 
-TEST(HistogramFunctionsTest, HistogramTimes) {
+TEST(HistogramFunctionsTest, Times) {
   std::string histogram("Testing.UMA.HistogramTimes");
   HistogramTester tester;
   UmaHistogramTimes(histogram, TimeDelta::FromSeconds(1));
@@ -106,4 +107,21 @@
   tester.ExpectTotalCount(histogram, 4);
 }
 
+TEST(HistogramFunctionsTest, Sparse_SupportsLargeRange) {
+  std::string histogram("Testing.UMA.HistogramSparse");
+  HistogramTester tester;
+  UmaHistogramSparse(histogram, 0);
+  UmaHistogramSparse(histogram, 123456789);
+  UmaHistogramSparse(histogram, 123456789);
+  EXPECT_THAT(tester.GetAllSamples(histogram),
+              testing::ElementsAre(Bucket(0, 1), Bucket(123456789, 2)));
+}
+
+TEST(HistogramFunctionsTest, Sparse_SupportsNegativeValues) {
+  std::string histogram("Testing.UMA.HistogramSparse");
+  HistogramTester tester;
+  UmaHistogramSparse(histogram, -1);
+  tester.ExpectUniqueSample(histogram, -1, 1);
+}
+
 }  // namespace base.
diff --git a/base/metrics/histogram_samples.cc b/base/metrics/histogram_samples.cc
index 7703580..6830637 100644
--- a/base/metrics/histogram_samples.cc
+++ b/base/metrics/histogram_samples.cc
@@ -7,6 +7,7 @@
 #include <limits>
 
 #include "base/compiler_specific.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/numerics/safe_math.h"
@@ -258,8 +259,8 @@
                             MAX_NEGATIVE_SAMPLE_REASONS);
   UMA_HISTOGRAM_CUSTOM_COUNTS("UMA.NegativeSamples.Increment", increment, 1,
                               1 << 30, 100);
-  UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.NegativeSamples.Histogram",
-                              static_cast<int32_t>(id()));
+  UmaHistogramSparse("UMA.NegativeSamples.Histogram",
+                     static_cast<int32_t>(id()));
 }
 
 SampleCountIterator::~SampleCountIterator() = default;
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index be107c3..65adaaa 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -16,7 +16,7 @@
 #include "base/files/memory_mapped_file.h"
 #include "base/logging.h"
 #include "base/memory/shared_memory.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/sys_info.h"
@@ -966,8 +966,8 @@
       ::VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
   if (address)
     return Memory(address, MEM_VIRTUAL);
-  UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LocalPersistentMemoryAllocator.Failures.Win",
-                              ::GetLastError());
+  UmaHistogramSparse("UMA.LocalPersistentMemoryAllocator.Failures.Win",
+                     ::GetLastError());
 #elif defined(OS_POSIX)
   // MAP_ANON is deprecated on Linux but MAP_ANONYMOUS is not universal on Mac.
   // MAP_SHARED is not available on Linux <2.4 but required on Mac.
@@ -975,8 +975,8 @@
                    MAP_ANON | MAP_SHARED, -1, 0);
   if (address != MAP_FAILED)
     return Memory(address, MEM_VIRTUAL);
-  UMA_HISTOGRAM_SPARSE_SLOWLY(
-      "UMA.LocalPersistentMemoryAllocator.Failures.Posix", errno);
+  UmaHistogramSparse("UMA.LocalPersistentMemoryAllocator.Failures.Posix",
+                     errno);
 #else
 #error This architecture is not (yet) supported.
 #endif
diff --git a/base/metrics/sparse_histogram_unittest.cc b/base/metrics/sparse_histogram_unittest.cc
index eeba150..c09a566 100644
--- a/base/metrics/sparse_histogram_unittest.cc
+++ b/base/metrics/sparse_histogram_unittest.cc
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_samples.h"
 #include "base/metrics/metrics_hashes.h"
 #include "base/metrics/persistent_histogram_allocator.h"
@@ -172,9 +172,9 @@
 }
 
 TEST_P(SparseHistogramTest, MacroBasicTest) {
-  UMA_HISTOGRAM_SPARSE_SLOWLY("Sparse", 100);
-  UMA_HISTOGRAM_SPARSE_SLOWLY("Sparse", 200);
-  UMA_HISTOGRAM_SPARSE_SLOWLY("Sparse", 100);
+  UmaHistogramSparse("Sparse", 100);
+  UmaHistogramSparse("Sparse", 200);
+  UmaHistogramSparse("Sparse", 100);
 
   StatisticsRecorder::Histograms histograms;
   StatisticsRecorder::GetHistograms(&histograms);
@@ -202,7 +202,7 @@
   // variable as histogram name.
   for (int i = 0; i < 2; i++) {
     std::string name = StringPrintf("Sparse%d", i + 1);
-    UMA_HISTOGRAM_SPARSE_SLOWLY(name, 100);
+    UmaHistogramSparse(name, 100);
   }
 
   StatisticsRecorder::Histograms histograms;
diff --git a/base/process/process_info_win.cc b/base/process/process_info_win.cc
index b9864b0..a33216b 100644
--- a/base/process/process_info_win.cc
+++ b/base/process/process_info_win.cc
@@ -15,16 +15,11 @@
 
 namespace {
 
-base::win::ScopedHandle GetCurrentProcessToken() {
+HANDLE GetCurrentProcessToken() {
   HANDLE process_token;
-  BOOL result =
-      OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &process_token);
-  // These checks are turned on in release builds to debug
-  // https://bugs.chromium.org/p/chromium/issues/detail?id=748431.
-  PCHECK(result);
-  CHECK(process_token != NULL);
-  CHECK(process_token != INVALID_HANDLE_VALUE);
-  return base::win::ScopedHandle(process_token);
+  OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token);
+  DCHECK(process_token != NULL && process_token != INVALID_HANDLE_VALUE);
+  return process_token;
 }
 
 }  // namespace
@@ -43,11 +38,11 @@
 }
 
 IntegrityLevel GetCurrentProcessIntegrityLevel() {
-  base::win::ScopedHandle scoped_process_token(GetCurrentProcessToken());
+  HANDLE process_token(GetCurrentProcessToken());
 
   DWORD token_info_length = 0;
-  if (::GetTokenInformation(scoped_process_token.Get(), TokenIntegrityLevel,
-                            nullptr, 0, &token_info_length) ||
+  if (::GetTokenInformation(process_token, TokenIntegrityLevel, nullptr, 0,
+                            &token_info_length) ||
       ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
     return INTEGRITY_UNKNOWN;
   }
@@ -55,9 +50,8 @@
   auto token_label_bytes = std::make_unique<char[]>(token_info_length);
   TOKEN_MANDATORY_LABEL* token_label =
       reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get());
-  if (!::GetTokenInformation(scoped_process_token.Get(), TokenIntegrityLevel,
-                             token_label, token_info_length,
-                             &token_info_length)) {
+  if (!::GetTokenInformation(process_token, TokenIntegrityLevel, token_label,
+                             token_info_length, &token_info_length)) {
     return INTEGRITY_UNKNOWN;
   }
 
@@ -82,14 +76,14 @@
 }
 
 bool IsCurrentProcessElevated() {
-  base::win::ScopedHandle scoped_process_token(GetCurrentProcessToken());
+  HANDLE process_token(GetCurrentProcessToken());
 
   // Unlike TOKEN_ELEVATION_TYPE which returns TokenElevationTypeDefault when
   // UAC is turned off, TOKEN_ELEVATION returns whether the process is elevated.
   DWORD size;
   TOKEN_ELEVATION elevation;
-  if (!GetTokenInformation(scoped_process_token.Get(), TokenElevation,
-                           &elevation, sizeof(elevation), &size)) {
+  if (!GetTokenInformation(process_token, TokenElevation, &elevation,
+                           sizeof(elevation), &size)) {
     PLOG(ERROR) << "GetTokenInformation() failed";
     return false;
   }
diff --git a/base/trace_event/trace_config_unittest.cc b/base/trace_event/trace_config_unittest.cc
index 30f82f9..3cb6d61b 100644
--- a/base/trace_event/trace_config_unittest.cc
+++ b/base/trace_event/trace_config_unittest.cc
@@ -653,8 +653,8 @@
             tc.ToString());
   EXPECT_EQ(0u, tc.memory_dump_config().triggers.size());
   EXPECT_EQ(
-      TraceConfig::MemoryDumpConfig::HeapProfiler ::
-          kDefaultBreakdownThresholdBytes,
+      static_cast<uint32_t>(TraceConfig::MemoryDumpConfig::HeapProfiler::
+                                kDefaultBreakdownThresholdBytes),
       tc.memory_dump_config().heap_profiler_options.breakdown_threshold_bytes);
 }
 
@@ -664,8 +664,8 @@
   EXPECT_NE(std::string::npos, tc.ToString().find("memory_dump_config"));
   EXPECT_EQ(0u, tc.memory_dump_config().triggers.size());
   EXPECT_EQ(
-      TraceConfig::MemoryDumpConfig::HeapProfiler ::
-          kDefaultBreakdownThresholdBytes,
+      static_cast<uint32_t>(TraceConfig::MemoryDumpConfig::HeapProfiler::
+                                kDefaultBreakdownThresholdBytes),
       tc.memory_dump_config().heap_profiler_options.breakdown_threshold_bytes);
 }
 
diff --git a/base/win/shortcut_unittest.cc b/base/win/shortcut_unittest.cc
index f167915..3c1c26f 100644
--- a/base/win/shortcut_unittest.cc
+++ b/base/win/shortcut_unittest.cc
@@ -99,7 +99,8 @@
   ShortcutProperties properties_read_1;
   ASSERT_TRUE(ResolveShortcutProperties(
       file_1, ShortcutProperties::PROPERTIES_ALL, &properties_read_1));
-  EXPECT_EQ(ShortcutProperties::PROPERTIES_ALL, properties_read_1.options);
+  EXPECT_EQ(static_cast<unsigned>(ShortcutProperties::PROPERTIES_ALL),
+            properties_read_1.options);
   ValidatePathsAreEqual(link_properties_.target, properties_read_1.target);
   ValidatePathsAreEqual(link_properties_.working_dir,
                         properties_read_1.working_dir);
@@ -122,7 +123,8 @@
   ShortcutProperties properties_read_2;
   ASSERT_TRUE(ResolveShortcutProperties(
       file_2, ShortcutProperties::PROPERTIES_ALL, &properties_read_2));
-  EXPECT_EQ(ShortcutProperties::PROPERTIES_ALL, properties_read_2.options);
+  EXPECT_EQ(static_cast<unsigned>(ShortcutProperties::PROPERTIES_ALL),
+            properties_read_2.options);
   ValidatePathsAreEqual(only_target_properties.target,
                         properties_read_2.target);
   ValidatePathsAreEqual(FilePath(), properties_read_2.working_dir);
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 0705031..82a4786 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -352,7 +352,8 @@
   filter_group.add_argument(
       '-f', '--gtest_filter', '--gtest-filter',
       dest='test_filter',
-      help='googletest-style filter string.')
+      help='googletest-style filter string.',
+      default=os.environ.get('GTEST_FILTER'))
   filter_group.add_argument(
       '--gtest-filter-file',
       dest='test_filter_file', type=os.path.realpath,
@@ -413,7 +414,8 @@
   parser.add_argument(
       '-f', '--test-filter', '--gtest_filter', '--gtest-filter',
       dest='test_filter',
-      help='Test filter (if not fully qualified, will run all matches).')
+      help='Test filter (if not fully qualified, will run all matches).',
+      default=os.environ.get('GTEST_FILTER'))
   parser.add_argument(
       '--gtest_also_run_disabled_tests', '--gtest-also-run-disabled-tests',
       dest='run_disabled', action='store_true',
@@ -559,7 +561,8 @@
   parser.add_argument(
       '-f', '--gtest-filter',
       dest='test_filter',
-      help='googletest-style filter string.')
+      help='googletest-style filter string.',
+      default=os.environ.get('GTEST_FILTER'))
   parser.add_argument(
       '--test-apk',
       type=os.path.realpath,
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index f0cd33f7..159e84a 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1401,11 +1401,7 @@
             get_path_info(_packaged_resources_path, "dir") + "/" +
             get_path_info(_packaged_resources_path, "name") +
             ".intermediate.ap_"
-
-        # TODO(estevenson): Remove this check.
-        if (defined(invoker.post_process_args)) {
-          _srcjar_path = "${_srcjar_path}.intermediate.srcjar"
-        }
+        _srcjar_path = "${_srcjar_path}.intermediate.srcjar"
       }
     }
     action(_process_resources_target_name) {
@@ -1625,35 +1621,27 @@
         depfile = "${target_gen_dir}/${target_name}.d"
         script = invoker.post_process_script
         args = [
-          "--depfile",
-          rebase_path(depfile, root_build_dir),
-          "--apk-path",
-          rebase_path(_packaged_resources_path, root_build_dir),
-          "--output",
-          rebase_path(invoker.output, root_build_dir),
-        ]
+                 "--depfile",
+                 rebase_path(depfile, root_build_dir),
+                 "--apk-path",
+                 rebase_path(_packaged_resources_path, root_build_dir),
+                 "--output",
+                 rebase_path(invoker.output, root_build_dir),
+                 "--srcjar-in",
+                 rebase_path(_srcjar_path, root_build_dir),
+                 "--srcjar-out",
+                 rebase_path(invoker.srcjar_path, root_build_dir),
+               ] + invoker.post_process_args
         inputs = [
+          _srcjar_path,
           _packaged_resources_path,
         ]
         outputs = [
           invoker.output,
+          invoker.srcjar_path,
         ]
-        public_deps = [
-          ":${_process_resources_target_name}",
-        ]
-
-        # TODO(estevenson): Remove this check.
-        if (defined(invoker.post_process_args)) {
-          args += [
-                    "--srcjar-in",
-                    rebase_path(_srcjar_path, root_build_dir),
-                    "--srcjar-out",
-                    rebase_path(invoker.srcjar_path, root_build_dir),
-                  ] + invoker.post_process_args
-          inputs += [ _srcjar_path ]
-          outputs += [ invoker.srcjar_path ]
-          public_deps += invoker.post_process_deps
-        }
+        public_deps =
+            [ ":${_process_resources_target_name}" ] + invoker.post_process_deps
       }
     }
   }
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 9a3f384..a9b8ea20 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -2048,12 +2048,8 @@
       version_name = _version_name
       if (defined(invoker.post_process_package_resources_script)) {
         post_process_script = invoker.post_process_package_resources_script
-
-        # TODO(estevenson): Remove this check.
-        if (defined(invoker.post_process_package_resources_deps)) {
-          post_process_deps = invoker.post_process_package_resources_deps
-          post_process_args = invoker.post_process_package_resources_args
-        }
+        post_process_deps = invoker.post_process_package_resources_deps
+        post_process_args = invoker.post_process_package_resources_args
       }
       srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
       r_text_out_path = "${target_gen_dir}/${target_name}_R.txt"
diff --git a/build/config/merge_for_jumbo.py b/build/config/merge_for_jumbo.py
index 7e5e2d4..4892c07 100755
--- a/build/config/merge_for_jumbo.py
+++ b/build/config/merge_for_jumbo.py
@@ -19,9 +19,11 @@
 # ignored by the build system. We warn for unexpected files in the
 # sources list, but these are ok.
 NOOP_FILE_SUFFIXES = (
+  ".css",
   ".g",
   ".idl",
   ".inc",
+  ".js",
   ".json",
   ".py",
 )
diff --git a/build/linux/BUILD.gn b/build/linux/BUILD.gn
index 1573bb0..54314c7 100644
--- a/build/linux/BUILD.gn
+++ b/build/linux/BUILD.gn
@@ -10,25 +10,7 @@
   pkg_config("gio_config") {
     packages = [ "gio-2.0" ]
 
-    # glib >=2.40 deprecate g_settings_list_schemas in favor of
-    # g_settings_schema_source_list_schemas. This function is not available on
-    # earlier versions that we still need to support (specifically, 2.32), so
-    # disable the warning with the GLIB_DISABLE_DEPRECATION_WARNINGS define.
-    # TODO(mgiuca): Remove this suppression when we drop support for Ubuntu
-    # 13.10 (saucy) and earlier. Update the code to use
-    # g_settings_schema_source_list_schemas instead.
-    defines = [
-      "USE_GIO",
-      "GLIB_DISABLE_DEPRECATION_WARNINGS",
-    ]
-
-    # TODO(brettw) Theoretically I think ignore_libs should be set so that we
-    # don't link directly to GIO and use the loader generated below. But the
-    # gio target in GYP doesn't make any sense to me and appears to link
-    # directly to GIO in addition to making a loader. This this uncommented,
-    # the link in component build fails, so I think this is closer to the
-    # GYP build.
-    #ignore_libs = true  # Loader generated below.
+    defines = [ "USE_GIO" ]
   }
 }
 
diff --git a/build/linux/libgio/BUILD.gn b/build/linux/libgio/BUILD.gn
deleted file mode 100644
index 3deb63dd..0000000
--- a/build/linux/libgio/BUILD.gn
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//tools/generate_library_loader/generate_library_loader.gni")
-
-# This generates a target named "libgio".
-generate_library_loader("libgio") {
-  name = "LibGioLoader"
-  output_h = "libgio.h"
-  output_cc = "libgio_loader.cc"
-  header = "<gio/gio.h>"
-  config = "//build/linux:gio_config"
-
-  functions = [
-    "glib_check_version",
-    "g_type_init",
-    "g_settings_new",
-    "g_settings_get_child",
-    "g_settings_get_string",
-    "g_settings_get_boolean",
-    "g_settings_get_int",
-    "g_settings_get_strv",
-    "g_settings_list_schemas",
-  ]
-}
diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py
index 1bd4fd7..78871afa 100755
--- a/build/mac_toolchain.py
+++ b/build/mac_toolchain.py
@@ -37,7 +37,7 @@
 # 16 is the major version number for macOS 10.12.
 MAC_MINIMUM_OS_VERSION = 16
 
-IOS_TOOLCHAIN_VERSION = '9B55'
+IOS_TOOLCHAIN_VERSION = '9C40b'
 IOS_TOOLCHAIN_SUB_REVISION = 1
 IOS_TOOLCHAIN_VERSION = '%s-%s' % (IOS_TOOLCHAIN_VERSION,
                                    IOS_TOOLCHAIN_SUB_REVISION)
diff --git a/build/toolchain/win/rc/linux64/rc.sha1 b/build/toolchain/win/rc/linux64/rc.sha1
index 76f7627b..11440ae 100644
--- a/build/toolchain/win/rc/linux64/rc.sha1
+++ b/build/toolchain/win/rc/linux64/rc.sha1
@@ -1 +1 @@
-a6d75f015275c8a65ff855e8b78437dd03a9bb7d
\ No newline at end of file
+e642170ce663c75a44822c3bffb1579068ab6f17
\ No newline at end of file
diff --git a/build/toolchain/win/rc/mac/rc.sha1 b/build/toolchain/win/rc/mac/rc.sha1
index 8a817c52..ff0c32e 100644
--- a/build/toolchain/win/rc/mac/rc.sha1
+++ b/build/toolchain/win/rc/mac/rc.sha1
@@ -1 +1 @@
-3ccc7a61fc5368e8db33364093e42a92de874a26
\ No newline at end of file
+58489426ecea29e276c94529201bc6a0cc1da027
\ No newline at end of file
diff --git a/build/toolchain/win/rc/win/rc.exe.sha1 b/build/toolchain/win/rc/win/rc.exe.sha1
index c74dce41..165e4688 100644
--- a/build/toolchain/win/rc/win/rc.exe.sha1
+++ b/build/toolchain/win/rc/win/rc.exe.sha1
@@ -1 +1 @@
-9887dc07d042bf58d20b5557e3f91d18d0254022
\ No newline at end of file
+9de6c3d751b4432a3a7b1cf96f432a21187764e9
\ No newline at end of file
diff --git a/build/util/lib/common/chrome_test_server_spawner.py b/build/util/lib/common/chrome_test_server_spawner.py
index d23db0e..3cbcde17 100644
--- a/build/util/lib/common/chrome_test_server_spawner.py
+++ b/build/util/lib/common/chrome_test_server_spawner.py
@@ -115,9 +115,11 @@
     self.test_server_process = None
     self.is_ready = False
     self.host_port = self.arguments['port']
+    self.host_ocsp_port = 0
     assert isinstance(self.host_port, int)
     # The forwarder device port now is dynamically allocated.
     self.forwarder_device_port = 0
+    self.forwarder_ocsp_device_port = 0
     # Anonymous pipe in order to get port info from test server.
     self.pipe_in = None
     self.pipe_out = None
@@ -152,18 +154,29 @@
     if not data_length:
       logging.error('Failed to get length of server data.')
       return False
-    port_json = os.read(self.pipe_in, data_length)
-    if not port_json:
+    server_data_json = os.read(self.pipe_in, data_length)
+    if not server_data_json:
       logging.error('Failed to get server data.')
       return False
-    logging.info('Got port json data: %s', port_json)
-    port_json = json.loads(port_json)
+    logging.info('Got port json data: %s', server_data_json)
 
-    if not port_json.has_key('port') or not isinstance(port_json['port'], int):
+    parsed_server_data = None
+    try:
+      parsed_server_data = json.loads(server_data_json)
+    except ValueError:
+      pass
+
+    if not isinstance(parsed_server_data, dict):
+      logging.error('Failed to parse server_data: %s' % server_data_json)
+      return False
+
+    if not isinstance(parsed_server_data.get('port'), int):
       logging.error('Failed to get port information from the server data.')
       return False
 
-    self.host_port = port_json['port']
+    self.host_port = parsed_server_data['port']
+    self.host_ocsp_port = parsed_server_data.get('ocsp_port', 0)
+
     return self.port_forwarder.WaitPortNotAvailable(self.host_port)
 
   def _GenerateCommandLineArguments(self):
@@ -240,15 +253,23 @@
         self.is_ready = self._WaitToStartAndGetPortFromTestServer()
       else:
         self.is_ready = self.port_forwarder.WaitPortNotAvailable(self.host_port)
+
     if self.is_ready:
-      self.port_forwarder.Map([(0, self.host_port)])
+      port_map = [(0, self.host_port)]
+      if self.host_ocsp_port:
+        port_map.append([(0, self.host_ocsp_port)])
+      self.port_forwarder.Map(port_map)
+
+      self.forwarder_device_port = \
+          self.port_forwarder.GetDevicePortForHostPort(self.host_port)
+      if self.host_ocsp_port:
+        self.forwarder_ocsp_device_port = \
+            self.port_forwarder.GetDevicePortForHostPort(self.host_ocsp_port)
 
       # Check whether the forwarder is ready on the device.
-      self.is_ready = False
-      device_port = self.port_forwarder.GetDevicePortForHostPort(self.host_port)
-      if device_port and self.port_forwarder.WaitDevicePortReady(device_port):
-        self.is_ready = True
-        self.forwarder_device_port = device_port
+      self.is_ready = self.forwarder_device_port and \
+          self.port_forwarder.WaitDevicePortReady(self.forwarder_device_port)
+
     # Wake up the request handler thread.
     self.ready_event.set()
     # Keep thread running until Stop() gets called.
@@ -332,9 +353,11 @@
     new_server.start()
     ready_event.wait()
     if new_server.is_ready:
-      self._SendResponse(200, 'OK', {}, json.dumps(
-          {'port': new_server.forwarder_device_port,
-           'message': 'started'}))
+      response = {'port': new_server.forwarder_device_port,
+                  'message': 'started'};
+      if new_server.forwarder_ocsp_device_port:
+        response['ocsp_port'] = new_server.forwarder_ocsp_device_port
+      self._SendResponse(200, 'OK', {}, json.dumps(response))
       logging.info('Test server is running on port %d forwarded to %d.' %
               (new_server.forwarder_device_port, new_server.host_port))
       port = new_server.forwarder_device_port
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 29f127f..168a79e 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -622,7 +622,7 @@
     "paint/paint_op_buffer_unittest.cc",
     "paint/paint_op_helper_unittest.cc",
     "paint/paint_shader_unittest.cc",
-    "paint/scoped_image_flags_unittest.cc",
+    "paint/scoped_raster_flags_unittest.cc",
     "paint/solid_color_analyzer_unittest.cc",
     "paint/transfer_cache_unittest.cc",
     "raster/playback_image_provider_unittest.cc",
@@ -630,6 +630,7 @@
     "raster/raster_source_unittest.cc",
     "raster/scoped_gpu_raster_unittest.cc",
     "raster/single_thread_task_graph_runner_unittest.cc",
+    "raster/staging_buffer_pool_unittest.cc",
     "raster/synchronous_task_graph_runner_unittest.cc",
     "raster/task_graph_work_queue_unittest.cc",
     "raster/texture_compressor_etc1_unittest.cc",
diff --git a/cc/ipc/cc_param_traits.cc b/cc/ipc/cc_param_traits.cc
index 3bf214a..0b27652 100644
--- a/cc/ipc/cc_param_traits.cc
+++ b/cc/ipc/cc_param_traits.cc
@@ -626,6 +626,7 @@
 void ParamTraits<viz::LocalSurfaceId>::Write(base::Pickle* m,
                                              const param_type& p) {
   WriteParam(m, p.parent_id());
+  WriteParam(m, p.child_sequence_number());
   WriteParam(m, p.nonce());
 }
 
@@ -636,11 +637,15 @@
   if (!ReadParam(m, iter, &parent_id))
     return false;
 
+  uint32_t child_sequence_number;
+  if (!ReadParam(m, iter, &child_sequence_number))
+    return false;
+
   base::UnguessableToken nonce;
   if (!ReadParam(m, iter, &nonce))
     return false;
 
-  *p = viz::LocalSurfaceId(parent_id, nonce);
+  *p = viz::LocalSurfaceId(parent_id, child_sequence_number, nonce);
   return true;
 }
 
@@ -649,6 +654,8 @@
   l->append("viz::LocalSurfaceId(");
   LogParam(p.parent_id(), l);
   l->append(", ");
+  LogParam(p.child_sequence_number(), l);
+  l->append(", ");
   LogParam(p.nonce(), l);
   l->append(")");
 }
diff --git a/cc/paint/BUILD.gn b/cc/paint/BUILD.gn
index 3448f4d..93438a6 100644
--- a/cc/paint/BUILD.gn
+++ b/cc/paint/BUILD.gn
@@ -66,8 +66,8 @@
     "record_paint_canvas.h",
     "render_surface_filters.cc",
     "render_surface_filters.h",
-    "scoped_image_flags.cc",
-    "scoped_image_flags.h",
+    "scoped_raster_flags.cc",
+    "scoped_raster_flags.h",
     "skia_paint_canvas.cc",
     "skia_paint_canvas.h",
     "skia_paint_image_generator.cc",
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc
index 252783d..37a018a 100644
--- a/cc/paint/image_transfer_cache_entry.cc
+++ b/cc/paint/image_transfer_cache_entry.cc
@@ -42,9 +42,10 @@
   return size_;
 }
 
-bool ClientImageTransferCacheEntry::Serialize(size_t size,
-                                              uint8_t* data) const {
-  PaintOpWriter writer(data, size);
+bool ClientImageTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
+  DCHECK_GE(data.size(), SerializedSize());
+
+  PaintOpWriter writer(data.data(), data.size());
   writer.Write(pixmap_->colorType());
   writer.Write(pixmap_->width());
   writer.Write(pixmap_->height());
@@ -53,7 +54,7 @@
   writer.WriteData(pixmap_size, pixmap_->addr());
   // TODO(ericrk): Handle colorspace.
 
-  if (writer.size() != size)
+  if (writer.size() != data.size())
     return false;
 
   return true;
@@ -66,14 +67,13 @@
   return TransferCacheEntryType::kImage;
 }
 
-size_t ServiceImageTransferCacheEntry::Size() const {
+size_t ServiceImageTransferCacheEntry::CachedSize() const {
   return size_;
 }
 
 bool ServiceImageTransferCacheEntry::Deserialize(GrContext* context,
-                                                 size_t size,
-                                                 uint8_t* data) {
-  PaintOpReader reader(data, size);
+                                                 base::span<uint8_t> data) {
+  PaintOpReader reader(data.data(), data.size());
   SkColorType color_type;
   reader.Read(&color_type);
   uint32_t width;
@@ -82,7 +82,7 @@
   reader.Read(&height);
   size_t pixel_size;
   reader.ReadSize(&pixel_size);
-  size_ = size;
+  size_ = data.size();
   if (!reader.valid())
     return false;
   // TODO(ericrk): Handle colorspace.
diff --git a/cc/paint/image_transfer_cache_entry.h b/cc/paint/image_transfer_cache_entry.h
index b99e58db..bd3a5138 100644
--- a/cc/paint/image_transfer_cache_entry.h
+++ b/cc/paint/image_transfer_cache_entry.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include "base/containers/span.h"
 #include "cc/paint/transfer_cache_entry.h"
 #include "third_party/skia/include/core/SkImage.h"
 
@@ -21,12 +22,12 @@
   explicit ClientImageTransferCacheEntry(
       const SkPixmap* pixmap,
       const SkColorSpace* target_color_space);
-  ~ClientImageTransferCacheEntry() override;
+  ~ClientImageTransferCacheEntry() final;
 
   // ClientTransferCacheEntry implementation:
-  TransferCacheEntryType Type() const override;
-  size_t SerializedSize() const override;
-  bool Serialize(size_t size, uint8_t* data) const override;
+  TransferCacheEntryType Type() const final;
+  size_t SerializedSize() const final;
+  bool Serialize(base::span<uint8_t> data) const final;
 
  private:
   const SkPixmap* const pixmap_;
@@ -37,12 +38,12 @@
     : public ServiceTransferCacheEntry {
  public:
   ServiceImageTransferCacheEntry();
-  ~ServiceImageTransferCacheEntry() override;
+  ~ServiceImageTransferCacheEntry() final;
 
   // ServiceTransferCacheEntry implementation:
-  TransferCacheEntryType Type() const override;
-  size_t Size() const override;
-  bool Deserialize(GrContext* context, size_t size, uint8_t* data) override;
+  TransferCacheEntryType Type() const final;
+  size_t CachedSize() const final;
+  bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
 
   const sk_sp<SkImage>& image() { return image_; }
 
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc
index 5edbd0b..4c603ea 100644
--- a/cc/paint/paint_op_buffer.cc
+++ b/cc/paint/paint_op_buffer.cc
@@ -12,7 +12,7 @@
 #include "cc/paint/paint_op_reader.h"
 #include "cc/paint/paint_op_writer.h"
 #include "cc/paint/paint_record.h"
-#include "cc/paint/scoped_image_flags.h"
+#include "cc/paint/scoped_raster_flags.h"
 #include "third_party/skia/include/core/SkAnnotation.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkRegion.h"
@@ -2165,18 +2165,10 @@
 
     if (op->IsPaintOpWithFlags()) {
       const auto* flags_op = static_cast<const PaintOpWithFlags*>(op);
-      base::Optional<ScopedImageFlags> scoped_flags;
-      const bool needs_flag_override =
-          iter.alpha() != 255 ||
-          (flags_op->flags.HasDiscardableImages() && params.image_provider);
-      if (needs_flag_override) {
-        scoped_flags.emplace(params.image_provider, &flags_op->flags,
-                             canvas->getTotalMatrix(), iter.alpha());
-      }
-
-      const PaintFlags* raster_flags =
-          scoped_flags ? scoped_flags->flags() : &flags_op->flags;
-      if (raster_flags)
+      const ScopedRasterFlags scoped_flags(
+          &flags_op->flags, params.image_provider, canvas->getTotalMatrix(),
+          iter.alpha());
+      if (const auto* raster_flags = scoped_flags.flags())
         flags_op->RasterWithFlags(canvas, raster_flags, params);
       continue;
     }
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h
index 2b1e250..c32b09e2 100644
--- a/cc/paint/paint_op_buffer.h
+++ b/cc/paint/paint_op_buffer.h
@@ -1026,7 +1026,6 @@
   friend class DisplayItemList;
   friend class PaintOpBufferOffsetsTest;
   friend class SolidColorAnalyzer;
-  friend class ScopedImageFlags;
 
   // Replays the paint op buffer into the canvas. If |indices| is specified, it
   // contains indices in an increasing order and only the indices specified in
diff --git a/cc/paint/paint_op_buffer_serializer.cc b/cc/paint/paint_op_buffer_serializer.cc
index 856c09b..e24784a 100644
--- a/cc/paint/paint_op_buffer_serializer.cc
+++ b/cc/paint/paint_op_buffer_serializer.cc
@@ -5,7 +5,7 @@
 #include "cc/paint/paint_op_buffer_serializer.h"
 
 #include "base/bind.h"
-#include "cc/paint/scoped_image_flags.h"
+#include "cc/paint/scoped_raster_flags.h"
 #include "ui/gfx/skia_util.h"
 
 namespace cc {
@@ -124,18 +124,10 @@
     PaintOp::SerializeOptions* options,
     const PlaybackParams& params,
     uint8_t alpha) {
-  const bool needs_flag_override =
-      alpha != 255 ||
-      (flags_op->flags.HasDiscardableImages() && options->image_provider);
-
-  base::Optional<ScopedImageFlags> scoped_flags;
-  if (needs_flag_override) {
-    scoped_flags.emplace(options->image_provider, &flags_op->flags,
-                         options->canvas->getTotalMatrix(), alpha);
-  }
-
-  const PaintFlags* flags_to_serialize =
-      scoped_flags ? scoped_flags->flags() : &flags_op->flags;
+  const ScopedRasterFlags scoped_flags(
+      &flags_op->flags, options->image_provider,
+      options->canvas->getTotalMatrix(), alpha);
+  const PaintFlags* flags_to_serialize = scoped_flags.flags();
   if (!flags_to_serialize)
     return true;
 
diff --git a/cc/paint/paint_shader.h b/cc/paint/paint_shader.h
index 6c72074..de9afa1 100644
--- a/cc/paint/paint_shader.h
+++ b/cc/paint/paint_shader.h
@@ -134,7 +134,7 @@
   friend class PaintOpReader;
   friend class PaintOpSerializationTestUtils;
   friend class PaintOpWriter;
-  friend class ScopedImageFlags;
+  friend class ScopedRasterFlags;
   FRIEND_TEST_ALL_PREFIXES(PaintShaderTest, DecodePaintRecord);
 
   explicit PaintShader(Type type);
diff --git a/cc/paint/raw_memory_transfer_cache_entry.cc b/cc/paint/raw_memory_transfer_cache_entry.cc
index 9e4660c6..4702550b 100644
--- a/cc/paint/raw_memory_transfer_cache_entry.cc
+++ b/cc/paint/raw_memory_transfer_cache_entry.cc
@@ -4,6 +4,8 @@
 
 #include "cc/paint/raw_memory_transfer_cache_entry.h"
 
+#include <string.h>
+
 namespace cc {
 
 ClientRawMemoryTransferCacheEntry::ClientRawMemoryTransferCacheEntry(
@@ -20,12 +22,12 @@
   return data_.size();
 }
 
-bool ClientRawMemoryTransferCacheEntry::Serialize(size_t size,
-                                                  uint8_t* data) const {
-  if (size != data_.size())
+bool ClientRawMemoryTransferCacheEntry::Serialize(
+    base::span<uint8_t> data) const {
+  if (data.size() != data_.size())
     return false;
 
-  memcpy(data, data_.data(), size);
+  memcpy(data.data(), data_.data(), data.size());
   return true;
 }
 
@@ -38,15 +40,13 @@
   return TransferCacheEntryType::kRawMemory;
 }
 
-size_t ServiceRawMemoryTransferCacheEntry::Size() const {
+size_t ServiceRawMemoryTransferCacheEntry::CachedSize() const {
   return data_.size();
 }
 
 bool ServiceRawMemoryTransferCacheEntry::Deserialize(GrContext* context,
-                                                     size_t size,
-                                                     uint8_t* data) {
-  data_.resize(size);
-  memcpy(data_.data(), data, size);
+                                                     base::span<uint8_t> data) {
+  data_ = std::vector<uint8_t>(data.begin(), data.end());
   return true;
 }
 
diff --git a/cc/paint/raw_memory_transfer_cache_entry.h b/cc/paint/raw_memory_transfer_cache_entry.h
index 981f2fd..71e4745 100644
--- a/cc/paint/raw_memory_transfer_cache_entry.h
+++ b/cc/paint/raw_memory_transfer_cache_entry.h
@@ -18,10 +18,10 @@
     : public ClientTransferCacheEntry {
  public:
   explicit ClientRawMemoryTransferCacheEntry(std::vector<uint8_t> data);
-  ~ClientRawMemoryTransferCacheEntry() override;
-  TransferCacheEntryType Type() const override;
-  size_t SerializedSize() const override;
-  bool Serialize(size_t size, uint8_t* data) const override;
+  ~ClientRawMemoryTransferCacheEntry() final;
+  TransferCacheEntryType Type() const final;
+  size_t SerializedSize() const final;
+  bool Serialize(base::span<uint8_t> data) const final;
 
  private:
   std::vector<uint8_t> data_;
@@ -31,10 +31,10 @@
     : public ServiceTransferCacheEntry {
  public:
   ServiceRawMemoryTransferCacheEntry();
-  ~ServiceRawMemoryTransferCacheEntry() override;
-  TransferCacheEntryType Type() const override;
-  size_t Size() const override;
-  bool Deserialize(GrContext* context, size_t size, uint8_t* data) override;
+  ~ServiceRawMemoryTransferCacheEntry() final;
+  TransferCacheEntryType Type() const final;
+  size_t CachedSize() const final;
+  bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
   const std::vector<uint8_t>& data() { return data_; }
 
  private:
diff --git a/cc/paint/scoped_image_flags.cc b/cc/paint/scoped_image_flags.cc
deleted file mode 100644
index ea81ad5..0000000
--- a/cc/paint/scoped_image_flags.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/paint/scoped_image_flags.h"
-
-#include "cc/paint/image_provider.h"
-#include "cc/paint/paint_image_builder.h"
-
-namespace cc {
-ScopedImageFlags::DecodeStashingImageProvider::DecodeStashingImageProvider(
-    ImageProvider* source_provider)
-    : source_provider_(source_provider) {
-  DCHECK(source_provider_);
-}
-ScopedImageFlags::DecodeStashingImageProvider::~DecodeStashingImageProvider() =
-    default;
-
-ImageProvider::ScopedDecodedDrawImage
-ScopedImageFlags::DecodeStashingImageProvider::GetDecodedDrawImage(
-    const DrawImage& draw_image) {
-  auto decode = source_provider_->GetDecodedDrawImage(draw_image);
-  if (!decode)
-    return ScopedDecodedDrawImage();
-
-  // No need to add any destruction callback to the returned image. The images
-  // decoded here match the lifetime of this provider.
-  auto image_to_return = ScopedDecodedDrawImage(decode.decoded_image());
-  decoded_images_->push_back(std::move(decode));
-  return image_to_return;
-}
-
-ScopedImageFlags::ScopedImageFlags(ImageProvider* image_provider,
-                                   const PaintFlags* flags,
-                                   const SkMatrix& ctm,
-                                   uint8_t alpha) {
-  DCHECK(flags->HasDiscardableImages() || alpha != 255);
-  if (flags->HasDiscardableImages() && image_provider) {
-    DCHECK(flags->HasShader());
-
-    decode_stashing_image_provider_.emplace(image_provider);
-    modified_flags_.emplace(*flags);
-    if (flags->getShader()->shader_type() == PaintShader::Type::kImage) {
-      DecodeImageShader(flags, ctm);
-    } else if (flags->getShader()->shader_type() ==
-               PaintShader::Type::kPaintRecord) {
-      DecodeRecordShader(flags, ctm);
-    } else {
-      NOTREACHED();
-    }
-
-    // We skip the op if any images fail to decode.
-    if (decode_failed_)
-      return;
-  }
-
-  if (alpha != 255) {
-    DCHECK(flags->SupportsFoldingAlpha());
-    if (!modified_flags_)
-      modified_flags_.emplace(*flags);
-    modified_flags_->setAlpha(SkMulDiv255Round(flags->getAlpha(), alpha));
-  }
-
-  DCHECK(modified_flags_);
-}
-
-ScopedImageFlags::~ScopedImageFlags() = default;
-
-void ScopedImageFlags::DecodeImageShader(const PaintFlags* original,
-                                         const SkMatrix& ctm) {
-  const PaintImage& paint_image = original->getShader()->paint_image();
-  SkMatrix matrix = original->getShader()->GetLocalMatrix();
-
-  SkMatrix total_image_matrix = matrix;
-  total_image_matrix.preConcat(ctm);
-  SkRect src_rect = SkRect::MakeIWH(paint_image.width(), paint_image.height());
-  SkIRect int_src_rect;
-  src_rect.roundOut(&int_src_rect);
-  DrawImage draw_image(paint_image, int_src_rect, original->getFilterQuality(),
-                       total_image_matrix);
-  auto decoded_draw_image =
-      decode_stashing_image_provider_->GetDecodedDrawImage(draw_image);
-
-  if (!decoded_draw_image) {
-    decode_failed_ = true;
-    return;
-  }
-
-  const auto& decoded_image = decoded_draw_image.decoded_image();
-  DCHECK(decoded_image.image());
-
-  bool need_scale = !decoded_image.is_scale_adjustment_identity();
-  if (need_scale) {
-    matrix.preScale(1.f / decoded_image.scale_adjustment().width(),
-                    1.f / decoded_image.scale_adjustment().height());
-  }
-
-  sk_sp<SkImage> sk_image =
-      sk_ref_sp<SkImage>(const_cast<SkImage*>(decoded_image.image().get()));
-  PaintImage decoded_paint_image = PaintImageBuilder::WithDefault()
-                                       .set_id(paint_image.stable_id())
-                                       .set_image(std::move(sk_image))
-                                       .TakePaintImage();
-  modified_flags_->setFilterQuality(decoded_image.filter_quality());
-  modified_flags_->setShader(
-      PaintShader::MakeImage(decoded_paint_image, original->getShader()->tx(),
-                             original->getShader()->ty(), &matrix));
-}
-
-void ScopedImageFlags::DecodeRecordShader(const PaintFlags* original,
-                                          const SkMatrix& ctm) {
-  auto decoded_shader = original->getShader()->CreateDecodedPaintRecord(
-      ctm, &*decode_stashing_image_provider_);
-  if (!decoded_shader) {
-    decode_failed_ = true;
-    return;
-  }
-
-  modified_flags_->setShader(std::move(decoded_shader));
-}
-
-}  // namespace cc
diff --git a/cc/paint/scoped_raster_flags.cc b/cc/paint/scoped_raster_flags.cc
new file mode 100644
index 0000000..deb5ee8
--- /dev/null
+++ b/cc/paint/scoped_raster_flags.cc
@@ -0,0 +1,154 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/paint/scoped_raster_flags.h"
+
+#include "cc/paint/image_provider.h"
+#include "cc/paint/paint_image_builder.h"
+
+namespace cc {
+ScopedRasterFlags::DecodeStashingImageProvider::DecodeStashingImageProvider(
+    ImageProvider* source_provider)
+    : source_provider_(source_provider) {
+  DCHECK(source_provider_);
+}
+ScopedRasterFlags::DecodeStashingImageProvider::~DecodeStashingImageProvider() =
+    default;
+
+ImageProvider::ScopedDecodedDrawImage
+ScopedRasterFlags::DecodeStashingImageProvider::GetDecodedDrawImage(
+    const DrawImage& draw_image) {
+  auto decode = source_provider_->GetDecodedDrawImage(draw_image);
+  if (!decode)
+    return ScopedDecodedDrawImage();
+
+  // No need to add any destruction callback to the returned image. The images
+  // decoded here match the lifetime of this provider.
+  auto image_to_return = ScopedDecodedDrawImage(decode.decoded_image());
+  decoded_images_->push_back(std::move(decode));
+  return image_to_return;
+}
+
+ScopedRasterFlags::ScopedRasterFlags(const PaintFlags* flags,
+                                     ImageProvider* image_provider,
+                                     const SkMatrix& ctm,
+                                     uint8_t alpha)
+    : original_flags_(flags) {
+  if (flags->HasDiscardableImages() && image_provider) {
+    DCHECK(flags->HasShader());
+
+    decode_stashing_image_provider_.emplace(image_provider);
+    if (flags->getShader()->shader_type() == PaintShader::Type::kImage) {
+      DecodeImageShader(ctm);
+    } else if (flags->getShader()->shader_type() ==
+               PaintShader::Type::kPaintRecord) {
+      DecodeRecordShader(ctm);
+    } else {
+      NOTREACHED();
+    }
+
+    // We skip the op if any images fail to decode.
+    if (decode_failed_)
+      return;
+  }
+
+  if (alpha != 255) {
+    DCHECK(flags->SupportsFoldingAlpha());
+    MutableFlags()->setAlpha(SkMulDiv255Round(flags->getAlpha(), alpha));
+  }
+
+  AdjustStrokeIfNeeded(ctm);
+}
+
+ScopedRasterFlags::~ScopedRasterFlags() = default;
+
+void ScopedRasterFlags::DecodeImageShader(const SkMatrix& ctm) {
+  const PaintImage& paint_image = flags()->getShader()->paint_image();
+  SkMatrix matrix = flags()->getShader()->GetLocalMatrix();
+
+  SkMatrix total_image_matrix = matrix;
+  total_image_matrix.preConcat(ctm);
+  SkRect src_rect = SkRect::MakeIWH(paint_image.width(), paint_image.height());
+  SkIRect int_src_rect;
+  src_rect.roundOut(&int_src_rect);
+  DrawImage draw_image(paint_image, int_src_rect, flags()->getFilterQuality(),
+                       total_image_matrix);
+  auto decoded_draw_image =
+      decode_stashing_image_provider_->GetDecodedDrawImage(draw_image);
+
+  if (!decoded_draw_image) {
+    decode_failed_ = true;
+    return;
+  }
+
+  const auto& decoded_image = decoded_draw_image.decoded_image();
+  DCHECK(decoded_image.image());
+
+  bool need_scale = !decoded_image.is_scale_adjustment_identity();
+  if (need_scale) {
+    matrix.preScale(1.f / decoded_image.scale_adjustment().width(),
+                    1.f / decoded_image.scale_adjustment().height());
+  }
+
+  sk_sp<SkImage> sk_image =
+      sk_ref_sp<SkImage>(const_cast<SkImage*>(decoded_image.image().get()));
+  PaintImage decoded_paint_image = PaintImageBuilder::WithDefault()
+                                       .set_id(paint_image.stable_id())
+                                       .set_image(std::move(sk_image))
+                                       .TakePaintImage();
+  MutableFlags()->setFilterQuality(decoded_image.filter_quality());
+  MutableFlags()->setShader(
+      PaintShader::MakeImage(decoded_paint_image, flags()->getShader()->tx(),
+                             flags()->getShader()->ty(), &matrix));
+}
+
+void ScopedRasterFlags::DecodeRecordShader(const SkMatrix& ctm) {
+  auto decoded_shader = flags()->getShader()->CreateDecodedPaintRecord(
+      ctm, &*decode_stashing_image_provider_);
+  if (!decoded_shader) {
+    decode_failed_ = true;
+    return;
+  }
+
+  MutableFlags()->setShader(std::move(decoded_shader));
+}
+
+void ScopedRasterFlags::AdjustStrokeIfNeeded(const SkMatrix& ctm) {
+  // With anti-aliasing turned off, strokes with a device space width in (0, 1)
+  // may not raster at all.  To avoid this, we have two options:
+  //
+  // 1) force a hairline stroke (stroke-width == 0)
+  // 2) force anti-aliasing on
+
+  SkSize scale;
+  if (flags()->isAntiAlias() ||                          // safe to raster
+      flags()->getStyle() == PaintFlags::kFill_Style ||  // not a stroke
+      !flags()->getStrokeWidth() ||                      // explicit hairline
+      !ctm.decomposeScale(&scale)) {                     // cannot decompose
+    return;
+  }
+
+  const auto stroke_vec =
+      SkVector::Make(flags()->getStrokeWidth() * scale.width(),
+                     flags()->getStrokeWidth() * scale.height());
+  if (stroke_vec.x() >= 1.f && stroke_vec.y() >= 1.f)
+    return;  // safe to raster
+
+  const auto can_substitute_hairline =
+      flags()->getStrokeCap() == PaintFlags::kDefault_Cap &&
+      flags()->getStrokeJoin() == PaintFlags::kDefault_Join;
+  if (can_substitute_hairline && stroke_vec.x() < 1.f && stroke_vec.y() < 1.f) {
+    // Use modulated hairline when possible, as it is faster and produces
+    // results closer to the original intent.
+    MutableFlags()->setStrokeWidth(0);
+    MutableFlags()->setAlpha(std::round(
+        flags()->getAlpha() * std::sqrt(stroke_vec.x() * stroke_vec.y())));
+    return;
+  }
+
+  // Fall back to anti-aliasing.
+  MutableFlags()->setAntiAlias(true);
+}
+
+}  // namespace cc
diff --git a/cc/paint/scoped_image_flags.h b/cc/paint/scoped_raster_flags.h
similarity index 61%
rename from cc/paint/scoped_image_flags.h
rename to cc/paint/scoped_raster_flags.h
index d6df03d..159b4d4 100644
--- a/cc/paint/scoped_image_flags.h
+++ b/cc/paint/scoped_raster_flags.h
@@ -2,33 +2,35 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CC_PAINT_SCOPED_IMAGE_FLAGS_H_
-#define CC_PAINT_SCOPED_IMAGE_FLAGS_H_
+#ifndef CC_PAINT_SCOPED_RASTER_FLAGS_H_
+#define CC_PAINT_SCOPED_RASTER_FLAGS_H_
 
+#include "base/containers/stack_container.h"
 #include "base/macros.h"
+#include "cc/paint/image_provider.h"
 #include "cc/paint/paint_export.h"
-#include "cc/paint/paint_op_buffer.h"
+#include "cc/paint/paint_flags.h"
 
 namespace cc {
-class ImageProvider;
 
 // A helper class to modify the flags for raster. This includes alpha folding
 // from SaveLayers and decoding images.
-class CC_PAINT_EXPORT ScopedImageFlags {
+class CC_PAINT_EXPORT ScopedRasterFlags {
  public:
-  // |image_provider| and |flags| must outlive this class.
-  ScopedImageFlags(ImageProvider* image_provider,
-                   const PaintFlags* flags,
-                   const SkMatrix& ctm,
-                   uint8_t alpha);
-  ~ScopedImageFlags();
+  // |flags| and |image_provider| must outlive this class.
+  ScopedRasterFlags(const PaintFlags* flags,
+                    ImageProvider* image_provider,
+                    const SkMatrix& ctm,
+                    uint8_t alpha);
+  ~ScopedRasterFlags();
 
   // The usage of these flags should not extend beyond the lifetime of this
   // object.
   const PaintFlags* flags() const {
     if (decode_failed_)
       return nullptr;
-    return &*modified_flags_;
+
+    return modified_flags_ ? &*modified_flags_ : original_flags_;
   }
 
  private:
@@ -52,17 +54,24 @@
     DISALLOW_COPY_AND_ASSIGN(DecodeStashingImageProvider);
   };
 
-  void DecodeImageShader(const PaintFlags* original, const SkMatrix& ctm);
-  void DecodeRecordShader(const PaintFlags* original, const SkMatrix& ctm);
-  void DecodeFailed();
+  void DecodeImageShader(const SkMatrix& ctm);
+  void DecodeRecordShader(const SkMatrix& ctm);
+  void AdjustStrokeIfNeeded(const SkMatrix& ctm);
 
-  bool decode_failed_ = false;
+  PaintFlags* MutableFlags() {
+    if (!modified_flags_)
+      modified_flags_.emplace(*original_flags_);
+    return &*modified_flags_;
+  }
+
+  const PaintFlags* original_flags_;
   base::Optional<PaintFlags> modified_flags_;
   base::Optional<DecodeStashingImageProvider> decode_stashing_image_provider_;
+  bool decode_failed_ = false;
 
-  DISALLOW_COPY_AND_ASSIGN(ScopedImageFlags);
+  DISALLOW_COPY_AND_ASSIGN(ScopedRasterFlags);
 };
 
 }  // namespace cc
 
-#endif  // CC_PAINT_SCOPED_IMAGE_FLAGS_H_
+#endif  // CC_PAINT_SCOPED_RASTER_FLAGS_H_
diff --git a/cc/paint/scoped_image_flags_unittest.cc b/cc/paint/scoped_raster_flags_unittest.cc
similarity index 60%
rename from cc/paint/scoped_image_flags_unittest.cc
rename to cc/paint/scoped_raster_flags_unittest.cc
index 7bdb8b8a..e3127f5 100644
--- a/cc/paint/scoped_image_flags_unittest.cc
+++ b/cc/paint/scoped_raster_flags_unittest.cc
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "cc/paint/scoped_image_flags.h"
+#include "cc/paint/scoped_raster_flags.h"
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "cc/paint/paint_op_buffer.h"
 #include "cc/test/skia_common.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -42,7 +43,7 @@
 };
 }  // namespace
 
-TEST(ScopedImageFlagsTest, KeepsDecodesAlive) {
+TEST(ScopedRasterFlagsTest, KeepsDecodesAlive) {
   auto record = sk_make_sp<PaintOpBuffer>();
   record->push<DrawImageOp>(CreateDiscardablePaintImage(gfx::Size(10, 10)), 0.f,
                             0.f, nullptr);
@@ -58,7 +59,7 @@
   PaintFlags flags;
   flags.setShader(record_shader);
   {
-    ScopedImageFlags scoped_flags(&provider, &flags, SkMatrix::I(), 255);
+    ScopedRasterFlags scoped_flags(&flags, &provider, SkMatrix::I(), 255);
     ASSERT_TRUE(scoped_flags.flags());
     EXPECT_NE(scoped_flags.flags(), &flags);
     SkPaint paint = scoped_flags.flags()->ToSkPaint();
@@ -68,16 +69,52 @@
   EXPECT_EQ(provider.ref_count(), 0);
 }
 
-TEST(ScopedImageFlagsTest, NoImageProvider) {
+TEST(ScopedRasterFlagsTest, NoImageProvider) {
   PaintFlags flags;
   flags.setAlpha(255);
   flags.setShader(PaintShader::MakeImage(
       CreateDiscardablePaintImage(gfx::Size(10, 10)),
       SkShader::TileMode::kClamp_TileMode, SkShader::TileMode::kClamp_TileMode,
       &SkMatrix::I()));
-  ScopedImageFlags scoped_flags(nullptr, &flags, SkMatrix::I(), 10);
+  ScopedRasterFlags scoped_flags(&flags, nullptr, SkMatrix::I(), 10);
   EXPECT_NE(scoped_flags.flags(), &flags);
   EXPECT_EQ(scoped_flags.flags()->getAlpha(), SkMulDiv255Round(255, 10));
 }
 
+TEST(ScopedRasterFlagsTest, ThinAliasedStroke) {
+  PaintFlags flags;
+  flags.setStyle(PaintFlags::kStroke_Style);
+  flags.setStrokeWidth(1);
+  flags.setAntiAlias(false);
+
+  struct {
+    SkMatrix ctm;
+    uint8_t alpha;
+
+    bool expect_same_flags;
+    bool expect_aa;
+    float expect_stroke_width;
+    uint8_t expect_alpha;
+  } tests[] = {
+      // No downscaling                    => no stroke change.
+      {SkMatrix::MakeScale(1.0f, 1.0f), 255, true, false, 1.0f, 0xFF},
+      // Symmetric downscaling             => modulated hairline stroke.
+      {SkMatrix::MakeScale(0.5f, 0.5f), 255, false, false, 0.0f, 0x80},
+      // Symmetric downscaling w/ alpha    => modulated hairline stroke.
+      {SkMatrix::MakeScale(0.5f, 0.5f), 127, false, false, 0.0f, 0x40},
+      // Anisotropic scaling              => AA stroke.
+      {SkMatrix::MakeScale(0.5f, 1.5f), 255, false, true, 1.0f, 0xFF},
+  };
+
+  for (const auto& test : tests) {
+    ScopedRasterFlags scoped_flags(&flags, nullptr, test.ctm, test.alpha);
+    ASSERT_TRUE(scoped_flags.flags());
+
+    EXPECT_EQ(scoped_flags.flags() == &flags, test.expect_same_flags);
+    EXPECT_EQ(scoped_flags.flags()->isAntiAlias(), test.expect_aa);
+    EXPECT_EQ(scoped_flags.flags()->getStrokeWidth(), test.expect_stroke_width);
+    EXPECT_EQ(scoped_flags.flags()->getAlpha(), test.expect_alpha);
+  }
+}
+
 }  // namespace cc
diff --git a/cc/paint/transfer_cache_entry.h b/cc/paint/transfer_cache_entry.h
index 44d0b32..0d14361 100644
--- a/cc/paint/transfer_cache_entry.h
+++ b/cc/paint/transfer_cache_entry.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/containers/span.h"
 #include "cc/paint/paint_export.h"
 
 class GrContext;
@@ -31,9 +32,19 @@
 class CC_PAINT_EXPORT ClientTransferCacheEntry {
  public:
   virtual ~ClientTransferCacheEntry() {}
+
+  // Returns the type of this entry.
   virtual TransferCacheEntryType Type() const = 0;
+
+  // Returns the serialized sized of this entry in bytes. This function will be
+  // used to determine how much memory is going to be allocated and passed to
+  // the Serialize() call.
   virtual size_t SerializedSize() const = 0;
-  virtual bool Serialize(size_t size, uint8_t* data) const = 0;
+
+  // Serializes the entry into the given span of memory. The size of the span is
+  // guaranteed to be at least SerializedSize() bytes. Returns true on success
+  // and false otherwise.
+  virtual bool Serialize(base::span<uint8_t> data) const = 0;
 };
 
 // An interface which receives the raw data sent by the client and
@@ -50,9 +61,18 @@
                                 TransferCacheEntryType* type);
 
   virtual ~ServiceTransferCacheEntry() {}
+
+  // Returns the type of this entry.
   virtual TransferCacheEntryType Type() const = 0;
-  virtual size_t Size() const = 0;
-  virtual bool Deserialize(GrContext* context, size_t size, uint8_t* data) = 0;
+
+  // Returns the cached size of this entry. This value is used for memory
+  // bookkeeping and to determine whether an unlocked cache entry will be
+  // evicted.
+  virtual size_t CachedSize() const = 0;
+
+  // Deserialize the cache entry from the given span of memory with the given
+  // context.
+  virtual bool Deserialize(GrContext* context, base::span<uint8_t> data) = 0;
 };
 
 };  // namespace cc
diff --git a/cc/paint/transfer_cache_unittest.cc b/cc/paint/transfer_cache_unittest.cc
index 25145930..1659ed9 100644
--- a/cc/paint/transfer_cache_unittest.cc
+++ b/cc/paint/transfer_cache_unittest.cc
@@ -248,7 +248,7 @@
         static_cast<uint32_t>(TransferCacheEntryType::kLast) + 1);
   }
   size_t SerializedSize() const override { return sizeof(uint32_t); }
-  bool Serialize(size_t size, uint8_t* data) const override { return true; }
+  bool Serialize(base::span<uint8_t> data) const override { return true; }
 };
 
 TEST_F(TransferCacheTest, InvalidTypeFails) {
diff --git a/cc/raster/staging_buffer_pool.cc b/cc/raster/staging_buffer_pool.cc
index 81b0e7e..bef94ed 100644
--- a/cc/raster/staging_buffer_pool.cc
+++ b/cc/raster/staging_buffer_pool.cc
@@ -145,30 +145,20 @@
   DCHECK(worker_context_provider_);
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
       this, "cc::StagingBufferPool", base::ThreadTaskRunnerHandle::Get());
+  base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
   reduce_memory_usage_callback_ = base::Bind(
       &StagingBufferPool::ReduceMemoryUsage, weak_ptr_factory_.GetWeakPtr());
-
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&StagingBufferPool::RegisterMemoryCoordinatorClient,
-                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 StagingBufferPool::~StagingBufferPool() {
+  base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
   base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
       this);
 }
 
-void StagingBufferPool::RegisterMemoryCoordinatorClient() {
-  // Register this component with base::MemoryCoordinatorClientRegistry.
-  base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
-}
-
 void StagingBufferPool::Shutdown() {
-  // Unregister this component with memory_coordinator::ClientRegistry.
-  base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
-
   base::AutoLock lock(lock_);
+
   if (buffers_.empty())
     return;
 
diff --git a/cc/raster/staging_buffer_pool.h b/cc/raster/staging_buffer_pool.h
index 158613f..299831c4 100644
--- a/cc/raster/staging_buffer_pool.h
+++ b/cc/raster/staging_buffer_pool.h
@@ -60,7 +60,6 @@
                     ResourceProvider* resource_provider,
                     bool use_partial_raster,
                     int max_staging_buffer_usage_in_bytes);
-  void RegisterMemoryCoordinatorClient();
   void Shutdown();
 
   // Overridden from base::trace_event::MemoryDumpProvider:
diff --git a/cc/raster/staging_buffer_pool_unittest.cc b/cc/raster/staging_buffer_pool_unittest.cc
new file mode 100644
index 0000000..8417d51
--- /dev/null
+++ b/cc/raster/staging_buffer_pool_unittest.cc
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/raster/staging_buffer_pool.h"
+
+#include "base/memory/memory_coordinator_client.h"
+#include "base/memory/memory_coordinator_client_registry.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "cc/test/test_context_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+
+TEST(StagingBufferPoolTest, ShutdownImmediatelyAfterCreation) {
+  auto context_provider = TestContextProvider::CreateWorker();
+  ResourceProvider* resource_provider = nullptr;
+  bool use_partial_raster = false;
+  int max_staging_buffer_usage_in_bytes = 1024;
+  auto task_runner = base::ThreadTaskRunnerHandle::Get();
+  // Create a StagingBufferPool and immediately shut it down.
+  auto pool = std::make_unique<StagingBufferPool>(
+      task_runner.get(), context_provider.get(), resource_provider,
+      use_partial_raster, max_staging_buffer_usage_in_bytes);
+  pool->Shutdown();
+  // Flush the message loop.
+  auto flush_message_loop = [] {
+    base::RunLoop runloop;
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  runloop.QuitClosure());
+    runloop.Run();
+  };
+
+  // Constructing the pool does a post-task to add itself as an observer. So
+  // allow for that registration to complete first.
+  flush_message_loop();
+
+  // Now, destroy the pool, and trigger a notification from the
+  // MemoryCoordinatorClientRegistry.
+  pool = nullptr;
+  base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory();
+  // Allow the callbacks in the observers to run.
+  flush_message_loop();
+  // No crash.
+}
+
+}  // namespace cc
diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc
index 45305961..2b7ad01 100644
--- a/cc/resources/scoped_resource_unittest.cc
+++ b/cc/resources/scoped_resource_unittest.cc
@@ -57,7 +57,8 @@
                                 texture->size(), texture->format()));
 
   EXPECT_LT(0u, texture->id());
-  EXPECT_EQ(static_cast<unsigned>(viz::RGBA_8888), texture->format());
+  EXPECT_EQ(static_cast<unsigned>(viz::RGBA_8888),
+            static_cast<unsigned>(texture->format()));
   EXPECT_EQ(gfx::Size(30, 30), texture->size());
 }
 
diff --git a/cc/scheduler/compositor_timing_history.cc b/cc/scheduler/compositor_timing_history.cc
index d6589f573..031e4a6 100644
--- a/cc/scheduler/compositor_timing_history.cc
+++ b/cc/scheduler/compositor_timing_history.cc
@@ -71,7 +71,8 @@
 const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0;
 const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0;
 const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0;
-const double kBeginMainFrameStartToCommitEstimationPercentile = 90.0;
+const double kBeginMainFrameStartToReadyToCommitEstimationPercentile = 90.0;
+const double kCommitEstimatePercentile = 90.0;
 const double kCommitToReadyToActivateEstimationPercentile = 90.0;
 const double kPrepareTilesEstimationPercentile = 90.0;
 const double kActivateEstimationPercentile = 90.0;
@@ -469,7 +470,9 @@
       begin_main_frame_queue_duration_critical_history_(kDurationHistorySize),
       begin_main_frame_queue_duration_not_critical_history_(
           kDurationHistorySize),
-      begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize),
+      begin_main_frame_start_to_ready_to_commit_duration_history_(
+          kDurationHistorySize),
+      commit_duration_history_(kDurationHistorySize),
       commit_to_ready_to_activate_duration_history_(kDurationHistorySize),
       prepare_tiles_duration_history_(kDurationHistorySize),
       activate_duration_history_(kDurationHistorySize),
@@ -507,8 +510,8 @@
       "begin_main_frame_queue_not_critical_estimate_ms",
       BeginMainFrameQueueDurationNotCriticalEstimate().InMillisecondsF());
   state->SetDouble(
-      "begin_main_frame_start_to_commit_estimate_ms",
-      BeginMainFrameStartToCommitDurationEstimate().InMillisecondsF());
+      "begin_main_frame_start_to_ready_to_commit_estimate_ms",
+      BeginMainFrameStartToReadyToCommitDurationEstimate().InMillisecondsF());
   state->SetDouble("commit_to_ready_to_activate_estimate_ms",
                    CommitToReadyToActivateDurationEstimate().InMillisecondsF());
   state->SetDouble("prepare_tiles_estimate_ms",
@@ -576,9 +579,14 @@
 }
 
 base::TimeDelta
-CompositorTimingHistory::BeginMainFrameStartToCommitDurationEstimate() const {
-  return begin_main_frame_start_to_commit_duration_history_.Percentile(
-      kBeginMainFrameStartToCommitEstimationPercentile);
+CompositorTimingHistory::BeginMainFrameStartToReadyToCommitDurationEstimate()
+    const {
+  return begin_main_frame_start_to_ready_to_commit_duration_history_.Percentile(
+      kBeginMainFrameStartToReadyToCommitEstimationPercentile);
+}
+
+base::TimeDelta CompositorTimingHistory::CommitDurationEstimate() const {
+  return commit_duration_history_.Percentile(kCommitEstimatePercentile);
 }
 
 base::TimeDelta
@@ -677,13 +685,27 @@
   begin_main_frame_frame_time_ = base::TimeTicks();
 }
 
+void CompositorTimingHistory::NotifyReadyToCommit() {
+  DCHECK_NE(begin_main_frame_start_time_, base::TimeTicks());
+  begin_main_frame_start_to_ready_to_commit_duration_history_.InsertSample(
+      Now() - begin_main_frame_start_time_);
+}
+
+void CompositorTimingHistory::WillCommit() {
+  DCHECK_NE(begin_main_frame_start_time_, base::TimeTicks());
+  commit_start_time_ = Now();
+}
+
 void CompositorTimingHistory::DidCommit() {
   DCHECK_EQ(base::TimeTicks(), pending_tree_main_frame_time_);
   DCHECK_EQ(pending_tree_creation_time_, base::TimeTicks());
+  DCHECK_NE(commit_start_time_, base::TimeTicks());
 
   SetBeginMainFrameCommittingContinuously(true);
   base::TimeTicks begin_main_frame_end_time = Now();
   DidBeginMainFrame(begin_main_frame_end_time);
+  commit_duration_history_.InsertSample(begin_main_frame_end_time -
+                                        commit_start_time_);
 
   pending_tree_is_impl_side_ = false;
   pending_tree_creation_time_ = begin_main_frame_end_time;
@@ -736,8 +758,6 @@
       begin_main_frame_queue_duration_not_critical_history_.InsertSample(
           begin_main_frame_queue_duration);
     }
-    begin_main_frame_start_to_commit_duration_history_.InsertSample(
-        begin_main_frame_start_to_commit_duration);
   }
 
   if (begin_main_frame_needed_continuously_) {
diff --git a/cc/scheduler/compositor_timing_history.h b/cc/scheduler/compositor_timing_history.h
index cf5629e..43e48c7 100644
--- a/cc/scheduler/compositor_timing_history.h
+++ b/cc/scheduler/compositor_timing_history.h
@@ -45,7 +45,9 @@
   virtual base::TimeDelta BeginMainFrameQueueDurationCriticalEstimate() const;
   virtual base::TimeDelta BeginMainFrameQueueDurationNotCriticalEstimate()
       const;
-  virtual base::TimeDelta BeginMainFrameStartToCommitDurationEstimate() const;
+  virtual base::TimeDelta BeginMainFrameStartToReadyToCommitDurationEstimate()
+      const;
+  virtual base::TimeDelta CommitDurationEstimate() const;
   virtual base::TimeDelta CommitToReadyToActivateDurationEstimate() const;
   virtual base::TimeDelta PrepareTilesDurationEstimate() const;
   virtual base::TimeDelta ActivateDurationEstimate() const;
@@ -66,6 +68,8 @@
                           base::TimeTicks main_frame_time);
   void BeginMainFrameStarted(base::TimeTicks main_thread_start_time);
   void BeginMainFrameAborted();
+  void NotifyReadyToCommit();
+  void WillCommit();
   void DidCommit();
   void WillPrepareTiles();
   void DidPrepareTiles();
@@ -110,7 +114,9 @@
   RollingTimeDeltaHistory begin_main_frame_queue_duration_history_;
   RollingTimeDeltaHistory begin_main_frame_queue_duration_critical_history_;
   RollingTimeDeltaHistory begin_main_frame_queue_duration_not_critical_history_;
-  RollingTimeDeltaHistory begin_main_frame_start_to_commit_duration_history_;
+  RollingTimeDeltaHistory
+      begin_main_frame_start_to_ready_to_commit_duration_history_;
+  RollingTimeDeltaHistory commit_duration_history_;
   RollingTimeDeltaHistory commit_to_ready_to_activate_duration_history_;
   RollingTimeDeltaHistory prepare_tiles_duration_history_;
   RollingTimeDeltaHistory activate_duration_history_;
@@ -120,6 +126,7 @@
   base::TimeTicks begin_main_frame_frame_time_;
   base::TimeTicks begin_main_frame_sent_time_;
   base::TimeTicks begin_main_frame_start_time_;
+  base::TimeTicks commit_start_time_;
   base::TimeTicks pending_tree_main_frame_time_;
   base::TimeTicks pending_tree_creation_time_;
   base::TimeTicks pending_tree_ready_to_activate_time_;
diff --git a/cc/scheduler/compositor_timing_history_unittest.cc b/cc/scheduler/compositor_timing_history_unittest.cc
index 5ba2b06..d8c4a75 100644
--- a/cc/scheduler/compositor_timing_history_unittest.cc
+++ b/cc/scheduler/compositor_timing_history_unittest.cc
@@ -49,6 +49,7 @@
                      int main_thread_compositable_animations_count) {
     timing_history_.WillBeginMainFrame(true, Now());
     timing_history_.BeginMainFrameStarted(Now());
+    timing_history_.WillCommit();
     timing_history_.DidCommit();
     timing_history_.ReadyToActivate();
     timing_history_.WillActivate();
@@ -93,20 +94,24 @@
   // as expected.
   base::TimeDelta begin_main_frame_queue_duration =
       base::TimeDelta::FromMilliseconds(1);
-  base::TimeDelta begin_main_frame_start_to_commit_duration =
+  base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
       base::TimeDelta::FromMilliseconds(1);
   base::TimeDelta prepare_tiles_duration = base::TimeDelta::FromMilliseconds(2);
   base::TimeDelta prepare_tiles_end_to_ready_to_activate_duration =
       base::TimeDelta::FromMilliseconds(1);
   base::TimeDelta commit_to_ready_to_activate_duration =
       base::TimeDelta::FromMilliseconds(3);
+  base::TimeDelta commit_duration = base::TimeDelta::FromMilliseconds(1);
   base::TimeDelta activate_duration = base::TimeDelta::FromMilliseconds(4);
   base::TimeDelta draw_duration = base::TimeDelta::FromMilliseconds(5);
 
   timing_history_.WillBeginMainFrame(true, Now());
   AdvanceNowBy(begin_main_frame_queue_duration);
   timing_history_.BeginMainFrameStarted(Now());
-  AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+  AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
+  timing_history_.NotifyReadyToCommit();
+  timing_history_.WillCommit();
+  AdvanceNowBy(commit_duration);
   timing_history_.DidCommit();
   timing_history_.WillPrepareTiles();
   AdvanceNowBy(prepare_tiles_duration);
@@ -129,9 +134,10 @@
   EXPECT_EQ(begin_main_frame_queue_duration,
             timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
 
-  EXPECT_EQ(begin_main_frame_start_to_commit_duration,
-            timing_history_.BeginMainFrameStartToCommitDurationEstimate());
-
+  EXPECT_EQ(
+      begin_main_frame_start_to_ready_to_commit_duration,
+      timing_history_.BeginMainFrameStartToReadyToCommitDurationEstimate());
+  EXPECT_EQ(commit_duration, timing_history_.CommitDurationEstimate());
   EXPECT_EQ(commit_to_ready_to_activate_duration,
             timing_history_.CommitToReadyToActivateDurationEstimate());
   EXPECT_EQ(prepare_tiles_duration,
@@ -145,7 +151,7 @@
 
   base::TimeDelta begin_main_frame_queue_duration =
       base::TimeDelta::FromMilliseconds(1);
-  base::TimeDelta begin_main_frame_start_to_commit_duration =
+  base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
       base::TimeDelta::FromMilliseconds(1);
   base::TimeDelta prepare_tiles_duration = base::TimeDelta::FromMilliseconds(2);
   base::TimeDelta prepare_tiles_end_to_ready_to_activate_duration =
@@ -156,7 +162,7 @@
   timing_history_.WillBeginMainFrame(false, Now());
   AdvanceNowBy(begin_main_frame_queue_duration);
   timing_history_.BeginMainFrameStarted(Now());
-  AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+  AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
   // BeginMainFrameAborted counts as a commit complete.
   timing_history_.BeginMainFrameAborted();
   timing_history_.WillPrepareTiles();
@@ -179,9 +185,6 @@
   EXPECT_EQ(begin_main_frame_queue_duration,
             timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
 
-  EXPECT_EQ(begin_main_frame_start_to_commit_duration,
-            timing_history_.BeginMainFrameStartToCommitDurationEstimate());
-
   EXPECT_EQ(prepare_tiles_duration,
             timing_history_.PrepareTilesDurationEstimate());
   EXPECT_EQ(activate_duration, timing_history_.ActivateDurationEstimate());
@@ -194,19 +197,19 @@
       base::TimeDelta::FromMilliseconds(1);
   base::TimeDelta begin_main_frame_queue_duration_not_critical =
       base::TimeDelta::FromMilliseconds(2);
-  base::TimeDelta begin_main_frame_start_to_commit_duration =
+  base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
       base::TimeDelta::FromMilliseconds(1);
 
   timing_history_.WillBeginMainFrame(true, Now());
   AdvanceNowBy(begin_main_frame_queue_duration_critical);
   timing_history_.BeginMainFrameStarted(Now());
-  AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+  AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
   timing_history_.BeginMainFrameAborted();
 
   timing_history_.WillBeginMainFrame(false, Now());
   AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
   timing_history_.BeginMainFrameStarted(Now());
-  AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+  AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
   timing_history_.BeginMainFrameAborted();
 
   // Since the critical BeginMainFrames are faster than non critical ones,
@@ -215,8 +218,6 @@
             timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
   EXPECT_EQ(begin_main_frame_queue_duration_not_critical,
             timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-  EXPECT_EQ(begin_main_frame_start_to_commit_duration,
-            timing_history_.BeginMainFrameStartToCommitDurationEstimate());
 }
 
 TEST_F(CompositorTimingHistoryTest, BeginMainFrames_OldCriticalSlower) {
@@ -227,14 +228,14 @@
       base::TimeDelta::FromMilliseconds(2);
   base::TimeDelta begin_main_frame_queue_duration_not_critical =
       base::TimeDelta::FromMilliseconds(1);
-  base::TimeDelta begin_main_frame_start_to_commit_duration =
+  base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
       base::TimeDelta::FromMilliseconds(1);
 
   // A single critical frame that is slow.
   timing_history_.WillBeginMainFrame(true, Now());
   AdvanceNowBy(begin_main_frame_queue_duration_critical);
   timing_history_.BeginMainFrameStarted(Now());
-  AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+  AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
   // BeginMainFrameAborted counts as a commit complete.
   timing_history_.BeginMainFrameAborted();
 
@@ -243,7 +244,7 @@
     timing_history_.WillBeginMainFrame(false, Now());
     AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
     timing_history_.BeginMainFrameStarted(Now());
-    AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+    AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
     // BeginMainFrameAborted counts as a commit complete.
     timing_history_.BeginMainFrameAborted();
   }
@@ -254,9 +255,6 @@
             timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
   EXPECT_EQ(begin_main_frame_queue_duration_not_critical,
             timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-
-  EXPECT_EQ(begin_main_frame_start_to_commit_duration,
-            timing_history_.BeginMainFrameStartToCommitDurationEstimate());
 }
 
 TEST_F(CompositorTimingHistoryTest, BeginMainFrames_NewCriticalSlower) {
@@ -267,14 +265,14 @@
       base::TimeDelta::FromMilliseconds(2);
   base::TimeDelta begin_main_frame_queue_duration_not_critical =
       base::TimeDelta::FromMilliseconds(1);
-  base::TimeDelta begin_main_frame_start_to_commit_duration =
+  base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
       base::TimeDelta::FromMilliseconds(1);
 
   // A single non critical frame that is fast.
   timing_history_.WillBeginMainFrame(false, Now());
   AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
   timing_history_.BeginMainFrameStarted(Now());
-  AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+  AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
   timing_history_.BeginMainFrameAborted();
 
   // A bunch of slower critical frames that are newer.
@@ -282,7 +280,7 @@
     timing_history_.WillBeginMainFrame(true, Now());
     AdvanceNowBy(begin_main_frame_queue_duration_critical);
     timing_history_.BeginMainFrameStarted(Now());
-    AdvanceNowBy(begin_main_frame_start_to_commit_duration);
+    AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
     timing_history_.BeginMainFrameAborted();
   }
 
@@ -292,9 +290,6 @@
             timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
   EXPECT_EQ(begin_main_frame_queue_duration_critical,
             timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-
-  EXPECT_EQ(begin_main_frame_start_to_commit_duration,
-            timing_history_.BeginMainFrameStartToCommitDurationEstimate());
 }
 
 void TestAnimationUMA(
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index cd901be4..99d46b9 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -156,6 +156,7 @@
 
 void Scheduler::NotifyReadyToCommit() {
   TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit");
+  compositor_timing_history_->NotifyReadyToCommit();
   state_machine_.NotifyReadyToCommit();
   ProcessScheduledActions();
 }
@@ -383,7 +384,8 @@
 
   base::TimeDelta bmf_start_to_activate =
       compositor_timing_history_
-          ->BeginMainFrameStartToCommitDurationEstimate() +
+          ->BeginMainFrameStartToReadyToCommitDurationEstimate() +
+      compositor_timing_history_->CommitDurationEstimate() +
       compositor_timing_history_->CommitToReadyToActivateDurationEstimate() +
       compositor_timing_history_->ActivateDurationEstimate();
 
@@ -670,6 +672,7 @@
       case SchedulerStateMachine::Action::COMMIT: {
         bool commit_has_no_updates = false;
         state_machine_.WillCommit(commit_has_no_updates);
+        compositor_timing_history_->WillCommit();
         client_->ScheduledActionCommit();
         break;
       }
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
index 4e2f664..a43eec08 100644
--- a/cc/scheduler/scheduler_state_machine.h
+++ b/cc/scheduler/scheduler_state_machine.h
@@ -293,6 +293,9 @@
   bool previous_pending_tree_was_impl_side() const {
     return previous_pending_tree_was_impl_side_;
   }
+  bool critical_begin_main_frame_to_activate_is_fast() const {
+    return critical_begin_main_frame_to_activate_is_fast_;
+  }
 
  protected:
   bool BeginFrameRequiredForAction() const;
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index a30bc284..6a8181a7 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -357,7 +357,8 @@
       SCOPED_TRACE("Do first frame to commit after initialize.");
       AdvanceFrame();
 
-      scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+      now_src_->Advance(base::TimeDelta::FromMilliseconds(1));
+      scheduler_->NotifyBeginMainFrameStarted(now_src_->NowTicks());
       scheduler_->NotifyReadyToCommit();
       scheduler_->NotifyReadyToActivate();
       scheduler_->NotifyReadyToDraw();
@@ -545,7 +546,7 @@
   client_->Reset();
 
   // NotifyReadyToCommit should trigger the commit.
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(scheduler_->begin_frames_expected());
@@ -660,7 +661,7 @@
   client_->Reset();
 
   // Finish the first commit.
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
@@ -689,7 +690,7 @@
 
   // Finishing the commit before the deadline should post a new deadline task
   // to trigger the deadline early.
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
@@ -867,7 +868,7 @@
   EXPECT_EQ(1, client->num_draws());
   EXPECT_TRUE(scheduler_->CommitPending());
   EXPECT_TRUE(client->needs_begin_frames());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
 
@@ -1259,7 +1260,7 @@
 
   // Begin new frame.
   EXPECT_SCOPED(AdvanceFrame());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
@@ -1297,7 +1298,7 @@
 
   // Begin new frame.
   EXPECT_SCOPED(AdvanceFrame());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
@@ -1332,7 +1333,7 @@
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
@@ -1442,7 +1443,7 @@
   SetUpScheduler(EXTERNAL_BFS);
   fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
   fake_compositor_timing_history_
-      ->SetBeginMainFrameStartToCommitDurationEstimate(kSlowDuration);
+      ->SetBeginMainFrameStartToReadyToCommitDurationEstimate(kSlowDuration);
 
   bool expect_send_begin_main_frame = true;
   EXPECT_SCOPED(
@@ -1499,7 +1500,7 @@
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
 
   // After aborting the frame, make sure we don't skip the
@@ -1534,7 +1535,7 @@
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
 
   // Make us abort the upcoming draw.
@@ -1579,7 +1580,7 @@
                  "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
@@ -1624,7 +1625,7 @@
     EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
     client_->Reset();
-    scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+    scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
     scheduler_->NotifyReadyToCommit();
     scheduler_->NotifyReadyToActivate();
     task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -1753,7 +1754,7 @@
                  "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
@@ -1777,7 +1778,7 @@
 
     client_->Reset();
     scheduler_->DidReceiveCompositorFrameAck();
-    scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+    scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
     scheduler_->NotifyReadyToCommit();
     scheduler_->NotifyReadyToActivate();
     task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -1804,7 +1805,7 @@
   SetUpScheduler(EXTERNAL_BFS);
   fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
   fake_compositor_timing_history_
-      ->SetBeginMainFrameStartToCommitDurationEstimate(kSlowDuration);
+      ->SetBeginMainFrameStartToReadyToCommitDurationEstimate(kSlowDuration);
   EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck());
 }
 
@@ -1851,7 +1852,7 @@
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
@@ -1867,7 +1868,7 @@
   EXPECT_SCOPED(AdvanceFrame());
   EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
 
@@ -1932,7 +1933,7 @@
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
   SendNextBeginFrame();
   EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -1969,7 +1970,7 @@
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   EXPECT_FALSE(scheduler_->CommitPending());
@@ -1983,7 +1984,7 @@
   EXPECT_FALSE(scheduler_->CommitPending());
   scheduler_->SetNeedsBeginMainFrame();
   EXPECT_SCOPED(AdvanceFrame());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
@@ -2031,7 +2032,7 @@
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   scheduler_->DidReceiveCompositorFrameAck();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_FALSE(scheduler_->CommitPending());
   EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
@@ -2049,7 +2050,7 @@
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   scheduler_->DidReceiveCompositorFrameAck();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
                  "ScheduledActionDrawIfPossible");
 
@@ -2087,7 +2088,7 @@
   client_->Reset();
 
   // NotifyReadyToCommit should trigger the commit.
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
@@ -2141,7 +2142,7 @@
   client_->Reset();
 
   // NotifyReadyToCommit should trigger the pending commit.
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
@@ -2247,7 +2248,7 @@
   EXPECT_NO_ACTION();
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
 
@@ -2293,7 +2294,7 @@
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
                  "ScheduledActionBeginLayerTreeFrameSinkCreation");
@@ -2312,7 +2313,7 @@
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
 
@@ -2368,7 +2369,7 @@
 
   // NotifyReadyToCommit should trigger the commit.
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(scheduler_->begin_frames_expected());
@@ -2404,7 +2405,7 @@
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
 
@@ -2436,7 +2437,7 @@
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
@@ -2462,7 +2463,7 @@
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
 
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_TRUE(client_->IsInsideBeginImplFrame());
@@ -2643,7 +2644,7 @@
 
   // Begin new frame.
   EXPECT_SCOPED(AdvanceFrame());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
 
   client_->Reset();
@@ -2710,7 +2711,7 @@
 
   // Trigger a frame draw.
   EXPECT_SCOPED(AdvanceFrame());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   task_runner().RunPendingTasks();
@@ -2746,7 +2747,7 @@
 
   // Trigger a frame draw.
   EXPECT_SCOPED(AdvanceFrame());
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   task_runner().RunPendingTasks();
@@ -2898,7 +2899,7 @@
       client_->last_begin_frame_ack());
   client_->Reset();
 
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_NO_ACTION();
 
   // Next vsync.
@@ -2970,7 +2971,7 @@
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_NO_ACTION();
 
   scheduler_->NotifyReadyToCommit();
@@ -2990,7 +2991,7 @@
   EXPECT_FALSE(client_->IsInsideBeginImplFrame());
   client_->Reset();
 
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   EXPECT_NO_ACTION();
 
   // Allow new commit even though previous commit hasn't been drawn.
@@ -3082,7 +3083,7 @@
   EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
   client_->Reset();
 
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   client_->Reset();
@@ -3137,7 +3138,7 @@
 
   EXPECT_EQ(initial_interval, scheduler_->BeginImplFrameInterval());
 
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
+  scheduler_->NotifyBeginMainFrameStarted(now_src_->NowTicks());
   scheduler_->NotifyReadyToCommit();
   scheduler_->NotifyReadyToActivate();
   task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -3213,7 +3214,7 @@
 
   // Abort the commit.
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks::Now());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->BeginMainFrameAborted(
       CommitEarlyOutReason::ABORTED_LAYER_TREE_FRAME_SINK_LOST);
   EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
@@ -3247,7 +3248,7 @@
   // actions since the impl-side invalidation request will be merged with the
   // commit.
   client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks::Now());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->NotifyReadyToCommit();
   EXPECT_ACTIONS("ScheduledActionCommit");
   EXPECT_FALSE(scheduler_->needs_impl_side_invalidation());
@@ -3273,7 +3274,7 @@
   // should not be blocked on the main frame.
   client_->Reset();
   scheduler_->SetNeedsBeginMainFrame();
-  scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks::Now());
+  scheduler_->NotifyBeginMainFrameStarted(now_src()->NowTicks());
   scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
   task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
   EXPECT_ACTIONS("ScheduledActionPerformImplSideInvalidation");
@@ -3703,5 +3704,24 @@
   EXPECT_FALSE(scheduler_->BeginFrameNeeded());
 }
 
+TEST_F(SchedulerTest, CriticalBeginMainFrameIsFast_CommitEstimateSlow) {
+  SetUpScheduler(EXTERNAL_BFS);
+  scheduler_->SetNeedsBeginMainFrame();
+  fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
+  fake_compositor_timing_history_->SetCommitDurationEstimate(kSlowDuration);
+  EXPECT_SCOPED(AdvanceFrame());
+  EXPECT_FALSE(scheduler_->state_machine()
+                   .critical_begin_main_frame_to_activate_is_fast());
+}
+
+TEST_F(SchedulerTest, CriticalBeginMainFrameIsFast_CommitEstimateFast) {
+  SetUpScheduler(EXTERNAL_BFS);
+  scheduler_->SetNeedsBeginMainFrame();
+  fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
+  EXPECT_SCOPED(AdvanceFrame());
+  EXPECT_TRUE(scheduler_->state_machine()
+                  .critical_begin_main_frame_to_activate_is_fast());
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 554fed9b..1556e94 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -38,6 +38,11 @@
   void NeedsImplSideInvalidation(bool needs_first_draw_on_activation) override;
   void RequestBeginMainFrameNotExpected(bool new_state) override {}
   void NotifyImageDecodeRequestFinished() override {}
+  void DidPresentCompositorFrameOnImplThread(
+      const std::vector<int>& source_frames,
+      base::TimeTicks time,
+      base::TimeDelta refresh,
+      uint32_t flags) override {}
 
   void reset_did_request_impl_side_invalidation() {
     did_request_impl_side_invalidation_ = false;
diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h
index dcc450fc..2ce1f1a 100644
--- a/cc/test/fake_output_surface_client.h
+++ b/cc/test/fake_output_surface_client.h
@@ -17,6 +17,8 @@
   void DidReceiveSwapBuffersAck(uint64_t swap_id) override;
   void DidReceiveTextureInUseResponses(
       const gpu::TextureInUseResponses& responses) override {}
+  void DidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) override {}
 
   int swap_count() { return swap_count_; }
 
diff --git a/cc/test/scheduler_test_common.cc b/cc/test/scheduler_test_common.cc
index 8052f46b..ed87fc29 100644
--- a/cc/test/scheduler_test_common.cc
+++ b/cc/test/scheduler_test_common.cc
@@ -39,7 +39,8 @@
 void FakeCompositorTimingHistory::SetAllEstimatesTo(base::TimeDelta duration) {
   begin_main_frame_queue_duration_critical_ = duration;
   begin_main_frame_queue_duration_not_critical_ = duration;
-  begin_main_frame_start_to_commit_duration_ = duration;
+  begin_main_frame_start_to_ready_to_commit_duration_ = duration;
+  commit_duration_ = duration;
   commit_to_ready_to_activate_duration_ = duration;
   prepare_tiles_duration_ = duration;
   activate_duration_ = duration;
@@ -58,8 +59,14 @@
 }
 
 void FakeCompositorTimingHistory::
-    SetBeginMainFrameStartToCommitDurationEstimate(base::TimeDelta duration) {
-  begin_main_frame_start_to_commit_duration_ = duration;
+    SetBeginMainFrameStartToReadyToCommitDurationEstimate(
+        base::TimeDelta duration) {
+  begin_main_frame_start_to_ready_to_commit_duration_ = duration;
+}
+
+void FakeCompositorTimingHistory::SetCommitDurationEstimate(
+    base::TimeDelta duration) {
+  commit_duration_ = duration;
 }
 
 void FakeCompositorTimingHistory::SetCommitToReadyToActivateDurationEstimate(
@@ -94,10 +101,13 @@
   return begin_main_frame_queue_duration_not_critical_;
 }
 
-base::TimeDelta
-FakeCompositorTimingHistory::BeginMainFrameStartToCommitDurationEstimate()
-    const {
-  return begin_main_frame_start_to_commit_duration_;
+base::TimeDelta FakeCompositorTimingHistory::
+    BeginMainFrameStartToReadyToCommitDurationEstimate() const {
+  return begin_main_frame_start_to_ready_to_commit_duration_;
+}
+
+base::TimeDelta FakeCompositorTimingHistory::CommitDurationEstimate() const {
+  return commit_duration_;
 }
 
 base::TimeDelta
diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h
index f4f8260c..025d228 100644
--- a/cc/test/scheduler_test_common.h
+++ b/cc/test/scheduler_test_common.h
@@ -33,8 +33,10 @@
   void SetBeginMainFrameQueueDurationCriticalEstimate(base::TimeDelta duration);
   void SetBeginMainFrameQueueDurationNotCriticalEstimate(
       base::TimeDelta duration);
-  void SetBeginMainFrameStartToCommitDurationEstimate(base::TimeDelta duration);
+  void SetBeginMainFrameStartToReadyToCommitDurationEstimate(
+      base::TimeDelta duration);
   void SetCommitToReadyToActivateDurationEstimate(base::TimeDelta duration);
+  void SetCommitDurationEstimate(base::TimeDelta duration);
   void SetPrepareTilesDurationEstimate(base::TimeDelta duration);
   void SetActivateDurationEstimate(base::TimeDelta duration);
   void SetDrawDurationEstimate(base::TimeDelta duration);
@@ -42,7 +44,9 @@
   base::TimeDelta BeginMainFrameQueueDurationCriticalEstimate() const override;
   base::TimeDelta BeginMainFrameQueueDurationNotCriticalEstimate()
       const override;
-  base::TimeDelta BeginMainFrameStartToCommitDurationEstimate() const override;
+  base::TimeDelta BeginMainFrameStartToReadyToCommitDurationEstimate()
+      const override;
+  base::TimeDelta CommitDurationEstimate() const override;
   base::TimeDelta CommitToReadyToActivateDurationEstimate() const override;
   base::TimeDelta PrepareTilesDurationEstimate() const override;
   base::TimeDelta ActivateDurationEstimate() const override;
@@ -58,7 +62,8 @@
 
   base::TimeDelta begin_main_frame_queue_duration_critical_;
   base::TimeDelta begin_main_frame_queue_duration_not_critical_;
-  base::TimeDelta begin_main_frame_start_to_commit_duration_;
+  base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration_;
+  base::TimeDelta commit_duration_;
   base::TimeDelta commit_to_ready_to_activate_duration_;
   base::TimeDelta prepare_tiles_duration_;
   base::TimeDelta activate_duration_;
@@ -122,6 +127,8 @@
     return state_machine_.ImplLatencyTakesPriority();
   }
 
+  const SchedulerStateMachine& state_machine() const { return state_machine_; }
+
  protected:
   // Overridden from Scheduler.
   base::TimeTicks Now() const override;
diff --git a/cc/tiles/tile_manager_perftest.cc b/cc/tiles/tile_manager_perftest.cc
index 952e0a90..421848a 100644
--- a/cc/tiles/tile_manager_perftest.cc
+++ b/cc/tiles/tile_manager_perftest.cc
@@ -295,7 +295,8 @@
   LapTimer timer_;
 };
 
-TEST_F(TileManagerPerfTest, PrepareTiles) {
+// Failing.  https://crbug.com/792995
+TEST_F(TileManagerPerfTest, DISABLED_PrepareTiles) {
   RunPrepareTilesTest("2_100", 2, 100);
   RunPrepareTilesTest("2_500", 2, 500);
   RunPrepareTilesTest("2_1000", 2, 1000);
diff --git a/cc/trees/layer_tree_frame_sink_client.h b/cc/trees/layer_tree_frame_sink_client.h
index 154d536..e2ca7ba 100644
--- a/cc/trees/layer_tree_frame_sink_client.h
+++ b/cc/trees/layer_tree_frame_sink_client.h
@@ -49,6 +49,8 @@
   // so that frames are submitted only at the rate it can handle them.
   virtual void DidReceiveCompositorFrameAck() = 0;
 
+  // See ui/gfx/presentation_feedback.h for details on args. |time| is always
+  // non-zero.
   virtual void DidPresentCompositorFrame(uint32_t presentation_token,
                                          base::TimeTicks time,
                                          base::TimeDelta refresh,
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 08268c6..ab290a0 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -319,6 +319,21 @@
 
   sync_tree->set_source_frame_number(SourceFrameNumber());
 
+  // Set presentation token if any pending .
+  bool request_presentation_time = false;
+  if (!pending_presentation_time_callbacks_.empty()) {
+    request_presentation_time = true;
+    frame_to_presentation_time_callbacks_[SourceFrameNumber()] =
+        std::move(pending_presentation_time_callbacks_);
+    pending_presentation_time_callbacks_.clear();
+  } else if (!frame_to_presentation_time_callbacks_.empty()) {
+    // There are pending callbacks. Keep requesting the presentation callback
+    // in case a previous frame was dropped (the callbacks run when the frame
+    // makes it to screen).
+    request_presentation_time = true;
+  }
+  sync_tree->set_request_presentation_time(request_presentation_time);
+
   if (needs_full_tree_sync_)
     TreeSynchronizer::SynchronizeTrees(root_layer(), sync_tree);
 
@@ -669,6 +684,22 @@
   return result;
 }
 
+void LayerTreeHost::DidPresentCompositorFrame(
+    const std::vector<int>& source_frames,
+    base::TimeTicks time,
+    base::TimeDelta refresh,
+    uint32_t flags) {
+  for (int frame : source_frames) {
+    if (!frame_to_presentation_time_callbacks_.count(frame))
+      continue;
+
+    for (auto& callback : frame_to_presentation_time_callbacks_[frame])
+      std::move(callback).Run(time, refresh, flags);
+
+    frame_to_presentation_time_callbacks_.erase(frame);
+  }
+}
+
 void LayerTreeHost::DidCompletePageScaleAnimation() {
   did_complete_scale_animation_ = true;
 }
@@ -931,6 +962,11 @@
   return compositor_mode_ == CompositorMode::THREADED;
 }
 
+void LayerTreeHost::RequestPresentationTimeForNextFrame(
+    PresentationTimeCallback callback) {
+  pending_presentation_time_callbacks_.push_back(std::move(callback));
+}
+
 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
   if (root_layer_.get() == root_layer.get())
     return;
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 138ec2b..8442325cc 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -15,6 +15,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include "base/callback_forward.h"
 #include "base/cancelable_callback.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
@@ -243,6 +244,13 @@
   // Calling this will reset it back to not suitable state.
   void ResetGpuRasterizationTracking();
 
+  // Registers a callback that is run when the next frame successfully makes it
+  // to the screen (it's entirely possible some frames may be dropped between
+  // the time this is called and the callback is run).
+  using PresentationTimeCallback =
+      base::OnceCallback<void(base::TimeTicks, base::TimeDelta, uint32_t)>;
+  void RequestPresentationTimeForNextFrame(PresentationTimeCallback callback);
+
   void SetRootLayer(scoped_refptr<Layer> root_layer);
   Layer* root_layer() { return root_layer_.get(); }
   const Layer* root_layer() const { return root_layer_.get(); }
@@ -435,6 +443,10 @@
     client_->DidReceiveCompositorFrameAck();
   }
   bool UpdateLayers();
+  void DidPresentCompositorFrame(const std::vector<int>& source_frames,
+                                 base::TimeTicks time,
+                                 base::TimeDelta refresh,
+                                 uint32_t flags);
   // Called when the compositor completed page scale animation.
   void DidCompletePageScaleAnimation();
   void ApplyScrollAndScale(ScrollAndScaleSet* info);
@@ -675,6 +687,15 @@
   std::unordered_map<int, base::OnceCallback<void(bool)>>
       pending_image_decodes_;
 
+  // Presentation time callbacks requested for the next frame are initially
+  // added here.
+  std::vector<PresentationTimeCallback> pending_presentation_time_callbacks_;
+
+  // Maps from the source frame presentation callbacks are requested for to
+  // the callbacks.
+  std::map<int, std::vector<PresentationTimeCallback>>
+      frame_to_presentation_time_callbacks_;
+
   DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
 };
 
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index d978be7..f068835b 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1632,7 +1632,25 @@
 void LayerTreeHostImpl::DidPresentCompositorFrame(uint32_t presentation_token,
                                                   base::TimeTicks time,
                                                   base::TimeDelta refresh,
-                                                  uint32_t flags) {}
+                                                  uint32_t flags) {
+  std::vector<int> source_frames;
+  auto iter = presentation_token_to_frame_.begin();
+  for (; iter != presentation_token_to_frame_.end() &&
+         iter->first <= presentation_token;
+       ++iter) {
+    source_frames.push_back(iter->second);
+  }
+  presentation_token_to_frame_.erase(presentation_token_to_frame_.begin(),
+                                     iter);
+  if (presentation_token_to_frame_.empty()) {
+    DCHECK_EQ(last_presentation_token_, presentation_token);
+    last_presentation_token_ = 0u;
+  }
+
+  client_->DidPresentCompositorFrameOnImplThread(source_frames, time, refresh,
+                                                 flags);
+}
+
 void LayerTreeHostImpl::DidDiscardCompositorFrame(uint32_t presentation_token) {
 }
 
@@ -1714,9 +1732,18 @@
   client_->OnCanDrawStateChanged(CanDraw());
 }
 
-viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata()
-    const {
+viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
   viz::CompositorFrameMetadata metadata;
+
+  if (active_tree_->request_presentation_time()) {
+    metadata.presentation_token = ++last_presentation_token_;
+    // Assume there is never a constant stream of requests that triggers
+    // overflow.
+    CHECK_NE(0u, last_presentation_token_);
+    presentation_token_to_frame_[last_presentation_token_] =
+        active_tree_->source_frame_number();
+  }
+
   metadata.device_scale_factor = active_tree_->painted_device_scale_factor() *
                                  active_tree_->device_scale_factor();
 
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 2dbe0d58..83356aa 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/flat_map.h"
 #include "base/macros.h"
 #include "base/sequenced_task_runner.h"
 #include "base/time/time.h"
@@ -138,6 +139,14 @@
 
   virtual void RequestBeginMainFrameNotExpected(bool new_state) = 0;
 
+  // Called when a presentation time is requested. |source_frames| identifies
+  // the frames that correspond to the request.
+  virtual void DidPresentCompositorFrameOnImplThread(
+      const std::vector<int>& source_frames,
+      base::TimeTicks time,
+      base::TimeDelta refresh,
+      uint32_t flags) = 0;
+
  protected:
   virtual ~LayerTreeHostImplClient() {}
 };
@@ -563,7 +572,7 @@
 
   void ScheduleMicroBenchmark(std::unique_ptr<MicroBenchmarkImpl> benchmark);
 
-  viz::CompositorFrameMetadata MakeCompositorFrameMetadata() const;
+  viz::CompositorFrameMetadata MakeCompositorFrameMetadata();
 
   // Viewport rectangle and clip in device space.  These rects are used to
   // prioritize raster and determine what is submitted in a CompositorFrame.
@@ -943,6 +952,15 @@
 
   std::unique_ptr<UkmManager> ukm_manager_;
 
+  // Maps from presentation_token set on CF to the source frame that requested
+  // it. Presentation tokens are requested if the active tree has
+  // request_presentation_time() set.
+  base::flat_map<uint32_t, int> presentation_token_to_frame_;
+
+  // If non-zero identifies the presentation-token added to the last CF. Reset
+  // to zero when no more presentation tokens are in flight.
+  uint32_t last_presentation_token_ = 0u;
+
   DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
 };
 
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index c0b5394..831ecc4 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -197,6 +197,11 @@
   }
   void NotifyImageDecodeRequestFinished() override {}
   void RequestBeginMainFrameNotExpected(bool new_state) override {}
+  void DidPresentCompositorFrameOnImplThread(
+      const std::vector<int>& source_frames,
+      base::TimeTicks time,
+      base::TimeDelta refresh,
+      uint32_t flags) override {}
 
   void set_reduce_memory_result(bool reduce_memory_result) {
     reduce_memory_result_ = reduce_memory_result;
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 8e2a816a..1ef63d99 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3066,7 +3066,7 @@
   bool IsCommitAllowed() const override { return local_surface_id_.is_valid(); }
 
  private:
-  viz::LocalSurfaceIdAllocator allocator_;
+  viz::ParentLocalSurfaceIdAllocator allocator_;
   viz::LocalSurfaceId local_surface_id_;
 };
 
@@ -7603,7 +7603,7 @@
   void AfterTest() override {}
 
   viz::LocalSurfaceId expected_local_surface_id_;
-  viz::LocalSurfaceIdAllocator allocator_;
+  viz::ParentLocalSurfaceIdAllocator allocator_;
 };
 
 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId);
@@ -8209,7 +8209,7 @@
 
 class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest {
  public:
-  LayerTreeHostTestCheckerboardUkm() : url_(GURL("chrome://test")) {}
+  LayerTreeHostTestCheckerboardUkm() : url_(GURL("https://example.com")) {}
 
   void BeginTest() override {
     PostSetNeedsCommitToMainThread();
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index bb1da082..8815683 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -552,6 +552,11 @@
 
   LayerTreeLifecycle& lifecycle() { return lifecycle_; }
 
+  bool request_presentation_time() const { return request_presentation_time_; }
+  void set_request_presentation_time(bool value) {
+    request_presentation_time_ = value;
+  }
+
  protected:
   float ClampPageScaleFactorToLimits(float page_scale_factor) const;
   void PushPageScaleFactorAndLimits(const float* page_scale_factor,
@@ -674,7 +679,10 @@
   // lifecycle states. See: |LayerTreeLifecycle|.
   LayerTreeLifecycle lifecycle_;
 
- private:
+  // If true LayerTreeHostImpl requests a presentation token for the current
+  // frame.
+  bool request_presentation_time_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(LayerTreeImpl);
 };
 
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc
index ef06407b..dafbc8f3 100644
--- a/cc/trees/proxy_impl.cc
+++ b/cc/trees/proxy_impl.cc
@@ -500,6 +500,17 @@
   SetNeedsCommitOnImplThread();
 }
 
+void ProxyImpl::DidPresentCompositorFrameOnImplThread(
+    const std::vector<int>& source_frames,
+    base::TimeTicks time,
+    base::TimeDelta refresh,
+    uint32_t flags) {
+  MainThreadTaskRunner()->PostTask(
+      FROM_HERE, base::BindOnce(&ProxyMain::DidPresentCompositorFrame,
+                                proxy_main_weak_ptr_, source_frames, time,
+                                refresh, flags));
+}
+
 void ProxyImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
   DCHECK(IsImplThread());
   host_impl_->WillBeginImplFrame(args);
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h
index 40700e5..21560e7f 100644
--- a/cc/trees/proxy_impl.h
+++ b/cc/trees/proxy_impl.h
@@ -98,6 +98,11 @@
   void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw) override;
   void NeedsImplSideInvalidation(bool needs_first_draw_on_activation) override;
   void NotifyImageDecodeRequestFinished() override;
+  void DidPresentCompositorFrameOnImplThread(
+      const std::vector<int>& source_frames,
+      base::TimeTicks time,
+      base::TimeDelta refresh,
+      uint32_t flags) override;
 
   // SchedulerClient implementation
   void WillBeginImplFrame(const viz::BeginFrameArgs& args) override;
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc
index 8b6a764..426a9c4 100644
--- a/cc/trees/proxy_main.cc
+++ b/cc/trees/proxy_main.cc
@@ -303,6 +303,14 @@
   layer_tree_host_->DidBeginMainFrame();
 }
 
+void ProxyMain::DidPresentCompositorFrame(const std::vector<int>& source_frames,
+                                          base::TimeTicks time,
+                                          base::TimeDelta refresh,
+                                          uint32_t flags) {
+  layer_tree_host_->DidPresentCompositorFrame(source_frames, time, refresh,
+                                              flags);
+}
+
 bool ProxyMain::IsStarted() const {
   DCHECK(IsMainThread());
   return started_;
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h
index df55511..d494a5c 100644
--- a/cc/trees/proxy_main.h
+++ b/cc/trees/proxy_main.h
@@ -51,6 +51,10 @@
   void DidCompletePageScaleAnimation();
   void BeginMainFrame(
       std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state);
+  void DidPresentCompositorFrame(const std::vector<int>& source_frames,
+                                 base::TimeTicks time,
+                                 base::TimeDelta refresh,
+                                 uint32_t flags);
 
   CommitPipelineStage max_requested_pipeline_stage() const {
     return max_requested_pipeline_stage_;
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index f86d1e1..ebbe994d 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -463,6 +463,15 @@
   SetNeedsCommitOnImplThread();
 }
 
+void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
+    const std::vector<int>& source_frames,
+    base::TimeTicks time,
+    base::TimeDelta refresh,
+    uint32_t flags) {
+  layer_tree_host_->DidPresentCompositorFrame(source_frames, time, refresh,
+                                              flags);
+}
+
 void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
   if (scheduler_on_impl_thread_) {
     scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index cf14f11..ec470b1 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -116,6 +116,11 @@
   void NeedsImplSideInvalidation(bool needs_first_draw_on_activation) override;
   void RequestBeginMainFrameNotExpected(bool new_state) override;
   void NotifyImageDecodeRequestFinished() override;
+  void DidPresentCompositorFrameOnImplThread(
+      const std::vector<int>& source_frames,
+      base::TimeTicks time,
+      base::TimeDelta refresh,
+      uint32_t flags) override;
 
   void RequestNewLayerTreeFrameSink();
 
diff --git a/cc/trees/ukm_manager_unittest.cc b/cc/trees/ukm_manager_unittest.cc
index b934159..f9ad62bc 100644
--- a/cc/trees/ukm_manager_unittest.cc
+++ b/cc/trees/ukm_manager_unittest.cc
@@ -10,8 +10,8 @@
 namespace cc {
 namespace {
 
-const char kTestUrl1[] = "chrome://test";
-const char kTestUrl2[] = "chrome://test2";
+const char kTestUrl1[] = "https://example.com/foo";
+const char kTestUrl2[] = "https://example.com/bar";
 
 const char kUserInteraction[] = "Compositor.UserInteraction";
 const char kCheckerboardArea[] = "CheckerboardedContentArea";
diff --git a/chrome/VERSION b/chrome/VERSION
index ed4d6a9..24ee40d 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=65
 MINOR=0
-BUILD=3288
+BUILD=3289
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index 26fb1e9..7dd2046 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -173,6 +173,9 @@
     public static final String CHROME_HOME_PROMO = "ChromeHomePromo";
     public static final String CHROME_HOME_PROMO_INFO_ONLY = "ChromeHomePromoInfoOnly";
     public static final String CHROME_HOME_PROMO_ON_STARTUP = "ChromeHomePromoOnStartup";
+    public static final String CHROME_HOME_SHOW_GOOGLE_G_WHEN_URL_CLEARED =
+            "ChromeHomeShowGoogleGWhenUrlCleared";
+    public static final String CHROME_HOME_SURVEY = "ChromeHomeSurvey";
     public static final String CHROME_HOME_SWIPE_VELOCITY_FEATURE = "ChromeHomeSwipeLogicVelocity";
     public static final String CHROME_MEMEX = "ChromeMemex";
     public static final String CHROME_SMART_SELECTION = "ChromeSmartSelection";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
index 1bd3c2c..648062e33 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -703,6 +703,13 @@
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         if (changed) {
             onViewportChanged();
+        } else {
+            // Have content pick up the size and browser control information
+            // when the content view got laid out with non-zero dimension after
+            // initialization. Successive calls with the same values are ignored
+            // by ViewAndroid that stores the size.
+            View v = getActiveView();
+            if (v != null) setSize(getActiveWebContents(), v, v.getWidth(), v.getHeight());
         }
         super.onLayout(changed, l, t, r, b);
 
@@ -935,7 +942,6 @@
         if (view == null || (tab.isNativePage() && view == tab.getView())) return;
         tab.setTopControlsHeight(getTopControlsHeightPixels(), controlsResizeView());
         tab.setBottomControlsHeight(getBottomControlsHeightPixels());
-        setSize(tab.getWebContents(), view, getWidth(), getHeight());
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java
new file mode 100644
index 0000000..171ea66
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java
@@ -0,0 +1,81 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.feedback;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.AsyncTask.Status;
+
+import org.chromium.base.ContextUtils;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * A helper class to make implementing an AsyncFeedbackSource easier for the common case.  The bulk
+ * of the background work is meant to be done in {@link #doInBackground(Context)} and the result can
+ * be queried from {@link #getResult()}.  Subclasses are meant to override {@link #getFeedback()} or
+ * {@link #getLogs()} as necessary and use {@link #getResult()} if they need the result from the
+ * asynchronous work.
+ * @param <Result> The {@link Object} type that represents the result of doing the background work.
+ */
+public abstract class AsyncFeedbackSourceAdapter<Result> implements AsyncFeedbackSource {
+    private Worker mWorker;
+
+    private class Worker extends AsyncTask<Context, Void, Result> {
+        private final Runnable mCallback;
+
+        public Worker(Runnable callback) {
+            mCallback = callback;
+        }
+
+        // AsyncTask implementation.
+        @Override
+        protected Result doInBackground(Context... params) {
+            return AsyncFeedbackSourceAdapter.this.doInBackground(params[0]);
+        }
+
+        @Override
+        protected void onPostExecute(Result result) {
+            super.onPostExecute(result);
+
+            mCallback.run();
+        }
+    }
+
+    /**
+     * Meant to do the actual work in the background.  This method will be called from a thread in
+     * the {@link AsyncTask} thread pool.
+     * @param context The application {@link Context}.
+     * @return        The result of doing the work in the background or {@code null}.
+     */
+    protected abstract Result doInBackground(Context context);
+
+    /**
+     * @return The result of the background work if it has been started and finished.  This will be
+     *         null if the underlying background task has not finished yet (see {@link #isReady()})
+     *         or if {@link #doInBackground(Context)} returned {@code null}.
+     */
+    protected final Result getResult() {
+        try {
+            return mWorker != null && mWorker.getStatus() == Status.FINISHED ? mWorker.get() : null;
+        } catch (ExecutionException | InterruptedException e) {
+            return null;
+        }
+    }
+
+    // AsyncFeedbackSource implementation.
+    @Override
+    public final boolean isReady() {
+        return mWorker != null && mWorker.getStatus() == Status.FINISHED;
+    }
+
+    @Override
+    public final void start(Runnable callback) {
+        if (mWorker != null) return;
+        mWorker = new Worker(callback);
+        mWorker.executeOnExecutor(
+                AsyncTask.THREAD_POOL_EXECUTOR, ContextUtils.getApplicationContext());
+    }
+}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/HistogramFeedbackSource.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/HistogramFeedbackSource.java
index d0d6896..99961b0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/HistogramFeedbackSource.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/HistogramFeedbackSource.java
@@ -17,6 +17,10 @@
 public class HistogramFeedbackSource implements FeedbackSource {
     public static final String HISTOGRAMS_KEY = "histograms";
 
+    // Minimum physical memory (in KB) required on the device to get a dump of the buckets.
+    // Currently, it is required that the physical memory be more than 2 GB.
+    private static final int MIN_PHYSICAL_MEMORY_KB = 2 * 1024 * 1024 + 1;
+
     private final boolean mIsOffTheRecord;
 
     HistogramFeedbackSource(Profile profile) {
@@ -27,7 +31,10 @@
     public Pair<String, String> getLogs() {
         if (mIsOffTheRecord) return null;
         int jsonVerbosityLevel = JSONVerbosityLevel.JSON_VERBOSITY_LEVEL_FULL;
-        if (SysUtils.isLowEndDevice()) {
+
+        if (SysUtils.isLowEndDevice()
+                || SysUtils.amountOfPhysicalMemoryKB() < MIN_PHYSICAL_MEMORY_KB
+                || SysUtils.isCurrentlyLowMemory()) {
             jsonVerbosityLevel = JSONVerbosityLevel.JSON_VERBOSITY_LEVEL_OMIT_BUCKETS;
         }
         return Pair.create(HISTOGRAMS_KEY, StatisticsRecorderAndroid.toJson(jsonVerbosityLevel));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java
index 679ee6d..043bb62 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java
@@ -4,8 +4,7 @@
 
 package org.chromium.chrome.browser.feedback;
 
-import android.os.AsyncTask;
-import android.os.AsyncTask.Status;
+import android.content.Context;
 import android.os.Environment;
 import android.os.StatFs;
 import android.util.Pair;
@@ -17,76 +16,17 @@
 
 import java.io.File;
 import java.util.Map;
-import java.util.concurrent.ExecutionException;
 
 /** Grabs feedback about the current system. */
 @JNINamespace("chrome::android")
-public class SystemInfoFeedbackSource implements AsyncFeedbackSource {
-    private StorageTask mStorageTask;
-
-    private static class StorageTask extends AsyncTask<Void, Void, StatFs> {
-        private Runnable mCallback;
-
-        public StorageTask(Runnable callback) {
-            mCallback = callback;
-        }
-
-        Long getAvailableSpaceMB() {
-            if (getStatus() != Status.FINISHED) return null;
-
-            try {
-                StatFs statFs = get();
-                if (statFs == null) return null;
-                long blockSize = ApiCompatibilityUtils.getBlockSize(statFs);
-                return ApiCompatibilityUtils.getAvailableBlocks(statFs) * blockSize / 1024 / 1024;
-            } catch (ExecutionException | InterruptedException e) {
-                return null;
-            }
-        }
-
-        Long getTotalSpaceMB() {
-            if (getStatus() != Status.FINISHED) return null;
-
-            try {
-                StatFs statFs = get();
-                if (statFs == null) return null;
-                long blockSize = ApiCompatibilityUtils.getBlockSize(statFs);
-                return ApiCompatibilityUtils.getBlockCount(statFs) * blockSize / 1024 / 1024;
-            } catch (ExecutionException | InterruptedException e) {
-                return null;
-            }
-        }
-
-        // AsyncTask implementation.
-        @Override
-        protected StatFs doInBackground(Void... params) {
-            File directory = Environment.getDataDirectory();
-
-            if (!directory.exists()) return null;
-
-            return new StatFs(directory.getPath());
-        }
-
-        @Override
-        protected void onPostExecute(StatFs result) {
-            super.onPostExecute(result);
-            mCallback.run();
-        }
-    }
-
-    SystemInfoFeedbackSource() {}
-
-    // AsyncFeedbackSource implementation.
+public class SystemInfoFeedbackSource extends AsyncFeedbackSourceAdapter<StatFs> {
+    // AsyncFeedbackSourceAdapter implementation.
     @Override
-    public boolean isReady() {
-        return mStorageTask != null && mStorageTask.getStatus() == Status.FINISHED;
-    }
+    protected StatFs doInBackground(Context context) {
+        File directory = Environment.getDataDirectory();
+        if (!directory.exists()) return null;
 
-    @Override
-    public void start(Runnable callback) {
-        if (mStorageTask != null) return;
-        mStorageTask = new StorageTask(callback);
-        mStorageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+        return new StatFs(directory.getPath());
     }
 
     @Override
@@ -100,12 +40,15 @@
                 Pair.create("GPU Model", nativeGetGpuModel()),
                 Pair.create("UI Locale", LocaleUtils.getDefaultLocaleString()));
 
-        if (isReady()) {
-            Long availSpace = mStorageTask.getAvailableSpaceMB();
-            Long totalSpace = mStorageTask.getTotalSpaceMB();
+        StatFs statFs = getResult();
+        if (statFs != null) {
+            long blockSize = ApiCompatibilityUtils.getBlockSize(statFs);
+            long availSpace =
+                    ApiCompatibilityUtils.getAvailableBlocks(statFs) * blockSize / 1024 / 1024;
+            long totalSpace = ApiCompatibilityUtils.getBlockCount(statFs) * blockSize / 1024 / 1024;
 
-            if (availSpace != null) feedback.put("Available Storage (MB)", availSpace.toString());
-            if (totalSpace != null) feedback.put("Total Storage (MB)", totalSpace.toString());
+            feedback.put("Available Storage (MB)", Long.toString(availSpace));
+            feedback.put("Total Storage (MB)", Long.toString(totalSpace));
         }
 
         return feedback;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java
index d1f1841..e594c575 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarPhone.java
@@ -19,11 +19,8 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.WindowDelegate;
-import org.chromium.chrome.browser.locale.LocaleManager;
 import org.chromium.chrome.browser.ntp.NewTabPage;
-import org.chromium.chrome.browser.search_engines.TemplateUrlService;
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
 import org.chromium.chrome.browser.util.MathUtils;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
@@ -209,29 +206,12 @@
     }
 
     private void updateGoogleG() {
-        // The Google 'G' is not shown in Chrome Home.
-        if (mBottomSheet != null) return;
-
         // The toolbar data provider can be null during startup, before the ToolbarManager has been
         // initialized.
         ToolbarDataProvider toolbarDataProvider = getToolbarDataProvider();
         if (toolbarDataProvider == null) return;
 
-        LocaleManager localeManager = LocaleManager.getInstance();
-        if (localeManager.hasCompletedSearchEnginePromo()
-                || localeManager.hasShownSearchEnginePromoThisSession()) {
-            mGoogleGContainer.setVisibility(View.GONE);
-            return;
-        }
-
-        // Only access ChromeFeatureList and TemplateUrlService after the NTP check,
-        // to prevent native method calls before the native side has been initialized.
-        NewTabPage ntp = toolbarDataProvider.getNewTabPageForCurrentTab();
-        boolean isShownInRegularNtp = ntp != null && ntp.isLocationBarShownInNTP()
-                && ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SHOW_GOOGLE_G_IN_OMNIBOX)
-                && TemplateUrlService.getInstance().isDefaultSearchEngineGoogle();
-
-        if (!isShownInRegularNtp) {
+        if (!getToolbarDataProvider().shouldShowGoogleG(mUrlBar.getEditableText().toString())) {
             mGoogleGContainer.setVisibility(View.GONE);
             return;
         }
@@ -364,6 +344,13 @@
             @Override
             public void onSheetOpened(@StateChangeReason int reason) {
                 if (reason == StateChangeReason.OMNIBOX_FOCUS) mCloseSheetOnBackButton = true;
+
+                updateGoogleG();
+            }
+
+            @Override
+            public void onSheetClosed(@StateChangeReason int reason) {
+                updateGoogleG();
             }
 
             @Override
@@ -378,14 +365,12 @@
             }
         });
 
-        // The Google 'G' is not shown in Chrome Home.
-        removeView(mGoogleGContainer);
-        mGoogleGContainer = null;
-        mGoogleG = null;
-
         // Chrome Home does not use the incognito badge. Remove the View to save memory.
         removeView(mIncognitoBadge);
         mIncognitoBadge = null;
+
+        // TODO(twellington): remove and null out mGoogleG and mGoogleGContainer if we remove
+        //                    support for the Google 'G' to save memory.
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java
index 48850618..7359d44 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java
@@ -30,7 +30,6 @@
 import android.widget.TextView;
 
 import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.base.VisibleForTesting;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.PasswordManagerHandler.PasswordListObserver;
@@ -81,9 +80,6 @@
     // If false this represents a saved name/password.
     private boolean mException;
 
-    @VisibleForTesting
-    public static final String VIEW_PASSWORDS = "view-passwords";
-
     private ClipboardManager mClipboard;
     private Bundle mExtras;
     private View mView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordReauthenticationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordReauthenticationFragment.java
index 5643bda..75589ce1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordReauthenticationFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordReauthenticationFragment.java
@@ -32,7 +32,8 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mFragmentManager = getFragmentManager();
-        if (!sPreventLockDevice) {
+        boolean isFirstTime = savedInstanceState == null;
+        if (!sPreventLockDevice && isFirstTime) {
             lockDevice();
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
index e95d349..a0a93517 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
@@ -104,6 +104,13 @@
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         menu.clear();
         inflater.inflate(R.menu.save_password_preferences_action_bar_menu, menu);
+        menu.findItem(R.id.export_passwords).setEnabled(false);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        menu.findItem(R.id.export_passwords).setEnabled(!mNoPasswords);
+        super.onPrepareOptionsMenu(menu);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java
index 2179a44b..088275f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java
@@ -71,6 +71,11 @@
     }
 
     @Override
+    public boolean shouldShowGoogleG(String urlBarText) {
+        return false;
+    }
+
+    @Override
     public boolean isOfflinePage() {
         return false;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java
index a2cd43e..37d8bea8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java
@@ -16,6 +16,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.infobar.InfoBarContainer;
 import org.chromium.chrome.browser.infobar.InfoBarContainerLayout.Item;
@@ -49,6 +50,7 @@
 
     private static final String TRIAL_NAME = "ChromeHome";
     private static final String MAX_NUMBER = "MaxNumber";
+    private static final String TEST_SITE_ID = "obw74vpeieqaw4xmw7o6qlpdbq";
 
     private static boolean sForceUmaEnabledForTesting;
 
@@ -93,6 +95,8 @@
         String siteId;
         if (commandLine.hasSwitch(PARAM_NAME)) {
             siteId = commandLine.getSwitchValue(PARAM_NAME);
+        } else if (ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME_SURVEY)) {
+            siteId = TEST_SITE_ID;
         } else {
             siteId = VariationsAssociatedData.getVariationParamValue(TRIAL_NAME, PARAM_NAME);
         }
@@ -117,7 +121,8 @@
         if (!FeatureUtilities.isChromeHomeEnabled()) return true;
         return wasChromeHomeEnabledForMinimumOneWeek()
                 || CommandLine.getInstance().hasSwitch(
-                           ChromeSwitches.CHROME_HOME_FORCE_ENABLE_SURVEY);
+                           ChromeSwitches.CHROME_HOME_FORCE_ENABLE_SURVEY)
+                || ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME_SURVEY);
     }
 
     /**
@@ -397,7 +402,8 @@
             if (!mController.doesUserQualifyForSurvey()) return false;
             return mController.isRandomlySelectedForSurvey()
                     || CommandLine.getInstance().hasSwitch(
-                               ChromeSwitches.CHROME_HOME_FORCE_ENABLE_SURVEY);
+                               ChromeSwitches.CHROME_HOME_FORCE_ENABLE_SURVEY)
+                    || ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME_SURVEY);
         }
 
         @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 3f5f1eb..48d6f05 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -739,6 +739,13 @@
                 return handleJavaCrash();
             }
 
+            if (mNativeTabAndroid == 0) {
+                // if mNativeTabAndroid is invalid then we are going to crash anyways on the
+                // native side. Lets crash on the java side so that we can have a better stack
+                // trace. https://crbug.com/662877
+                throw new RuntimeException("Please post this crash on crbug.com/662877");
+            }
+
             // We load the URL from the tab rather than directly from the ContentView so the tab has
             // a chance of using a prerenderer page is any.
             int loadType = nativeLoadUrl(mNativeTabAndroid, params.getUrl(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java
index 43972cdc..223782d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java
@@ -70,6 +70,12 @@
     boolean isOfflinePage();
 
     /**
+     * @param urlBarText The text currently displayed in the url bar.
+     * @return Whether the Google 'G' should be shown in the location bar.
+     */
+    boolean shouldShowGoogleG(String urlBarText);
+
+    /**
      * @return Whether the security icon should be displayed.
      */
     boolean shouldShowSecurityIcon();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java
index 56a466e..9f1024f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java
@@ -200,6 +200,11 @@
             }
 
             @Override
+            public boolean shouldShowGoogleG(String urlBarText) {
+                return false;
+            }
+
+            @Override
             public boolean shouldShowSecurityIcon() {
                 return false;
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java
index 12e45ca..6fcd224 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarModelImpl.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.Build;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
@@ -17,9 +18,11 @@
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.dom_distiller.DomDistillerServiceFactory;
 import org.chromium.chrome.browser.dom_distiller.DomDistillerTabUtils;
+import org.chromium.chrome.browser.locale.LocaleManager;
 import org.chromium.chrome.browser.ntp.NewTabPage;
 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.search_engines.TemplateUrlService;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.toolbar.ToolbarModel.ToolbarModelDelegate;
 import org.chromium.chrome.browser.util.ColorUtils;
@@ -198,6 +201,31 @@
     }
 
     @Override
+    public boolean shouldShowGoogleG(String urlBarText) {
+        LocaleManager localeManager = LocaleManager.getInstance();
+        if (localeManager.hasCompletedSearchEnginePromo()
+                || localeManager.hasShownSearchEnginePromoThisSession()) {
+            return false;
+        }
+
+        // Only access ChromeFeatureList and TemplateUrlService after the NTP check,
+        // to prevent native method calls before the native side has been initialized.
+        NewTabPage ntp = getNewTabPageForCurrentTab();
+        boolean isShownInRegularNtp = ntp != null && ntp.isLocationBarShownInNTP()
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SHOW_GOOGLE_G_IN_OMNIBOX);
+
+        boolean isShownInBottomSheet = mBottomSheet != null && !mBottomSheet.isShowingNewTab()
+                && mBottomSheet.isSheetOpen() && TextUtils.isEmpty(urlBarText)
+                && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME_CLEAR_URL_ON_OPEN)
+                && ChromeFeatureList.isEnabled(
+                           ChromeFeatureList.CHROME_HOME_SHOW_GOOGLE_G_WHEN_URL_CLEARED);
+
+        return (isShownInRegularNtp || isShownInBottomSheet)
+                && TemplateUrlService.getInstance().isDefaultSearchEngineGoogle();
+    }
+
+    @Override
     public boolean shouldShowSecurityIcon() {
         return !clearUrlForBottomSheetOpen() && getSecurityIconResource() != 0;
     }
@@ -260,6 +288,7 @@
     private boolean clearUrlForBottomSheetOpen() {
         return mBottomSheet != null && mBottomSheet.isSheetOpen()
                 && mBottomSheet.getTargetSheetState() != BottomSheet.SHEET_STATE_PEEK
+                && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
                 && ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_HOME_CLEAR_URL_ON_OPEN);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/keyboard/GvrKeyboardLoaderClient.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/keyboard/GvrKeyboardLoaderClient.java
index a7358ff..051eedbf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/keyboard/GvrKeyboardLoaderClient.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/keyboard/GvrKeyboardLoaderClient.java
@@ -30,6 +30,10 @@
 
     private static IGvrKeyboardLoader sLoader = null;
     private static ClassLoader sRemoteClassLoader = null;
+    // GVR doesn't support setting the context twice in the application's lifetime and crashes if we
+    // do so. Setting the same context wrapper is a no-op, so we keep a reference to the one we
+    // create and use it across re-initialization of the keyboard api.
+    private static KeyboardContextWrapper sContextWrapper = null;
 
     @CalledByNative
     public static long loadKeyboardSDK() {
@@ -86,8 +90,10 @@
 
     @CalledByNative
     public static Context getContextWrapper() {
+        if (sContextWrapper != null) return sContextWrapper;
         Context context = ContextUtils.getApplicationContext();
-        return new KeyboardContextWrapper(getRemoteContext(context), context);
+        sContextWrapper = new KeyboardContextWrapper(getRemoteContext(context), context);
+        return sContextWrapper;
     }
 
     @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
index 92b33af..58b8fba 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -1406,7 +1406,7 @@
      * @param animate If true, the sheet will animate to the provided state, otherwise it will
      *                move there instantly.
      * @param reason The reason the sheet state is changing. This can be specified to indicate to
-     *               observers that a more specific event has occured, otherwise
+     *               observers that a more specific event has occurred, otherwise
      *               STATE_CHANGE_REASON_NONE can be used.
      */
     public void setSheetState(
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index c4347f7..a81975d 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2660,7 +2660,7 @@
         URL copied.
       </message>
       <message name="IDS_CHROME_HOME_SURVEY_PROMPT" desc="Message shown that invites the user to take a survey about Chrome. 'Help' and 'improve' are imperative verbs. 'Take survey' is a tappable link. When tapped, a survey about Chrome opens.">
-        Help improve Chrome. <ph name="BEGIN_LINK">&lt;LINK&gt;</ph>Take survey.<ph name="END_LINK">&lt;/LINK&gt;</ph>
+        Help improve Chrome. <ph name="BEGIN_LINK">&lt;LINK&gt;</ph>Take survey<ph name="END_LINK">&lt;/LINK&gt;</ph>
       </message>
 
       <!-- Accessibility -->
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index cfa65afd..2580f67c 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -409,6 +409,7 @@
   "java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java",
   "java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitorDelegate.java",
   "java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSource.java",
+  "java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java",
   "java/src/org/chromium/chrome/browser/feedback/ChromeHomeFeedbackSource.java",
   "java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java",
   "java/src/org/chromium/chrome/browser/feedback/ConnectivityFeedbackSource.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java
index a34a8a3..5d74e6b1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java
@@ -701,6 +701,7 @@
     @Test
     @SmallTest
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @RetryOnFailure
     public void testCellularPrerenderingDoesntKillSpareRenderer() throws Exception {
         final CustomTabsSessionToken token =
                 CustomTabsSessionToken.createMockSessionTokenForTesting();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
index 4ffce20..7dcf93fd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
@@ -22,6 +22,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
@@ -143,8 +144,9 @@
     }
 
     @Test
-    @MediumTest
-    @Feature({"NewTabPage"})
+    //@MediumTest
+    //@Feature({"NewTabPage"})
+    @DisabledTest(message = "crbug.com/793054")
     public void testAllDismissed() throws InterruptedException, TimeoutException {
         setSuggestionsAndWaitForUpdate(3);
         assertEquals(3, mSource.getSuggestionsForCategory(TEST_CATEGORY).size());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
index 776efb7d..5db4963 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
@@ -5,14 +5,18 @@
 package org.chromium.chrome.browser.preferences.password;
 
 import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;
 import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
+import static android.support.test.espresso.matcher.ViewMatchers.withParent;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
 
+import static org.hamcrest.Matchers.allOf;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
 
 import android.support.test.InstrumentationRegistry;
 import android.support.test.espresso.Espresso;
@@ -106,6 +110,30 @@
         }
     }
 
+    // Used to provide fake lists of stored passwords. Tests which need it can use setPasswordSource
+    // to instantiate it.
+    FakePasswordManagerHandler mHandler;
+
+    /**
+     * Helper to set up a fake source of displayed passwords.
+     * @param entry An entry to be added to saved passwords. Can be null.
+     */
+    private void setPasswordSource(SavedPasswordEntry entry) throws Exception {
+        if (mHandler == null) {
+            mHandler = new FakePasswordManagerHandler(PasswordManagerHandlerProvider.getInstance());
+        }
+        ArrayList<SavedPasswordEntry> entries = new ArrayList<SavedPasswordEntry>();
+        if (entry != null) entries.add(entry);
+        mHandler.setSavedPasswords(entries);
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                PasswordManagerHandlerProvider.getInstance().setPasswordManagerHandlerForTest(
+                        mHandler);
+            }
+        });
+    }
+
     /**
      * Ensure that resetting of empty passwords list works.
      */
@@ -244,6 +272,82 @@
     }
 
     /**
+     * Check that if there are no saved passwords, the export menu item is disabled.
+     */
+    @Test
+    @SmallTest
+    @Feature({"Preferences"})
+    @EnableFeatures("password-export")
+    public void testExportMenuDisabled() throws Exception {
+        // Ensure there are no saved passwords reported to settings.
+        setPasswordSource(null);
+
+        ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
+
+        final Preferences preferences =
+                PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
+                        SavePasswordsPreferences.class.getName());
+
+        Espresso.openActionBarOverflowOrOptionsMenu(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
+        // The text matches a text view, but the disabled entity is some wrapper two levels up in
+        // the view hierarchy, hence the two withParent matchers.
+        Espresso.onView(allOf(withText(R.string.save_password_preferences_export_action_title),
+                                withParent(withParent(not(isEnabled())))))
+                .check(matches(isDisplayed()));
+    }
+
+    /**
+     * Check that if there are saved passwords, the export menu item is enabled.
+     */
+    @Test
+    @SmallTest
+    @Feature({"Preferences"})
+    @EnableFeatures("password-export")
+    public void testExportMenuEnabled() throws Exception {
+        setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password"));
+
+        ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
+
+        final Preferences preferences =
+                PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
+                        SavePasswordsPreferences.class.getName());
+
+        Espresso.openActionBarOverflowOrOptionsMenu(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
+        // The text matches a text view, but the potentially disabled entity is some wrapper two
+        // levels up in the view hierarchy, hence the two withParent matchers.
+        Espresso.onView(allOf(withText(R.string.save_password_preferences_export_action_title),
+                                withParent(withParent(isEnabled()))))
+                .check(matches(isDisplayed()));
+    }
+
+    /**
+     * Check that if "password-export" feature is not explicitly enabled, there is no menu item to
+     * export passwords.
+     * TODO(crbug.com/788701): Add the @DisableFeatures annotation once exporting gets enabled by
+     * default, and remove completely once the feature is gone.
+     */
+    @Test
+    @SmallTest
+    @Feature({"Preferences"})
+    public void testExportMenuMissing() throws Exception {
+        ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
+
+        final Preferences preferences =
+                PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
+                        SavePasswordsPreferences.class.getName());
+
+        // Ideally this would need the same matcher (Espresso.OVERFLOW_BUTTON_MATCHER) as used
+        // inside Espresso.openActionBarOverflowOrOptionsMenu(), but that is private to Espresso.
+        // Matching the overflow menu with the class name "OverflowMenuButton" won't work on
+        // obfuscated release builds, so matching the description remains. The
+        // OVERFLOW_BUTTON_MATCHER specifies the string directly, not via string resource, so this
+        // is also done below.
+        Espresso.onView(withContentDescription("More options")).check(doesNotExist());
+    }
+
+    /**
      * Check that the export menu item is included and hidden behind the overflow menu. Check that
      * the menu displays the warning before letting the user export passwords.
      */
@@ -252,6 +356,8 @@
     @Feature({"Preferences"})
     @EnableFeatures("password-export")
     public void testExportMenuItem() throws Exception {
+        setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password"));
+
         ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
         ReauthenticationManager.setScreenLockSetUpOverride(
                 ReauthenticationManager.OverrideState.AVAILABLE);
@@ -280,6 +386,8 @@
     @Feature({"Preferences"})
     @EnableFeatures("password-export")
     public void testExportMenuItemNoLock() throws Exception {
+        setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password"));
+
         ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
         ReauthenticationManager.setScreenLockSetUpOverride(
                 ReauthenticationManager.OverrideState.UNAVAILABLE);
@@ -304,18 +412,7 @@
     @SmallTest
     @Feature({"Preferences"})
     public void testViewPasswordNoLock() throws Exception {
-        FakePasswordManagerHandler handler =
-                new FakePasswordManagerHandler(PasswordManagerHandlerProvider.getInstance());
-        ArrayList<SavedPasswordEntry> entries = new ArrayList<SavedPasswordEntry>();
-        entries.add(new SavedPasswordEntry("https://example.com", "test user", "password"));
-        handler.setSavedPasswords(entries);
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                PasswordManagerHandlerProvider.getInstance().setPasswordManagerHandlerForTest(
-                        handler);
-            }
-        });
+        setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password"));
 
         ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
         ReauthenticationManager.setScreenLockSetUpOverride(
@@ -332,8 +429,6 @@
         Espresso.onView(withText(R.string.password_entry_editor_set_lock_screen))
                 .inRoot(withDecorView(isEnabled()))
                 .check(matches(isDisplayed()));
-
-        handler.setSavedPasswords(null);
     }
 
     /**
@@ -343,18 +438,8 @@
     @SmallTest
     @Feature({"Preferences"})
     public void testViewPassword() throws Exception {
-        FakePasswordManagerHandler handler =
-                new FakePasswordManagerHandler(PasswordManagerHandlerProvider.getInstance());
-        ArrayList<SavedPasswordEntry> entries = new ArrayList<SavedPasswordEntry>();
-        entries.add(new SavedPasswordEntry("https://example.com", "test user", "test password"));
-        handler.setSavedPasswords(entries);
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                PasswordManagerHandlerProvider.getInstance().setPasswordManagerHandlerForTest(
-                        handler);
-            }
-        });
+        setPasswordSource(
+                new SavedPasswordEntry("https://example.com", "test user", "test password"));
 
         ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
         ReauthenticationManager.setScreenLockSetUpOverride(
@@ -372,7 +457,5 @@
         Espresso.onView(withContentDescription(R.string.password_entry_editor_view_stored_password))
                 .perform(click());
         Espresso.onView(withText("test password")).check(matches(isDisplayed()));
-
-        handler.setSavedPasswords(null);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDisplayModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDisplayModeTest.java
index 25f230a..7fd3cd4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDisplayModeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDisplayModeTest.java
@@ -16,6 +16,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.blink_public.platform.WebDisplayMode;
 import org.chromium.chrome.R;
@@ -48,8 +49,9 @@
     }
 
     @Test
-    @SmallTest
-    @Feature({"Webapps"})
+    //@SmallTest
+    //@Feature({"Webapps"})
+    @DisabledTest(message = "crbug.com/793133")
     public void testFullScreen() throws Exception {
         WebappActivity activity = startActivity(WebDisplayMode.FULLSCREEN);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OWNERS
new file mode 100644
index 0000000..37b4360
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OWNERS
@@ -0,0 +1 @@
+file://chrome/android/java/src/org/chromium/chrome/browser/widget/OWNERS
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java
index 508f4ff..ea402657 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/ToolbarProgressBarTest.java
@@ -80,11 +80,7 @@
             }
         });
 
-        // Make sure the progress bar is invisible before starting any of the tests.
-        if (mProgressBar.getVisibility() == View.VISIBLE) {
-            int count = mProgressVisibilityHelper.getCallCount();
-            mProgressVisibilityHelper.waitForCallback(count, 1);
-        }
+        ThreadUtils.runOnUiThreadBlocking(() -> mProgressBar.finish(false));
     }
 
     /**
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterSinkObservationTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterSinkObservationTest.java
index 981aed4..15a745b 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterSinkObservationTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterSinkObservationTest.java
@@ -9,15 +9,16 @@
 
 import android.os.Build;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
 import org.chromium.base.BaseSwitches;
 import org.chromium.base.CommandLine;
 import org.chromium.base.SysUtils;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.media.router.cast.MediaSink;
 import org.chromium.testing.local.LocalRobolectricTestRunner;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -95,7 +96,7 @@
     @Test
     @Feature({"MediaRouter"})
     public void testNotLowRamDevice() throws Exception {
-        SysUtils.reset();
+        SysUtils.resetForTesting();
         CommandLine.getInstance().appendSwitch(
                 BaseSwitches.DISABLE_LOW_END_DEVICE_MODE);
         assertTrue(mChromeMediaRouter.startObservingMediaSinks(SOURCE_ID1));
@@ -104,7 +105,7 @@
     @Test
     @Feature({"MediaRouter"})
     public void testIsLowRamDevice() throws Exception {
-        SysUtils.reset();
+        SysUtils.resetForTesting();
         CommandLine.getInstance().appendSwitch(
                 BaseSwitches.ENABLE_LOW_END_DEVICE_MODE);
         assertEquals(Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2,
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java
index 3220075..c9eaea8 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java
@@ -120,7 +120,7 @@
     public void tearDown() throws Exception {
         // Clean up static state for subsequent Robolectric tests.
         CommandLine.reset();
-        SysUtils.reset();
+        SysUtils.resetForTesting();
         ApplicationStatus.destroyForJUnitTests();
     }
 
diff --git a/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java b/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java
index fbc4ef5d..7fc589f 100644
--- a/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java
+++ b/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java
@@ -4,7 +4,6 @@
 
 package org.chromium.webapk.lib.runtime_library;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -84,16 +83,17 @@
         return NotificationManagerCompat.from(mContext).areNotificationsEnabled();
     }
 
-    @TargetApi(Build.VERSION_CODES.O)
+    @SuppressWarnings("NewApi")
     @Override
     public void notifyNotificationWithChannel(
             String platformTag, int platformID, Notification notification, String channelName) {
         NotificationManager notificationManager = getNotificationManager();
-        if (notification.getChannelId() != null) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && notification.getChannelId() != null) {
             NotificationChannel channel = new NotificationChannel(notification.getChannelId(),
                     channelName, NotificationManager.IMPORTANCE_DEFAULT);
             notificationManager.createNotificationChannel(channel);
         }
+
         notificationManager.notify(platformTag, platformID, notification);
     }
 
diff --git a/chrome/android/webapk/libs/runtime_library_version.gni b/chrome/android/webapk/libs/runtime_library_version.gni
index 8ad15921..88cc0557 100644
--- a/chrome/android/webapk/libs/runtime_library_version.gni
+++ b/chrome/android/webapk/libs/runtime_library_version.gni
@@ -5,4 +5,4 @@
 # Must be incremented whenever the runtime library is updated. The WebAPK
 # re-extracts the runtime library from the Chrome APK when
 # |runtime_library_version| is incremented.
-runtime_library_version = 4
+runtime_library_version = 5
diff --git a/chrome/app/chrome_crash_reporter_client_win.cc b/chrome/app/chrome_crash_reporter_client_win.cc
index 04d0569..fb2f173d 100644
--- a/chrome/app/chrome_crash_reporter_client_win.cc
+++ b/chrome/app/chrome_crash_reporter_client_win.cc
@@ -37,7 +37,6 @@
 // RegisterCrashKeys function in the crash_keys::CrashReporterClient interface
 // and the snprintf function defined here.
 constexpr char kActiveURL[] = "url-chunk";
-constexpr char kFontKeyName[] = "font_key_name";
 
 // Installed extensions. |kExtensionID| should be formatted with an integer,
 // in the range [0, kExtensionIDMaxCount).
@@ -53,14 +52,6 @@
 constexpr char kApValue[] = "ap";
 constexpr char kCohortName[] = "cohort-name";
 
-constexpr char kHungRendererOutstandingAckCount[] = "hung-outstanding-acks";
-constexpr char kHungRendererOutstandingEventType[] =
-    "hung-outstanding-event-type";
-constexpr char kHungRendererLastEventType[] = "hung-last-event-type";
-constexpr char kHungRendererReason[] = "hung-reason";
-constexpr char kInputEventFilterSendFailure[] =
-    "input-event-filter-send-failure";
-
 constexpr char kIsEnterpriseManaged[] = "is-enterprise-managed";
 
 constexpr char kViewCount[] = "view-count";
@@ -114,20 +105,11 @@
       {kIsEnterpriseManaged, kSmallSize},
 
       // content/:
-      {"bad_message_reason", kSmallSize},
       {"discardable-memory-allocated", kSmallSize},
       {"discardable-memory-free", kSmallSize},
-      {kFontKeyName, kSmallSize},
-      {"mojo-message-error", kMediumSize},
-      {"ppapi_path", kMediumSize},
       {"subresource_url", kLargeSize},
       {"total-discardable-memory-allocated", kSmallSize},
       {kViewCount, kSmallSize},
-      {kHungRendererOutstandingAckCount, kSmallSize},
-      {kHungRendererOutstandingEventType, kSmallSize},
-      {kHungRendererLastEventType, kSmallSize},
-      {kHungRendererReason, kSmallSize},
-      {kInputEventFilterSendFailure, kSmallSize},
 
       // media/:
       {kZeroEncodeDetails, kSmallSize},
@@ -144,10 +126,6 @@
 
       // TODO(sunnyps): Remove after fixing crbug.com/724999.
       {"gl-context-set-current-stack-trace", kMediumSize},
-
-      // Accessibility keys. Temporary for http://crbug.com/765490.
-      {"ax_tree_error", kSmallSize},
-      {"ax_tree_update", kMediumSize},
   };
 
   // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index d40a8c0..db968758 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -630,11 +630,12 @@
         base::DIR_HOME, homedir, true, false);
   }
 
-  // If we are recovering from a crash on ChromeOS, then we will do some
-  // recovery using the diagnostics module, and then continue on. We fake up a
-  // command line to tell it that we want it to recover, and to preserve the
-  // original command line.
-  if (command_line.HasSwitch(chromeos::switches::kLoginUser) ||
+  // If we are recovering from a crash on a ChromeOS device, then we will do
+  // some recovery using the diagnostics module, and then continue on. We fake
+  // up a command line to tell it that we want it to recover, and to preserve
+  // the original command line. Note: logging at this point is to /var/log/ui.
+  if ((base::SysInfo::IsRunningOnChromeOS() &&
+       command_line.HasSwitch(chromeos::switches::kLoginUser)) ||
       command_line.HasSwitch(switches::kDiagnosticsRecovery)) {
     // The statistics subsystem needs get initialized soon enough for the
     // statistics to be collected.  It's safe to call this more than once.
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index d6802fe2..d9f303e 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -232,9 +232,6 @@
       <message name="IDS_ACCNAME_APP" desc="The accessible name for the app menu.">
         Chromium
       </message>
-      <message name="IDS_ACCNAME_TOOLBAR" desc="The accessible name for the application's toolbar.">
-        main
-      </message>
       <!-- Hung Browser Detector -->
       <if expr="is_win">
         <message name="IDS_BROWSER_HUNGBROWSER_MESSAGE" desc="Content of the dialog box shown when the browser is hung">
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index ee79ac8..145de8c9 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -242,9 +242,6 @@
       <message name="IDS_ACCNAME_APP" desc="The accessible name for the app menu.">
         Chrome
       </message>
-      <message name="IDS_ACCNAME_TOOLBAR" desc="The accessible name for the application's toolbar.">
-        main
-      </message>
       <!-- Hung Browser Detector -->
       <if expr="is_win">
         <message name="IDS_BROWSER_HUNGBROWSER_MESSAGE" desc="Content of the dialog box shown when the browser is hung">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 7a8e27e..65e53cc 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1650,7 +1650,6 @@
     "//components/payments/core",
     "//components/physical_web/eddystone",
     "//components/policy:generated",
-    "//components/policy/content/",
     "//components/policy/core/browser",
     "//components/policy/proto",
     "//components/prefs:prefs",
@@ -2037,6 +2036,8 @@
       "android/omnibox/omnibox_prerender.h",
       "android/oom_intervention/near_oom_monitor.cc",
       "android/oom_intervention/near_oom_monitor.h",
+      "android/oom_intervention/oom_intervention_decider.cc",
+      "android/oom_intervention/oom_intervention_decider.h",
       "android/oom_intervention/oom_intervention_tab_helper.cc",
       "android/oom_intervention/oom_intervention_tab_helper.h",
       "android/partner_browser_customizations.cc",
@@ -2561,8 +2562,13 @@
       "resource_coordinator/discard_reason.h",
       "resource_coordinator/lifecycle_unit.cc",
       "resource_coordinator/lifecycle_unit.h",
+      "resource_coordinator/lifecycle_unit_source.h",
+      "resource_coordinator/lifecycle_unit_source_base.cc",
+      "resource_coordinator/lifecycle_unit_source_base.h",
       "resource_coordinator/lifecycle_unit_source_observer.h",
       "resource_coordinator/tab_lifecycle_observer.h",
+      "resource_coordinator/tab_lifecycle_unit.cc",
+      "resource_coordinator/tab_lifecycle_unit.h",
       "resource_coordinator/tab_lifecycle_unit_external.cc",
       "resource_coordinator/tab_lifecycle_unit_external.h",
       "resource_coordinator/tab_manager.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index a36a42cc..fa9b104 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -16,7 +16,6 @@
   "+chrome_elf/dll_hash",
   "+chromeos",
   "+components",
-  "+components/policy/throttle/",
   "+content/public/browser",
   "+courgette",
   "+device/base",
@@ -135,6 +134,7 @@
   "+third_party/WebKit/public/platform/WebMouseWheelEvent.h",
   "+third_party/WebKit/public/platform/WebReferrerPolicy.h",
   "+third_party/WebKit/public/platform/WebSecurityStyle.h",
+  "+third_party/WebKit/public/platform/WebSuddenTerminationDisablerType.h",
   "+third_party/WebKit/public/platform/modules/notifications/WebNotificationConstants.h",
   "+third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h",
   "+third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 81348ea..c428c8a 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1877,6 +1877,10 @@
      flag_descriptions::kChromeHomeClearUrlOnOpenName,
      flag_descriptions::kChromeHomeClearUrlOnOpenDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kChromeHomeClearUrlOnOpen)},
+    {"enable-chrome-home-show-google-g",
+     flag_descriptions::kChromeHomeShowGoogleGName,
+     flag_descriptions::kChromeHomeShowGoogleGDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kChromeHomeShowGoogleGWhenUrlCleared)},
     {"enable-chrome-home-bottom-sheet-inactivity-expansion",
      flag_descriptions::kChromeHomeInactivitySheetExpansionName,
      flag_descriptions::kChromeHomeInactivitySheetExpansionDescription,
@@ -1901,6 +1905,10 @@
     {"enable-chrome-memex", flag_descriptions::kChromeMemexName,
      flag_descriptions::kChromeMemexDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kChromeMemexFeature)},
+    {"enable-chrome-home-survey",
+     flag_descriptions::kChromeHomeEnableSurveyName,
+     flag_descriptions::kChromeHomeEnableSurveyDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kChromeHomeSurvey)},
 #endif  // OS_ANDROID
 #if defined(OS_ANDROID)
     {"enable-tab-modal-js-dialog-android",
@@ -2281,10 +2289,6 @@
     {"offline-bookmarks", flag_descriptions::kOfflineBookmarksName,
      flag_descriptions::kOfflineBookmarksDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(offline_pages::kOfflineBookmarksFeature)},
-    {"offline-pages-async-download",
-     flag_descriptions::kOfflinePagesAsyncDownloadName,
-     flag_descriptions::kOfflinePagesAsyncDownloadDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(offline_pages::kOfflinePagesAsyncDownloadFeature)},
     {"offline-pages-load-signal-collecting",
      flag_descriptions::kOfflinePagesLoadSignalCollectingName,
      flag_descriptions::kOfflinePagesLoadSignalCollectingDescription,
@@ -3403,7 +3407,7 @@
      FEATURE_VALUE_TYPE(chrome::android::kPwaPersistentNotification)},
 #endif  // OS_ANDROID
 #if defined(OS_ANDROID)
-    {"view-passwords", flag_descriptions::kAndroidViewPasswordsName,
+    {"ViewPasswords", flag_descriptions::kAndroidViewPasswordsName,
      flag_descriptions::kAndroidViewPasswordsDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(password_manager::features::kViewPasswords)},
 #endif  // OS_ANDROID
@@ -3590,6 +3594,11 @@
 #endif  // defined(OS_WIN)
 
 #if defined(OS_CHROMEOS)
+    {"ash-enable-display-move-window-accels",
+     flag_descriptions::kAshEnableDisplayMoveWindowAccelsName,
+     flag_descriptions::kAshEnableDisplayMoveWindowAccelsDescription, kOsCrOS,
+     SINGLE_VALUE_TYPE(ash::switches::kAshEnableDisplayMoveWindowAccels)},
+
     {"ash-enable-keyboard-shortcut-viewer",
      flag_descriptions::kAshEnableKeyboardShortcutViewerName,
      flag_descriptions::kAshEnableKeyboardShortcutViewerDescription, kOsCrOS,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index e70c6db..9912616 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -73,6 +73,8 @@
     &kChromeHomePromoInfoOnly,
     &kChromeHomePromoOnStartup,
     &kChromeHomeOptOutSnackbar,
+    &kChromeHomeShowGoogleGWhenUrlCleared,
+    &kChromeHomeSurvey,
     &kChromeHomeSwipeLogic,
     &kChromeHomeSwipeLogicVelocity,
     &kChromeSmartSelection,
@@ -167,7 +169,7 @@
                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kAndroidSigninPromos{"AndroidSigninPromos",
-                                         base::FEATURE_DISABLED_BY_DEFAULT};
+                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kCCTBackgroundTab{"CCTBackgroundTab",
                                       base::FEATURE_ENABLED_BY_DEFAULT};
@@ -214,6 +216,12 @@
 const base::Feature kChromeHomeOptOutSnackbar{
     "ChromeHomeOptOutSnackbar", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kChromeHomeShowGoogleGWhenUrlCleared{
+    "ChromeHomeShowGoogleGWhenUrlCleared", base::FEATURE_DISABLED_BY_DEFAULT};
+
+const base::Feature kChromeHomeSurvey{"ChromeHomeSurvey",
+                                      base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kChromeHomeSwipeLogic{"ChromeHomeSwipeLogic",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index 53bb9c70..ceef8e6 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -33,6 +33,8 @@
 extern const base::Feature kChromeHomePromoInfoOnly;
 extern const base::Feature kChromeHomePromoOnStartup;
 extern const base::Feature kChromeHomeOptOutSnackbar;
+extern const base::Feature kChromeHomeShowGoogleGWhenUrlCleared;
+extern const base::Feature kChromeHomeSurvey;
 extern const base::Feature kChromeHomeSwipeLogic;
 extern const base::Feature kChromeHomeSwipeLogicVelocity;
 extern const base::Feature kChromeMemexFeature;
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_decider.cc b/chrome/browser/android/oom_intervention/oom_intervention_decider.cc
new file mode 100644
index 0000000..fea0aae
--- /dev/null
+++ b/chrome/browser/android/oom_intervention/oom_intervention_decider.cc
@@ -0,0 +1,175 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/oom_intervention/oom_intervention_decider.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/metrics/metrics_service.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/scoped_user_pref_update.h"
+
+namespace {
+
+const char kOomInterventionDecider[] = "oom_intervention.decider";
+
+// Pref path for blacklist. If a hostname is in the blacklist we never trigger
+// intervention on the host.
+const char kBlacklist[] = "oom_intervention.blacklist";
+// Pref path for declined host list. If a hostname is in the declined host list
+// we don't trigger intervention until a OOM crash happends on the host.
+const char kDeclinedHostList[] = "oom_intervention.declined_host_list";
+// Pref path for OOM detected host list. When an OOM crash is observed on
+// a host the hostname is added to the list.
+const char kOomDetectedHostList[] = "oom_intervention.oom_detected_host_list";
+
+class DelegateImpl : public OomInterventionDecider::Delegate {
+ public:
+  bool WasLastShutdownClean() override {
+    if (!g_browser_process || !g_browser_process->metrics_service())
+      return true;
+    return g_browser_process->metrics_service()->WasLastShutdownClean();
+  }
+};
+
+}  // namespace
+
+const size_t OomInterventionDecider::kMaxListSize = 10;
+const size_t OomInterventionDecider::kMaxBlacklistSize = 6;
+
+// static
+void OomInterventionDecider::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterListPref(kBlacklist);
+  registry->RegisterListPref(kDeclinedHostList);
+  registry->RegisterListPref(kOomDetectedHostList);
+}
+
+// static
+OomInterventionDecider* OomInterventionDecider::GetForBrowserContext(
+    content::BrowserContext* context) {
+  // The OomIntervetnionDecider is disabled in incognito mode because it is
+  // written in such a way that hostnames would be persisted in preferences on
+  // disk which is not acceptable for incognito mode.
+  if (context->IsOffTheRecord())
+    return nullptr;
+
+  if (!context->GetUserData(kOomInterventionDecider)) {
+    PrefService* prefs = Profile::FromBrowserContext(context)->GetPrefs();
+    context->SetUserData(kOomInterventionDecider,
+                         base::WrapUnique(new OomInterventionDecider(
+                             std::make_unique<DelegateImpl>(), prefs)));
+  }
+  return static_cast<OomInterventionDecider*>(
+      context->GetUserData(kOomInterventionDecider));
+}
+
+OomInterventionDecider::OomInterventionDecider(
+    std::unique_ptr<Delegate> delegate,
+    PrefService* prefs)
+    : delegate_(std::move(delegate)), prefs_(prefs) {
+  DCHECK(delegate_);
+
+  PrefService::PrefInitializationStatus pref_status =
+      prefs_->GetInitializationStatus();
+  if (pref_status == PrefService::INITIALIZATION_STATUS_WAITING) {
+    prefs_->AddPrefInitObserver(base::BindRepeating(
+        &OomInterventionDecider::OnPrefInitialized, base::Unretained(this)));
+  } else {
+    OnPrefInitialized(pref_status ==
+                      PrefService::INITIALIZATION_STATUS_SUCCESS);
+  }
+}
+
+OomInterventionDecider::~OomInterventionDecider() = default;
+
+bool OomInterventionDecider::CanTriggerIntervention(
+    const std::string& host) const {
+  if (IsOptedOut(host))
+    return false;
+
+  // Check whether OOM was observed before checking declined host list in favor
+  // of triggering intervention after OOM.
+  if (IsInList(kOomDetectedHostList, host))
+    return true;
+
+  if (IsInList(kDeclinedHostList, host))
+    return false;
+
+  return true;
+}
+
+void OomInterventionDecider::OnInterventionDeclined(const std::string& host) {
+  if (IsOptedOut(host))
+    return;
+
+  if (IsInList(kDeclinedHostList, host)) {
+    AddToList(kBlacklist, host);
+  } else {
+    AddToList(kDeclinedHostList, host);
+  }
+}
+
+void OomInterventionDecider::OnOomDetected(const std::string& host) {
+  if (IsOptedOut(host))
+    return;
+  AddToList(kOomDetectedHostList, host);
+}
+
+void OomInterventionDecider::ClearData() {
+  prefs_->ClearPref(kBlacklist);
+  prefs_->ClearPref(kDeclinedHostList);
+  prefs_->ClearPref(kOomDetectedHostList);
+}
+
+void OomInterventionDecider::OnPrefInitialized(bool success) {
+  if (!success)
+    return;
+
+  if (delegate_->WasLastShutdownClean())
+    return;
+
+  const base::Value::ListStorage& declined_list =
+      prefs_->GetList(kDeclinedHostList)->GetList();
+  if (declined_list.size() > 0) {
+    const std::string& last_declined =
+        declined_list[declined_list.size() - 1].GetString();
+    if (!IsInList(kBlacklist, last_declined))
+      AddToList(kOomDetectedHostList, last_declined);
+  }
+}
+
+bool OomInterventionDecider::IsOptedOut(const std::string& host) const {
+  const base::Value::ListStorage& blacklist =
+      prefs_->GetList(kBlacklist)->GetList();
+  if (blacklist.size() >= kMaxBlacklistSize)
+    return true;
+
+  return IsInList(kBlacklist, host);
+}
+
+bool OomInterventionDecider::IsInList(const char* list_name,
+                                      const std::string& host) const {
+  for (const auto& value : prefs_->GetList(list_name)->GetList()) {
+    if (value.GetString() == host)
+      return true;
+  }
+  return false;
+}
+
+void OomInterventionDecider::AddToList(const char* list_name,
+                                       const std::string& host) {
+  if (IsInList(list_name, host))
+    return;
+  ListPrefUpdate update(prefs_, list_name);
+  base::Value::ListStorage& list = update.Get()->GetList();
+  list.push_back(base::Value(host));
+  if (list.size() > kMaxListSize)
+    list.erase(list.begin());
+
+  // Save the list immediately because we typically modify lists under high
+  // memory pressure, in which the browser process can be killed by the OS
+  // soon.
+  prefs_->CommitPendingWrite();
+}
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_decider.h b/chrome/browser/android/oom_intervention/oom_intervention_decider.h
new file mode 100644
index 0000000..5c04550
--- /dev/null
+++ b/chrome/browser/android/oom_intervention/oom_intervention_decider.h
@@ -0,0 +1,86 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_DECIDER_H_
+#define CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_DECIDER_H_
+
+#include "base/gtest_prod_util.h"
+#include "base/supports_user_data.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+class OomInterventionDeciderTest;
+class PrefService;
+
+// This class contains triggering and opting-out logic for OOM intervention.
+// Opt-out logic:
+// - If user declined intervention, don't trigger it until OOM is observed on
+//   the same site.
+// - If user declined intervention again even after OOM is observed on the site,
+//   never trigger intervention on the site.
+// - If len(blacklist) > kMaxBlacklistSize, the user is permanently opted out.
+//
+// An instance of this class is associated with BrowserContext when the
+// BrowserContext isn't incognito. You can obtain it via GetForBrowserContext().
+// GetForBrowserContext() will return nullptr when in incognito mode.
+class OomInterventionDecider : public base::SupportsUserData::Data {
+ public:
+  // This delegate is a testing seam.
+  class Delegate {
+   public:
+    virtual ~Delegate() = default;
+    virtual bool WasLastShutdownClean() = 0;
+  };
+
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+  static OomInterventionDecider* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  ~OomInterventionDecider() override;
+
+  bool CanTriggerIntervention(const std::string& host) const;
+
+  void OnInterventionDeclined(const std::string& host);
+  void OnOomDetected(const std::string& host);
+
+  void ClearData();
+
+ private:
+  OomInterventionDecider(std::unique_ptr<Delegate> delegate,
+                         PrefService* prefs);
+
+  friend class OomInterventionDeciderTest;
+  FRIEND_TEST_ALL_PREFIXES(OomInterventionDeciderTest, OptOutSingleHost);
+  FRIEND_TEST_ALL_PREFIXES(OomInterventionDeciderTest, ParmanentlyOptOut);
+  FRIEND_TEST_ALL_PREFIXES(OomInterventionDeciderTest, WasLastShutdownClean);
+
+  // These constants are declared here for testing.
+  static const size_t kMaxListSize;
+  static const size_t kMaxBlacklistSize;
+
+  // Called when |prefs_| is ready to use. When the last shutdown wasn't clean,
+  // this method adds the last entry of the declined list to the OOM detected
+  // list, assuming that the site caused the crash and the crash was due to
+  // OOM.
+  void OnPrefInitialized(bool success);
+
+  bool IsOptedOut(const std::string& host) const;
+
+  bool IsInList(const char* list_name, const std::string& host) const;
+  void AddToList(const char* list_name, const std::string& host);
+
+  std::unique_ptr<Delegate> delegate_;
+  PrefService* prefs_;
+
+  DISALLOW_COPY_AND_ASSIGN(OomInterventionDecider);
+};
+
+#endif  // CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_DECIDER_H_
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_decider_unittest.cc b/chrome/browser/android/oom_intervention/oom_intervention_decider_unittest.cc
new file mode 100644
index 0000000..69006e6
--- /dev/null
+++ b/chrome/browser/android/oom_intervention/oom_intervention_decider_unittest.cc
@@ -0,0 +1,103 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/oom_intervention/oom_intervention_decider.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class MockInterventionDeciderDelegate
+    : public OomInterventionDecider::Delegate {
+ public:
+  explicit MockInterventionDeciderDelegate(bool was_clean)
+      : was_clean_(was_clean) {}
+  bool WasLastShutdownClean() override { return was_clean_; }
+
+ private:
+  bool was_clean_;
+};
+
+class OomInterventionDeciderTest : public testing::Test {
+ protected:
+  OomInterventionDeciderTest() {
+    OomInterventionDecider::RegisterProfilePrefs(prefs_.registry());
+  }
+
+  sync_preferences::TestingPrefServiceSyncable prefs_;
+};
+
+TEST_F(OomInterventionDeciderTest, OptOutSingleHost) {
+  std::string host = "www.example.com";
+
+  OomInterventionDecider decider(
+      std::make_unique<MockInterventionDeciderDelegate>(true), &prefs_);
+  decider.ClearData();
+
+  EXPECT_TRUE(decider.CanTriggerIntervention(host));
+  EXPECT_FALSE(decider.IsOptedOut(host));
+
+  decider.OnInterventionDeclined(host);
+  EXPECT_FALSE(decider.CanTriggerIntervention(host));
+  EXPECT_FALSE(decider.IsOptedOut(host));
+
+  decider.OnOomDetected(host);
+  EXPECT_TRUE(decider.CanTriggerIntervention(host));
+  EXPECT_FALSE(decider.IsOptedOut(host));
+
+  decider.OnInterventionDeclined(host);
+  EXPECT_FALSE(decider.CanTriggerIntervention(host));
+  EXPECT_TRUE(decider.IsOptedOut(host));
+}
+
+TEST_F(OomInterventionDeciderTest, ParmanentlyOptOut) {
+  OomInterventionDecider decider(
+      std::make_unique<MockInterventionDeciderDelegate>(true), &prefs_);
+  decider.ClearData();
+
+  std::string not_declined_host = "not_declined_host";
+  EXPECT_TRUE(decider.CanTriggerIntervention(not_declined_host));
+
+  // Put sufficient number of hosts into the blacklist.
+  for (size_t i = 0; i < OomInterventionDecider::kMaxBlacklistSize; ++i) {
+    std::string declined_host = "declined_host" + base::NumberToString(i);
+    decider.OnInterventionDeclined(declined_host);
+    decider.OnOomDetected(declined_host);
+    decider.OnInterventionDeclined(declined_host);
+  }
+
+  EXPECT_FALSE(decider.CanTriggerIntervention(not_declined_host));
+  EXPECT_TRUE(decider.IsOptedOut(not_declined_host));
+}
+
+TEST_F(OomInterventionDeciderTest, WasLastShutdownClean) {
+  std::string host = "www.example.com";
+
+  {
+    // Simulate a clean launch.
+    OomInterventionDecider decider(
+        std::make_unique<MockInterventionDeciderDelegate>(true), &prefs_);
+    decider.ClearData();
+
+    EXPECT_TRUE(decider.CanTriggerIntervention(host));
+
+    decider.OnInterventionDeclined(host);
+    EXPECT_FALSE(decider.CanTriggerIntervention(host));
+    EXPECT_FALSE(decider.IsOptedOut(host));
+  }
+
+  {
+    // Simulate a launch after a browser crash by passing a delegate which
+    // returns false when WasLastShutdownClean() is called. |host| will be
+    // considererd as a host which caused the crash (probably due to OOM).
+    OomInterventionDecider decider(
+        std::make_unique<MockInterventionDeciderDelegate>(false), &prefs_);
+
+    EXPECT_TRUE(decider.CanTriggerIntervention(host));
+
+    decider.OnInterventionDeclined(host);
+    EXPECT_FALSE(decider.CanTriggerIntervention(host));
+    EXPECT_TRUE(decider.IsOptedOut(host));
+  }
+}
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
index b78c601..aaffccad 100644
--- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
+++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
@@ -6,8 +6,10 @@
 
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
+#include "chrome/browser/android/oom_intervention/oom_intervention_decider.h"
 #include "chrome/browser/ui/android/infobars/near_oom_infobar.h"
 #include "chrome/common/chrome_features.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
@@ -69,7 +71,9 @@
 
 OomInterventionTabHelper::OomInterventionTabHelper(
     content::WebContents* web_contents)
-    : content::WebContentsObserver(web_contents) {
+    : content::WebContentsObserver(web_contents),
+      decider_(OomInterventionDecider::GetForBrowserContext(
+          web_contents->GetBrowserContext())) {
   OutOfMemoryReporter::FromWebContents(web_contents)->AddObserver(this);
 }
 
@@ -84,6 +88,12 @@
   RecordInterventionUserDecision(false);
   intervention_.reset();
   intervention_state_ = InterventionState::DECLINED;
+
+  if (decider_) {
+    DCHECK(!web_contents()->GetBrowserContext()->IsOffTheRecord());
+    const std::string& host = web_contents()->GetVisibleURL().host();
+    decider_->OnInterventionDeclined(host);
+  }
 }
 
 void OomInterventionTabHelper::WebContentsDestroyed() {
@@ -195,6 +205,12 @@
     RecordNearOomDetectionEndReason(
         NearOomDetectionEndReason::OOM_PROTECTED_CRASH);
   }
+
+  if (decider_) {
+    DCHECK(!web_contents()->GetBrowserContext()->IsOffTheRecord());
+    const std::string& host = web_contents()->GetVisibleURL().host();
+    decider_->OnOomDetected(host);
+  }
 }
 
 void OomInterventionTabHelper::StartMonitoringIfNeeded() {
@@ -218,7 +234,14 @@
   near_oom_detected_time_ = base::TimeTicks::Now();
   subscription_.reset();
 
-  if (RendererPauseIsEnabled()) {
+  bool trigger_intervention = RendererPauseIsEnabled();
+  if (trigger_intervention && decider_) {
+    DCHECK(!web_contents()->GetBrowserContext()->IsOffTheRecord());
+    const std::string& host = web_contents()->GetVisibleURL().host();
+    trigger_intervention = decider_->CanTriggerIntervention(host);
+  }
+
+  if (trigger_intervention) {
     content::RenderFrameHost* main_frame = web_contents()->GetMainFrame();
     DCHECK(main_frame);
     content::RenderProcessHost* render_process_host = main_frame->GetProcess();
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
index 7ee5e30e9..b19d0b2 100644
--- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
+++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
@@ -19,6 +19,8 @@
 class WebContents;
 }
 
+class OomInterventionDecider;
+
 // A tab helper for near-OOM intervention. This class depends on
 // OutOfMemoryReporter. OutOfMemoryReporter must be created on TabHelpers
 // before creating OomInterventionTabHelper.
@@ -68,6 +70,9 @@
   base::Optional<base::TimeTicks> near_oom_detected_time_;
   std::unique_ptr<NearOomMonitor::Subscription> subscription_;
 
+  // Not owned. This will be nullptr in incognito mode.
+  OomInterventionDecider* decider_;
+
   blink::mojom::OomInterventionPtr intervention_;
 
   enum class InterventionState {
diff --git a/chrome/browser/android/vr_shell/autocomplete_controller.cc b/chrome/browser/android/vr_shell/autocomplete_controller.cc
index 534c922..3498086 100644
--- a/chrome/browser/android/vr_shell/autocomplete_controller.cc
+++ b/chrome/browser/android/vr_shell/autocomplete_controller.cc
@@ -37,6 +37,7 @@
 
 void AutocompleteController::Stop() {
   autocomplete_controller_->Stop(true);
+  ui_->SetOmniboxSuggestions(base::MakeUnique<vr::OmniboxSuggestions>());
 }
 
 GURL AutocompleteController::GetUrlFromVoiceInput(const base::string16& input) {
diff --git a/chrome/browser/android/vr_shell/gvr_keyboard_delegate.cc b/chrome/browser/android/vr_shell/gvr_keyboard_delegate.cc
index a4467b3..fb05d30 100644
--- a/chrome/browser/android/vr_shell/gvr_keyboard_delegate.cc
+++ b/chrome/browser/android/vr_shell/gvr_keyboard_delegate.cc
@@ -57,10 +57,6 @@
     gvr_keyboard_destroy(&gvr_keyboard_);
 }
 
-void GvrKeyboardDelegate::SetController(VrController* controller) {
-  controller_ = controller;
-}
-
 void GvrKeyboardDelegate::SetUiInterface(vr::KeyboardUiInterface* ui) {
   ui_ = ui;
 }
@@ -69,14 +65,6 @@
   gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow();
   gvr_keyboard_set_frame_time(gvr_keyboard_, &target_time);
   gvr_keyboard_advance_frame(gvr_keyboard_);
-
-  if (controller_) {
-    bool pressed = controller_->ButtonUpHappened(
-        gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK);
-    gvr_keyboard_update_button_state(
-        gvr_keyboard_, gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK,
-        pressed);
-  }
 }
 
 void GvrKeyboardDelegate::ShowKeyboard() {
@@ -129,6 +117,16 @@
   gvr_keyboard_render(gvr_keyboard_, eye);
 }
 
+void GvrKeyboardDelegate::OnButtonDown(const gfx::PointF& position) {
+  gvr_keyboard_update_button_state(
+      gvr_keyboard_, gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK, true);
+}
+
+void GvrKeyboardDelegate::OnButtonUp(const gfx::PointF& position) {
+  gvr_keyboard_update_button_state(
+      gvr_keyboard_, gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK, false);
+}
+
 void GvrKeyboardDelegate::UpdateInput(const vr::TextInputInfo& info) {
   gvr_keyboard_set_text(gvr_keyboard_, base::UTF16ToUTF8(info.text).c_str());
   gvr_keyboard_set_selection_indices(gvr_keyboard_, info.selection_start,
diff --git a/chrome/browser/android/vr_shell/gvr_keyboard_delegate.h b/chrome/browser/android/vr_shell/gvr_keyboard_delegate.h
index 7a3ffeff..e447d6b 100644
--- a/chrome/browser/android/vr_shell/gvr_keyboard_delegate.h
+++ b/chrome/browser/android/vr_shell/gvr_keyboard_delegate.h
@@ -7,7 +7,6 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "chrome/browser/android/vr_shell/vr_controller.h"
 #include "chrome/browser/vr/keyboard_delegate.h"
 #include "chrome/browser/vr/keyboard_ui_interface.h"
 #include "third_party/gvr-android-keyboard/src/libraries/headers/vr/gvr/capi/include/gvr_keyboard.h"
@@ -25,7 +24,6 @@
   static std::unique_ptr<GvrKeyboardDelegate> Create();
   ~GvrKeyboardDelegate() override;
 
-  void SetController(VrController* controller);
   void SetUiInterface(vr::KeyboardUiInterface* ui);
 
   typedef int32_t EventType;
@@ -41,6 +39,9 @@
                gfx::Point3F* hit_position) override;
   void Draw(const vr::CameraModel& model) override;
 
+  void OnButtonDown(const gfx::PointF& position) override;
+  void OnButtonUp(const gfx::PointF& position) override;
+
   // Called to update GVR keyboard with the given text input info.
   void UpdateInput(const vr::TextInputInfo& info);
 
@@ -50,7 +51,6 @@
   void OnGvrKeyboardEvent(EventType);
   vr::TextInputInfo GetTextInfo();
 
-  VrController* controller_;
   vr::KeyboardUiInterface* ui_;
   gvr_keyboard_context* gvr_keyboard_ = nullptr;
   OnEventCallback keyboard_event_callback_;
diff --git a/chrome/browser/android/vr_shell/vr_controller.cc b/chrome/browser/android/vr_shell/vr_controller.cc
index 7268eaa..36348ec 100644
--- a/chrome/browser/android/vr_shell/vr_controller.cc
+++ b/chrome/browser/android/vr_shell/vr_controller.cc
@@ -28,10 +28,10 @@
 // If the user does not move outside of the slop, no gesture is detected.
 // Gestures start to be detected when the user moves outside of the slop.
 // Vertical distance from the border to the center of slop.
-constexpr float kSlopVertical = 0.165f;
+constexpr float kSlopVertical = 0.185f;
 
 // Horizontal distance from the border to the center of slop.
-constexpr float kSlopHorizontal = 0.15f;
+constexpr float kSlopHorizontal = 0.17f;
 
 // Minimum distance needed in at least one direction to call two vectors
 // not equal. Also, minimum time distance needed to call two timestamps
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc
index 6bf7d72c..a22c017 100644
--- a/chrome/browser/android/vr_shell/vr_gl_thread.cc
+++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -57,6 +57,8 @@
   if (keyboard_enabled) {
     text_input_delegate_->SetRequestFocusCallback(
         base::BindRepeating(&vr::Ui::RequestFocus, base::Unretained(ui.get())));
+    text_input_delegate_->SetRequestUnfocusCallback(base::BindRepeating(
+        &vr::Ui::RequestUnfocus, base::Unretained(ui.get())));
     if (keyboard_delegate) {
       keyboard_delegate_->SetUiInterface(ui.get());
       text_input_delegate_->SetUpdateInputCallback(
@@ -67,7 +69,7 @@
 
   vr_shell_gl_ = base::MakeUnique<VrShellGl>(
       this, std::move(ui), gvr_api_, reprojected_rendering_, daydream_support_,
-      ui_initial_state_.in_web_vr, keyboard_delegate_.get());
+      ui_initial_state_.in_web_vr);
 
   browser_ui_ = vr_shell_gl_->GetBrowserUiWeakPtr();
 
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc
index 435c217..d906196 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.cc
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -162,8 +162,7 @@
                      gvr_context* gvr_api,
                      bool reprojected_rendering,
                      bool daydream_support,
-                     bool start_in_web_vr_mode,
-                     GvrKeyboardDelegate* keyboard_delegate)
+                     bool start_in_web_vr_mode)
     : ui_(std::move(ui)),
       web_vr_mode_(start_in_web_vr_mode),
       surfaceless_rendering_(reprojected_rendering),
@@ -171,7 +170,6 @@
       task_runner_(base::ThreadTaskRunnerHandle::Get()),
       binding_(this),
       browser_(browser_interface),
-      keyboard_delegate_(keyboard_delegate),
       fps_meter_(),
       webvr_js_time_(kWebVRSlidingAverageSize),
       webvr_render_time_(kWebVRSlidingAverageSize),
@@ -456,8 +454,6 @@
   gvr_api_ = gvr::GvrApi::WrapNonOwned(gvr_api);
   controller_.reset(new VrController(gvr_api));
   ui_->OnPlatformControllerInitialized(controller_.get());
-  if (keyboard_delegate_)
-    keyboard_delegate_->SetController(controller_.get());
 
   VrMetricsUtil::LogVrViewerType(gvr_api_->GetViewerType());
 
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h
index caa34a48..d75d144 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.h
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -16,7 +16,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "chrome/browser/android/vr_shell/android_vsync_helper.h"
-#include "chrome/browser/android/vr_shell/gvr_keyboard_delegate.h"
 #include "chrome/browser/android/vr_shell/vr_controller.h"
 #include "chrome/browser/vr/content_input_delegate.h"
 #include "chrome/browser/vr/controller_mesh.h"
@@ -83,8 +82,7 @@
             gvr_context* gvr_api,
             bool reprojected_rendering,
             bool daydream_support,
-            bool start_in_web_vr_mode,
-            GvrKeyboardDelegate* keyboard_delegate);
+            bool start_in_web_vr_mode);
   ~VrShellGl() override;
 
   void Initialize();
@@ -244,7 +242,6 @@
   device::mojom::VRSubmitFrameClientPtr submit_client_;
 
   GlBrowserInterface* browser_;
-  GvrKeyboardDelegate* keyboard_delegate_;
 
   uint8_t frame_index_ = 0;
   // Larger than frame_index_ so it can be initialized out-of-band.
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index a92ae57e..fc8c67f 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -20,6 +20,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "chrome/browser/autofill/autofill_uitest_util.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
@@ -51,7 +52,6 @@
 
 using base::ASCIIToUTF16;
 using base::UTF16ToASCII;
-using base::WideToUTF16;
 
 namespace autofill {
 
@@ -126,30 +126,6 @@
     return PersonalDataManagerFactory::GetForProfile(browser()->profile());
   }
 
-  void SetProfiles(std::vector<AutofillProfile>* profiles) {
-    WindowedPersonalDataManagerObserver observer(browser());
-    personal_data_manager()->SetProfiles(profiles);
-    observer.Wait();
-  }
-
-  void SetProfile(const AutofillProfile& profile) {
-    std::vector<AutofillProfile> profiles;
-    profiles.push_back(profile);
-    SetProfiles(&profiles);
-  }
-
-  void SetCards(std::vector<CreditCard>* cards) {
-    WindowedPersonalDataManagerObserver observer(browser());
-    personal_data_manager()->SetCreditCards(cards);
-    observer.Wait();
-  }
-
-  void SetCard(const CreditCard& card) {
-    std::vector<CreditCard> cards;
-    cards.push_back(card);
-    SetCards(&cards);
-  }
-
   typedef std::map<std::string, std::string> FormMap;
 
   // Helper function to obtain the Javascript required to update a form.
@@ -252,206 +228,6 @@
   net::TestURLFetcherFactory url_fetcher_factory_;
 };
 
-// Test filling profiles with unicode strings and crazy characters.
-// TODO(isherman): rewrite as unit test under PersonalDataManagerTest.
-IN_PROC_BROWSER_TEST_F(AutofillTest, FillProfileCrazyCharacters) {
-  std::vector<AutofillProfile> profiles;
-  AutofillProfile profile1;
-  profile1.SetRawInfo(NAME_FIRST,
-                      WideToUTF16(L"\u0623\u0648\u0628\u0627\u0645\u0627 "
-                                  L"\u064a\u0639\u062a\u0630\u0631 "
-                                  L"\u0647\u0627\u062a\u0641\u064a\u0627 "
-                                  L"\u0644\u0645\u0648\u0638\u0641\u0629 "
-                                  L"\u0633\u0648\u062f\u0627\u0621 "
-                                  L"\u0627\u0633\u062a\u0642\u0627\u0644\u062a "
-                                  L"\u0628\u0633\u0628\u0628 "
-                                  L"\u062a\u0635\u0631\u064a\u062d\u0627\u062a "
-                                  L"\u0645\u062c\u062a\u0632\u0623\u0629"));
-  profile1.SetRawInfo(NAME_MIDDLE, WideToUTF16(L"BANK\xcBERF\xc4LLE"));
-  profile1.SetRawInfo(EMAIL_ADDRESS,
-                      WideToUTF16(L"\uacbd\uc81c \ub274\uc2a4 "
-                                  L"\ub354\ubcf4\uae30@google.com"));
-  profile1.SetRawInfo(ADDRESS_HOME_LINE1,
-                      WideToUTF16(L"\uad6d\uc815\uc6d0\xb7\uac80\ucc30, "
-                                  L"\ub178\ubb34\ud604\uc815\ubd80 "
-                                  L"\ub300\ubd81\uc811\ucd09 \ub2f4\ub2f9 "
-                                  L"\uc778\uc0ac\ub4e4 \uc870\uc0ac"));
-  profile1.SetRawInfo(ADDRESS_HOME_CITY,
-                      WideToUTF16(L"\u653f\u5e9c\u4e0d\u6392\u9664\u7acb\u6cd5"
-                                  L"\u898f\u7ba1\u5c0e\u904a"));
-  profile1.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"YOHO_54676"));
-  profile1.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, WideToUTF16(L"861088828000"));
-  profile1.SetInfo(
-      AutofillType(ADDRESS_HOME_COUNTRY), WideToUTF16(L"India"), "en-US");
-  profiles.push_back(profile1);
-
-  AutofillProfile profile2;
-  profile2.SetRawInfo(NAME_FIRST,
-                      WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a "
-                                  L"\u677e\u9690\u9547\u4ead\u67ab\u516c"
-                                  L"\u8def1915\u53f7"));
-  profile2.SetRawInfo(NAME_LAST, WideToUTF16(L"aguantó"));
-  profile2.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"HOME 94043"));
-  profiles.push_back(profile2);
-
-  AutofillProfile profile3;
-  profile3.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"sue@example.com"));
-  profile3.SetRawInfo(COMPANY_NAME, WideToUTF16(L"Company X"));
-  profiles.push_back(profile3);
-
-  AutofillProfile profile4;
-  profile4.SetRawInfo(NAME_FIRST, WideToUTF16(L"Joe 3254"));
-  profile4.SetRawInfo(NAME_LAST, WideToUTF16(L"\u8bb0\u8d262\u5e74\u591a"));
-  profile4.SetRawInfo(ADDRESS_HOME_ZIP,
-                      WideToUTF16(L"\uff08\u90ae\u7f16\uff1a201504\uff09"));
-  profile4.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"télévision@example.com"));
-  profile4.SetRawInfo(COMPANY_NAME,
-                      WideToUTF16(L"\u0907\u0932\u0947\u0915\u093f\u091f\u094d"
-                                  L"\u0930\u0928\u093f\u0915\u094d\u0938, "
-                                  L"\u0905\u092a\u094b\u0932\u094b "
-                                  L"\u091f\u093e\u092f\u0930\u094d\u0938 "
-                                  L"\u0906\u0926\u093f"));
-  profiles.push_back(profile4);
-
-  AutofillProfile profile5;
-  profile5.SetRawInfo(NAME_FIRST, WideToUTF16(L"Larry"));
-  profile5.SetRawInfo(NAME_LAST,
-                      WideToUTF16(L"\u0938\u094d\u091f\u093e\u0902\u092a "
-                                  L"\u0921\u094d\u092f\u0942\u091f\u0940"));
-  profile5.SetRawInfo(ADDRESS_HOME_ZIP,
-                      WideToUTF16(L"111111111111110000GOOGLE"));
-  profile5.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"page@000000.com"));
-  profile5.SetRawInfo(COMPANY_NAME, WideToUTF16(L"Google"));
-  profiles.push_back(profile5);
-
-  AutofillProfile profile6;
-  profile6.SetRawInfo(NAME_FIRST,
-                      WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a "
-                                  L"\u677e\u9690\u9547\u4ead\u67ab\u516c"
-                                  L"\u8def1915\u53f7"));
-  profile6.SetRawInfo(NAME_LAST,
-                      WideToUTF16(L"\u0646\u062c\u0627\u0645\u064a\u0646\u0627 "
-                                  L"\u062f\u0639\u0645\u0647\u0627 "
-                                  L"\u0644\u0644\u0631\u0626\u064a\u0633 "
-                                  L"\u0627\u0644\u0633\u0648\u062f\u0627\u0646"
-                                  L"\u064a \u0639\u0645\u0631 "
-                                  L"\u0627\u0644\u0628\u0634\u064a\u0631"));
-  profile6.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"HOME 94043"));
-  profiles.push_back(profile6);
-
-  AutofillProfile profile7;
-  profile7.SetRawInfo(NAME_FIRST, WideToUTF16(L"&$%$$$ TESTO *&*&^&^& MOKO"));
-  profile7.SetRawInfo(NAME_MIDDLE, WideToUTF16(L"WOHOOOO$$$$$$$$****"));
-  profile7.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"yuvu@example.com"));
-  profile7.SetRawInfo(ADDRESS_HOME_LINE1,
-                      WideToUTF16(L"34544, anderson ST.(120230)"));
-  profile7.SetRawInfo(ADDRESS_HOME_CITY, WideToUTF16(L"Sunnyvale"));
-  profile7.SetRawInfo(ADDRESS_HOME_STATE, WideToUTF16(L"CA"));
-  profile7.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"94086"));
-  profile7.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, WideToUTF16(L"15466784565"));
-  profile7.SetInfo(
-      AutofillType(ADDRESS_HOME_COUNTRY), WideToUTF16(L"United States"),
-      "en-US");
-  profiles.push_back(profile7);
-
-  SetProfiles(&profiles);
-  ASSERT_EQ(profiles.size(), personal_data_manager()->GetProfiles().size());
-  for (size_t i = 0; i < profiles.size(); ++i) {
-    EXPECT_TRUE(base::ContainsValue(
-        profiles, *personal_data_manager()->GetProfiles()[i]));
-  }
-
-  std::vector<CreditCard> cards;
-  CreditCard card1;
-  card1.SetRawInfo(CREDIT_CARD_NAME_FULL,
-                   WideToUTF16(L"\u751f\u6d3b\u5f88\u6709\u89c4\u5f8b "
-                               L"\u4ee5\u73a9\u4e3a\u4e3b"));
-  card1.SetRawInfo(CREDIT_CARD_NUMBER, WideToUTF16(L"6011111111111117"));
-  card1.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"12"));
-  card1.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2011"));
-  cards.push_back(card1);
-
-  CreditCard card2;
-  card2.SetRawInfo(CREDIT_CARD_NAME_FULL, WideToUTF16(L"John Williams"));
-  card2.SetRawInfo(CREDIT_CARD_NUMBER, WideToUTF16(L"WokoAwesome12345"));
-  card2.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"10"));
-  card2.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2015"));
-  cards.push_back(card2);
-
-  CreditCard card3;
-  card3.SetRawInfo(CREDIT_CARD_NAME_FULL,
-                   WideToUTF16(L"\u0623\u062d\u0645\u062f\u064a "
-                               L"\u0646\u062c\u0627\u062f "
-                               L"\u0644\u0645\u062d\u0627\u0648\u0644\u0647 "
-                               L"\u0627\u063a\u062a\u064a\u0627\u0644 "
-                               L"\u0641\u064a \u0645\u062f\u064a\u0646\u0629 "
-                               L"\u0647\u0645\u062f\u0627\u0646 "));
-  card3.SetRawInfo(CREDIT_CARD_NUMBER,
-                   WideToUTF16(L"\u092a\u0941\u0928\u0930\u094d\u091c\u0940"
-                               L"\u0935\u093f\u0924 \u0939\u094b\u0917\u093e "
-                               L"\u0928\u093e\u0932\u0902\u0926\u093e"));
-  card3.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"10"));
-  card3.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2015"));
-  cards.push_back(card3);
-
-  CreditCard card4;
-  card4.SetRawInfo(CREDIT_CARD_NAME_FULL,
-                   WideToUTF16(L"\u039d\u03ad\u03b5\u03c2 "
-                               L"\u03c3\u03c5\u03b3\u03c7\u03c9\u03bd\u03b5"
-                               L"\u03cd\u03c3\u03b5\u03b9\u03c2 "
-                               L"\u03ba\u03b1\u03b9 "
-                               L"\u03ba\u03b1\u03c4\u03b1\u03c1\u03b3\u03ae"
-                               L"\u03c3\u03b5\u03b9\u03c2"));
-  card4.SetRawInfo(CREDIT_CARD_NUMBER, WideToUTF16(L"00000000000000000000000"));
-  card4.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"01"));
-  card4.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2016"));
-  cards.push_back(card4);
-
-  SetCards(&cards);
-  ASSERT_EQ(cards.size(), personal_data_manager()->GetCreditCards().size());
-  for (size_t i = 0; i < cards.size(); ++i) {
-    EXPECT_TRUE(base::ContainsValue(
-        cards, *personal_data_manager()->GetCreditCards()[i]));
-  }
-}
-
-// Test filling in invalid values for profiles are saved as-is. Phone
-// information entered into the prefs UI is not validated or rejected except for
-// duplicates.
-// TODO(isherman): rewrite as WebUI test?
-IN_PROC_BROWSER_TEST_F(AutofillTest, Invalid) {
-  // First try profiles with invalid ZIP input.
-  AutofillProfile without_invalid;
-  without_invalid.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Will"));
-  without_invalid.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Sunnyvale"));
-  without_invalid.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA"));
-  without_invalid.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("my_zip"));
-  without_invalid.SetInfo(
-      AutofillType(ADDRESS_HOME_COUNTRY), ASCIIToUTF16("United States"),
-      "en-US");
-
-  AutofillProfile with_invalid = without_invalid;
-  with_invalid.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
-                          ASCIIToUTF16("Invalid_Phone_Number"));
-  SetProfile(with_invalid);
-
-  ASSERT_EQ(1u, personal_data_manager()->GetProfiles().size());
-  AutofillProfile profile = *personal_data_manager()->GetProfiles()[0];
-  ASSERT_NE(without_invalid.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
-            profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
-}
-
-// Test invalid credit card numbers typed in prefs should be saved as-is.
-// TODO(isherman): rewrite as WebUI test?
-IN_PROC_BROWSER_TEST_F(AutofillTest, PrefsStringSavedAsIs) {
-  CreditCard card;
-  card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("Not_0123-5Checked"));
-  SetCard(card);
-
-  ASSERT_EQ(1u, personal_data_manager()->GetCreditCards().size());
-  ASSERT_EQ(card, *personal_data_manager()->GetCreditCards()[0]);
-}
-
 // Test that Autofill aggregates a minimum valid profile.
 // The minimum required address fields must be specified: First Name, Last Name,
 // Address Line 1, City, Zip Code, and State.
diff --git a/chrome/browser/autofill/autofill_metrics_browsertest.cc b/chrome/browser/autofill/autofill_metrics_browsertest.cc
index eb715d0..c995edf 100644
--- a/chrome/browser/autofill/autofill_metrics_browsertest.cc
+++ b/chrome/browser/autofill/autofill_metrics_browsertest.cc
@@ -87,7 +87,7 @@
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
   for (const auto& kv : test_ukm_recorder_->GetSources()) {
-    EXPECT_NE(iframe_url, kv.second->url());
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
   }
 }
 
@@ -110,7 +110,79 @@
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
   for (const auto& kv : test_ukm_recorder_->GetSources()) {
-    EXPECT_NE(iframe_url, kv.second->url());
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(AutofillMetricsMetricsBrowserTest,
+                       CorrectSourceForUnownedAddressCheckout) {
+  GURL main_frame_url =
+      https_server_->GetURL("a.com", "/autofill_unowned_address_checkout.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  // Make sure the UKM were logged for the main frame url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_EQ(main_frame_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(AutofillMetricsMetricsBrowserTest,
+                       CorrectSourceForUnownedCreditCardCheckout) {
+  GURL main_frame_url = https_server_->GetURL(
+      "a.com", "/autofill_unowned_credit_card_checkout.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  // Make sure the UKM were logged for the main frame url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_EQ(main_frame_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(
+    AutofillMetricsMetricsBrowserTest,
+    CorrectSourceForCrossSiteEmbeddedUnownedAddressCheckout) {
+  GURL main_frame_url =
+      https_server_->GetURL("a.com", "/autofill_iframe_embedder.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  GURL iframe_url =
+      https_server_->GetURL("b.com", "/autofill_unowned_address_checkout.html");
+  EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
+
+  EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  EXPECT_TRUE(frame);
+
+  // Make sure the UKM were logged for the main frame url and none for the
+  // iframe url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(
+    AutofillMetricsMetricsBrowserTest,
+    CorrectSourceForCrossSiteEmbeddedUnownedCreditCardCheckout) {
+  GURL main_frame_url =
+      https_server_->GetURL("a.com", "/autofill_iframe_embedder.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  GURL iframe_url = https_server_->GetURL(
+      "b.com", "/autofill_unowned_credit_card_checkout.html");
+  EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
+
+  EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  EXPECT_TRUE(frame);
+
+  // Make sure the UKM were logged for the main frame url and none for the
+  // iframe url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
   }
 }
 
@@ -153,7 +225,7 @@
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
   for (const auto& kv : test_ukm_recorder_->GetSources()) {
-    EXPECT_NE(iframe_url, kv.second->url());
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
   }
 }
 
@@ -177,6 +249,80 @@
   // Make sure the UKM were logged for the main frame url and none for the
   // iframe url.
   for (const auto& kv : test_ukm_recorder_->GetSources()) {
-    EXPECT_NE(iframe_url, kv.second->url());
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(SitePerProcessAutofillMetricsMetricsBrowserTest,
+                       CorrectSourceForUnownedAddressCheckout) {
+  GURL main_frame_url =
+      https_server_->GetURL("a.com", "/autofill_unowned_address_checkout.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  // Make sure the UKM were logged for the main frame url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_EQ(main_frame_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(SitePerProcessAutofillMetricsMetricsBrowserTest,
+                       CorrectSourceForUnownedCreditCardCheckout) {
+  GURL main_frame_url = https_server_->GetURL(
+      "a.com", "/autofill_unowned_credit_card_checkout.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  // Make sure the UKM were logged for the main frame url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_EQ(main_frame_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(
+    SitePerProcessAutofillMetricsMetricsBrowserTest,
+    CorrectSourceForCrossSiteEmbeddedUnownedAddressCheckout) {
+  GURL main_frame_url =
+      https_server_->GetURL("a.com", "/autofill_iframe_embedder.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  GURL iframe_url =
+      https_server_->GetURL("b.com", "/autofill_unowned_address_checkout.html");
+  EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
+
+  EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  EXPECT_TRUE(frame);
+  EXPECT_NE(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+
+  // Make sure the UKM were logged for the main frame url and none for the
+  // iframe url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(
+    SitePerProcessAutofillMetricsMetricsBrowserTest,
+    CorrectSourceForCrossSiteEmbeddedUnownedCreditCardCheckout) {
+  GURL main_frame_url =
+      https_server_->GetURL("a.com", "/autofill_iframe_embedder.html");
+  ui_test_utils::NavigateToURL(browser(), main_frame_url);
+
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  GURL iframe_url = https_server_->GetURL(
+      "b.com", "/autofill_unowned_credit_card_checkout.html");
+  EXPECT_TRUE(content::NavigateIframeToURL(tab, "test", iframe_url));
+
+  EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
+  content::RenderFrameHost* frame = ChildFrameAt(tab->GetMainFrame(), 0);
+  EXPECT_TRUE(frame);
+  EXPECT_NE(frame->GetSiteInstance(), tab->GetMainFrame()->GetSiteInstance());
+
+  // Make sure the UKM were logged for the main frame url and none for the
+  // iframe url.
+  for (const auto& kv : test_ukm_recorder_->GetSources()) {
+    EXPECT_NE(iframe_url.host(), kv.second->url().host());
   }
 }
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index 77443dea..2f223ff 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -89,6 +89,7 @@
 #include "url/url_util.h"
 
 #if defined(OS_ANDROID)
+#include "chrome/browser/android/oom_intervention/oom_intervention_decider.h"
 #include "chrome/browser/android/search_permissions/search_permissions_service.h"
 #include "chrome/browser/android/webapps/webapp_registry.h"
 #include "chrome/browser/media/android/cdm/media_drm_license_manager.h"
@@ -668,6 +669,13 @@
                                                               delete_end_);
     }
 
+#if defined(OS_ANDROID)
+    OomInterventionDecider* oom_intervention_decider =
+        OomInterventionDecider::GetForBrowserContext(profile_);
+    if (oom_intervention_decider)
+      oom_intervention_decider->ClearData();
+#endif
+
     // The SSL Host State that tracks SSL interstitial "proceed" decisions may
     // include origins that the user has visited, so it must be cleared.
     // TODO(msramek): We can reuse the plugin filter here, since both plugins
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 188e23a..4ae3b24 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -157,7 +157,6 @@
 #include "components/net_log/chrome_net_log.h"
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 #include "components/patch_service/public/interfaces/constants.mojom.h"
-#include "components/policy/content/policy_blacklist_navigation_throttle.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -3549,9 +3548,6 @@
   if (tab_under_throttle)
     throttles.push_back(std::move(tab_under_throttle));
 
-  throttles.push_back(base::MakeUnique<PolicyBlacklistNavigationThrottle>(
-      handle, handle->GetWebContents()->GetBrowserContext()));
-
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kCommittedInterstitials)) {
     throttles.push_back(std::make_unique<SSLErrorNavigationThrottle>(
diff --git a/chrome/browser/chrome_network_service_restart_browsertest.cc b/chrome/browser/chrome_network_service_restart_browsertest.cc
new file mode 100644
index 0000000..d6e1264
--- /dev/null
+++ b/chrome/browser/chrome_network_service_restart_browsertest.cc
@@ -0,0 +1,130 @@
+// 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/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/net/system_network_context_manager.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/network_service_test.mojom.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/simple_url_loader_test_helper.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace content {
+
+// |ChromeNetworkServiceRestartBrowserTest| is required to test Chrome specific
+// code such as |ChromeContentBrowserClient|.
+// See |NetworkServiceRestartBrowserTest| for content's version of tests.
+class ChromeNetworkServiceRestartBrowserTest : public InProcessBrowserTest {
+ public:
+  ChromeNetworkServiceRestartBrowserTest() {
+    scoped_feature_list_.InitAndEnableFeature(features::kNetworkService);
+    EXPECT_TRUE(embedded_test_server()->Start());
+  }
+
+  void SimulateNetworkServiceCrash() {
+    mojom::NetworkServiceTestPtr network_service_test;
+    ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
+        mojom::kNetworkServiceName, &network_service_test);
+
+    base::RunLoop run_loop;
+    network_service_test.set_connection_error_handler(run_loop.QuitClosure());
+
+    network_service_test->SimulateCrash();
+    run_loop.Run();
+  }
+
+  int LoadBasicRequest(mojom::NetworkContext* network_context) {
+    mojom::URLLoaderFactoryPtr url_loader_factory;
+    network_context->CreateURLLoaderFactory(MakeRequest(&url_loader_factory),
+                                            0);
+
+    auto request = std::make_unique<ResourceRequest>();
+    // Use '/echoheader' instead of '/echo' to avoid a disk_cache bug.
+    // See https://crbug.com/792255.
+    request->url = embedded_test_server()->GetURL("/echoheader");
+
+    content::SimpleURLLoaderTestHelper simple_loader_helper;
+    std::unique_ptr<content::SimpleURLLoader> simple_loader =
+        content::SimpleURLLoader::Create(std::move(request),
+                                         TRAFFIC_ANNOTATION_FOR_TESTS);
+
+    simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+        url_loader_factory.get(), simple_loader_helper.GetCallback());
+    simple_loader_helper.WaitForCallback();
+
+    return simple_loader->NetError();
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeNetworkServiceRestartBrowserTest);
+};
+
+// Make sure |StoragePartition::GetNetworkContext()| returns valid interface
+// after crash.
+IN_PROC_BROWSER_TEST_F(ChromeNetworkServiceRestartBrowserTest,
+                       StoragePartitionGetNetworkContext) {
+#if defined(OS_MACOSX)
+  // |NetworkServiceTestHelper| doesn't work on browser_tests on macOS.
+  return;
+#endif
+  StoragePartition* partition =
+      BrowserContext::GetDefaultStoragePartition(browser()->profile());
+
+  mojom::NetworkContext* old_network_context = partition->GetNetworkContext();
+  EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context));
+
+  // Crash the NetworkService process. Existing interfaces should receive error
+  // notifications at some point.
+  SimulateNetworkServiceCrash();
+  // Flush the interface to make sure the error notification was received.
+  partition->FlushNetworkInterfaceForTesting();
+
+  // |partition->GetNetworkContext()| should return a valid new pointer after
+  // crash.
+  EXPECT_NE(old_network_context, partition->GetNetworkContext());
+  EXPECT_EQ(net::OK, LoadBasicRequest(partition->GetNetworkContext()));
+}
+
+// Make sure |SystemNetworkContextManager::GetContext()| returns valid interface
+// after crash.
+IN_PROC_BROWSER_TEST_F(ChromeNetworkServiceRestartBrowserTest,
+                       SystemNetworkContextManagerGetContext) {
+#if defined(OS_MACOSX)
+  // |NetworkServiceTestHelper| doesn't work on browser_tests on macOS.
+  return;
+#endif
+  SystemNetworkContextManager* system_network_context_manager =
+      g_browser_process->system_network_context_manager();
+
+  mojom::NetworkContext* old_network_context =
+      system_network_context_manager->GetContext();
+  EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context));
+
+  // Crash the NetworkService process. Existing interfaces should receive error
+  // notifications at some point.
+  SimulateNetworkServiceCrash();
+  // Flush the interface to make sure the error notification was received.
+  system_network_context_manager->FlushNetworkInterfaceForTesting();
+
+  // |system_network_context_manager->GetContext()| should return a valid new
+  // pointer after crash.
+  EXPECT_NE(old_network_context, system_network_context_manager->GetContext());
+  EXPECT_EQ(net::OK,
+            LoadBasicRequest(system_network_context_manager->GetContext()));
+}
+
+}  // namespace content
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 1b9a60fd..946939e 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -119,6 +119,7 @@
     "//components/sync_wifi",
     "//components/toolbar",
     "//components/tracing:startup_tracing",
+    "//components/ukm/content",
     "//components/user_manager",
     "//services/metrics/public/cpp:ukm_builders",
     "//third_party/fontconfig",
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.cc b/chrome/browser/chromeos/arc/arc_session_manager.cc
index 3cd7adb..643145e 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager.cc
@@ -42,6 +42,7 @@
 #include "components/arc/arc_prefs.h"
 #include "components/arc/arc_session_runner.h"
 #include "components/arc/arc_util.h"
+#include "components/arc/metrics/arc_metrics_service.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_thread.h"
 #include "ui/display/types/display_constants.h"
@@ -539,8 +540,14 @@
 void ArcSessionManager::RecordArcState() {
   // Only record Enabled state if ARC is allowed in the first place, so we do
   // not split the ARC population by devices that cannot run ARC.
-  if (IsAllowed())
-    UpdateEnabledStateUMA(enable_requested_);
+  if (!IsAllowed())
+    return;
+
+  UpdateEnabledStateUMA(enable_requested_);
+
+  ArcMetricsService* service =
+      ArcMetricsService::GetForBrowserContext(profile_);
+  service->RecordNativeBridgeUMA();
 }
 
 void ArcSessionManager::RequestEnable() {
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.h b/chrome/browser/chromeos/arc/arc_session_manager.h
index 0ff567a..647b830b 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager.h
+++ b/chrome/browser/chromeos/arc/arc_session_manager.h
@@ -194,8 +194,10 @@
   // this.
   void RequestArcDataRemoval();
 
-  // Called from the Chrome OS metrics provider to record Arc.State
-  // periodically.
+  // Called from the Chrome OS metrics provider to record Arc.State and similar
+  // values strictly once per every metrics recording interval. This way they
+  // are in every record uploaded to the server and therefore can be used to
+  // split and compare analysis data for all other metrics.
   void RecordArcState();
 
   // ArcSupportHost:::ErrorDelegate:
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
index d6cc373..8883712 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -131,7 +131,6 @@
   void StartAppLaunch(const std::string& app_id,
                       bool diagnostic_mode,
                       bool is_auto_launch) override {}
-  void StartDemoAppLaunch() override {}
   void StartArcKiosk(const AccountId& account_id) override {}
   void StartVoiceInteractionOobe() override {
     is_voice_interaction_oobe_ = true;
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
index eb4b2a0..8fa50ca 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -227,7 +227,7 @@
   EXPECT_FALSE(auth_instance.account_info()->enrollment_token);
   EXPECT_FALSE(auth_instance.account_info()->is_managed);
 
-  arc_bridge_service->auth()->SetInstance(nullptr, 0);
+  arc_bridge_service->auth()->CloseInstance(&auth_instance);
 }
 
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
index d767b690..6989339 100644
--- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
+++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
@@ -106,7 +106,9 @@
   }
 
   void TearDown() override {
-    arc_bridge_service_->bluetooth()->SetInstance(nullptr, 0);
+    arc_bridge_service_->bluetooth()->CloseInstance(
+        fake_bluetooth_instance_.get());
+    fake_bluetooth_instance_.reset();
     arc_bluetooth_bridge_.reset();
     arc_bridge_service_.reset();
   }
diff --git a/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc b/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc
index b6561d3..46c9eec 100644
--- a/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc
+++ b/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc
@@ -140,7 +140,7 @@
 
   void TearDownOnMainThread() override {
     ASSERT_TRUE(arc_bridge());
-    arc_bridge()->cert_store()->SetInstance(nullptr, 0);
+    arc_bridge()->cert_store()->CloseInstance(instance_.get());
     instance_.reset();
 
     // Since ArcServiceLauncher is (re-)set up with profile() in
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc
index 6969b57..b032282a 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc
@@ -64,8 +64,8 @@
   }
 
   void TearDown() override {
-    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
-        nullptr, 0);
+    arc_service_manager_->arc_bridge_service()->file_system()->CloseInstance(
+        &fake_file_system_);
   }
 
  protected:
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
index 940e1f3..c0ed171 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
@@ -89,8 +89,8 @@
   }
 
   void TearDown() override {
-    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
-        nullptr, 0);
+    arc_service_manager_->arc_bridge_service()->file_system()->CloseInstance(
+        &fake_file_system_);
   }
 
  private:
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
index 3448826..86bcea5 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
@@ -144,8 +144,8 @@
 
   void TearDown() override {
     root_.reset();
-    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
-        nullptr);
+    arc_service_manager_->arc_bridge_service()->file_system()->CloseInstance(
+        &fake_file_system_);
 
     // Run all pending tasks before destroying testing profile.
     base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc
index b2050aa..dab11ff 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc
@@ -74,7 +74,7 @@
 
   void TearDown() override {
     integration_service_factory_scope_.reset();
-    arc_bridge_service_.file_system()->SetInstance(nullptr, 0);
+    arc_bridge_service_.file_system()->CloseInstance(&fake_file_system_);
     arc_file_system_bridge_.reset();
     profile_manager_.reset();
     chromeos::DBusThreadManager::Shutdown();
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc
index ae0db71..bfabfd4 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc
@@ -57,8 +57,8 @@
   }
 
   void TearDown() override {
-    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
-        nullptr, 0);
+    arc_service_manager_->arc_bridge_service()->file_system()->CloseInstance(
+        &file_system_instance_);
     // Explicitly calls Shutdown() to detach from services.
     if (runner_)
       runner_->Shutdown();
@@ -168,8 +168,8 @@
 }
 
 TEST_F(ArcFileSystemOperationRunnerTest, FileInstanceUnavailable) {
-  arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
-      nullptr);
+  arc_service_manager_->arc_bridge_service()->file_system()->CloseInstance(
+      &file_system_instance_);
 
   int counter = 0;
   CallSetShouldDefer(false);
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
index a8c73639..f5d10915 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -259,13 +259,13 @@
     ArcServiceManager::Get()
         ->arc_bridge_service()
         ->backup_settings()
-        ->SetInstance(nullptr);
+        ->CloseInstance(fake_backup_settings_instance_.get());
     fake_backup_settings_instance_.reset();
 
     ArcServiceManager::Get()
         ->arc_bridge_service()
         ->intent_helper()
-        ->SetInstance(nullptr);
+        ->CloseInstance(fake_intent_helper_instance_.get());
     fake_intent_helper_instance_.reset();
   }
 
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
index c1d7fe0..37b2912 100644
--- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
+++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -153,7 +153,7 @@
   }
 
   void TearDown() override {
-    bridge_service_->policy()->SetInstance(nullptr, 0);
+    bridge_service_->policy()->CloseInstance(policy_instance_.get());
     policy_instance_.reset();
   }
 
diff --git a/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc b/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc
index 12c0962..0c5aec13 100644
--- a/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc
@@ -68,7 +68,7 @@
     ArcServiceManager::Get()
         ->arc_bridge_service()
         ->intent_helper()
-        ->SetInstance(nullptr);
+        ->CloseInstance(fake_intent_helper_instance_.get());
     fake_intent_helper_instance_.reset(nullptr);
   }
 
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc
index 55f682e8..b03bd3b 100644
--- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc
@@ -204,7 +204,8 @@
   }
 
   void TearDown() override {
-    arc_bridge_service_->voice_interaction_framework()->SetInstance(nullptr);
+    arc_bridge_service_->voice_interaction_framework()->CloseInstance(
+        framework_instance_.get());
     framework_instance_.reset();
     framework_service_.reset();
     arc_bridge_service_.reset();
@@ -298,7 +299,8 @@
 
 TEST_F(ArcVoiceInteractionFrameworkServiceTest, StartSessionWithoutInstance) {
   // Reset the framework instance.
-  arc_bridge_service()->voice_interaction_framework()->SetInstance(nullptr);
+  arc_bridge_service()->voice_interaction_framework()->CloseInstance(
+      framework_instance());
 
   framework_service()->StartSessionFromUserInteraction(gfx::Rect());
   // A notification should be sent if the container is not ready yet.
@@ -373,7 +375,8 @@
 
   // Clear the framework instance to simulate the container crash.
   // The client should become detached.
-  arc_bridge_service()->voice_interaction_framework()->SetInstance(nullptr);
+  arc_bridge_service()->voice_interaction_framework()->CloseInstance(
+      framework_instance());
   FlushHighlighterControllerMojo();
   EXPECT_FALSE(highlighter_controller()->client_attached());
 
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
index 2d430fa..4d8a028 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -131,8 +131,8 @@
   }
 
   void TearDown() override {
-    arc_service_manager_.arc_bridge_service()->wallpaper()->SetInstance(
-        nullptr);
+    arc_service_manager_.arc_bridge_service()->wallpaper()->CloseInstance(
+        wallpaper_instance_.get());
     wallpaper_instance_.reset();
 
     wallpaper_controller_client_.reset();
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
index 6f86ce96..0b8d117 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -504,57 +504,53 @@
 #endif
 }
 
-FileManagerPrivateGetProvidingExtensionsFunction::
-    FileManagerPrivateGetProvidingExtensionsFunction()
-    : chrome_details_(this) {
-}
+FileManagerPrivateGetProvidersFunction::FileManagerPrivateGetProvidersFunction()
+    : chrome_details_(this) {}
 
 ExtensionFunction::ResponseAction
-FileManagerPrivateGetProvidingExtensionsFunction::Run() {
+FileManagerPrivateGetProvidersFunction::Run() {
   using chromeos::file_system_provider::Capabilities;
   using chromeos::file_system_provider::ProviderId;
   using chromeos::file_system_provider::ProviderInterface;
   using chromeos::file_system_provider::Service;
   const Service* const service = Service::Get(chrome_details_.GetProfile());
 
-  using api::file_manager_private::ProvidingExtension;
-  std::vector<ProvidingExtension> providing_extensions;
+  using api::file_manager_private::Provider;
+  std::vector<Provider> result;
   for (const auto& pair : service->GetProviders()) {
     const ProviderInterface* const provider = pair.second.get();
     const ProviderId provider_id = provider->GetId();
 
-    // TODO(baileyberro, mtomasz): Add support for NATIVE too.
-    if (provider_id.GetType() != ProviderId::EXTENSION) {
-      continue;
-    }
+    Provider result_item;
+    result_item.provider_id = provider->GetId().ToString();
+    if (provider_id.GetType() == ProviderId::EXTENSION)
+      result_item.extension_id.reset(
+          new std::string(provider_id.GetExtensionId()));
+    result_item.name = provider->GetName();
 
-    ProvidingExtension providing_extension;
-    providing_extension.extension_id = provider_id.GetExtensionId();
-    providing_extension.name = provider->GetName();
-    Capabilities capabilities = provider->GetCapabilities();
-    providing_extension.configurable = capabilities.configurable;
-    providing_extension.watchable = capabilities.watchable;
-    providing_extension.multiple_mounts = capabilities.multiple_mounts;
+    const Capabilities capabilities = provider->GetCapabilities();
+    result_item.configurable = capabilities.configurable;
+    result_item.watchable = capabilities.watchable;
+    result_item.multiple_mounts = capabilities.multiple_mounts;
     switch (capabilities.source) {
       case SOURCE_FILE:
-        providing_extension.source =
+        result_item.source =
             api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_FILE;
         break;
       case SOURCE_DEVICE:
-        providing_extension.source =
+        result_item.source =
             api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_DEVICE;
         break;
       case SOURCE_NETWORK:
-        providing_extension.source =
+        result_item.source =
             api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_NETWORK;
         break;
     }
-    providing_extensions.push_back(std::move(providing_extension));
+    result.push_back(std::move(result_item));
   }
 
   return RespondNow(ArgumentList(
-      api::file_manager_private::GetProvidingExtensions::Results::Create(
-          providing_extensions)));
+      api::file_manager_private::GetProviders::Results::Create(result)));
 }
 
 FileManagerPrivateAddProvidedFileSystemFunction::
@@ -573,8 +569,7 @@
   using chromeos::file_system_provider::ProviderId;
   Service* const service = Service::Get(chrome_details_.GetProfile());
 
-  if (!service->RequestMount(
-          ProviderId::CreateFromExtensionId(params->extension_id)))
+  if (!service->RequestMount(ProviderId::FromString(params->provider_id)))
     return RespondNow(Error("Failed to request a new mount."));
 
   return RespondNow(NoArguments());
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h
index 0f29ad76..41f0d1a 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h
@@ -196,20 +196,20 @@
   DISALLOW_COPY_AND_ASSIGN(FileManagerPrivateIsPiexLoaderEnabledFunction);
 };
 
-// Implements the chrome.fileManagerPrivate.getProvidingExtensions method.
-class FileManagerPrivateGetProvidingExtensionsFunction
+// Implements the chrome.fileManagerPrivate.getProviders method.
+class FileManagerPrivateGetProvidersFunction
     : public UIThreadExtensionFunction {
  public:
-  FileManagerPrivateGetProvidingExtensionsFunction();
-  DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.getProvidingExtensions",
-                             FILEMANAGERPRIVATE_GETPROVIDINGEXTENSIONS)
+  FileManagerPrivateGetProvidersFunction();
+  DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.getProviders",
+                             FILEMANAGERPRIVATE_GETPROVIDERS)
  protected:
-  ~FileManagerPrivateGetProvidingExtensionsFunction() override {}
+  ~FileManagerPrivateGetProvidersFunction() override {}
 
  private:
   ResponseAction Run() override;
   const ChromeExtensionFunctionDetails chrome_details_;
-  DISALLOW_COPY_AND_ASSIGN(FileManagerPrivateGetProvidingExtensionsFunction);
+  DISALLOW_COPY_AND_ASSIGN(FileManagerPrivateGetProvidersFunction);
 };
 
 // Implements the chrome.fileManagerPrivate.addProvidedFileSystem method.
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc
index 1b24b03..e6a8560 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc
@@ -212,10 +212,14 @@
   volume_metadata->configurable = volume.configurable();
   volume_metadata->watchable = volume.watchable();
 
-  // TODO(baileyberro): Refactor extension_id into provider_id here.
   if (volume.type() == VOLUME_TYPE_PROVIDED) {
-    volume_metadata->extension_id.reset(
-        new std::string(volume.provider_id().GetIdUnsafe()));
+    volume_metadata->provider_id.reset(
+        new std::string(volume.provider_id().ToString()));
+    if (volume.provider_id().GetType() ==
+        chromeos::file_system_provider::ProviderId::EXTENSION) {
+      volume_metadata->extension_id.reset(
+          new std::string(volume.provider_id().GetExtensionId()));
+    }
     volume_metadata->file_system_id.reset(
         new std::string(volume.file_system_id()));
   }
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc
index cf22de1..be69cb1 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.cc
@@ -26,6 +26,16 @@
   return ProviderId(native_id, NATIVE);
 }
 
+ProviderId ProviderId::FromString(const std::string& str) {
+  if (str.length() == 0)
+    return ProviderId();  // Invalid.
+
+  if (str[0] == '@')
+    return ProviderId::CreateFromNativeId(str.substr(1));
+
+  return ProviderId::CreateFromExtensionId(str);
+}
+
 const extensions::ExtensionId& ProviderId::GetExtensionId() const {
   CHECK_EQ(EXTENSION, type_);
   return internal_id_;
@@ -36,10 +46,6 @@
   return internal_id_;
 }
 
-const std::string& ProviderId::GetIdUnsafe() const {
-  return internal_id_;
-}
-
 ProviderId::ProviderType ProviderId::GetType() const {
   return type_;
 }
@@ -53,13 +59,12 @@
     case NATIVE:
       return std::string("@") + internal_id_;
     case INVALID:
-      NOTREACHED();
       return "";
   }
 }
 
 bool ProviderId::operator==(const ProviderId& other) const {
-  return type_ == other.GetType() && internal_id_ == other.GetIdUnsafe();
+  return type_ == other.type_ && internal_id_ == other.internal_id_;
 }
 
 bool ProviderId::operator<(const ProviderId& other) const {
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_info.h b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.h
index ecd14853..6195196d 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system_info.h
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_info.h
@@ -40,8 +40,8 @@
   static ProviderId CreateFromExtensionId(
       const extensions::ExtensionId& extension_id);
   static ProviderId CreateFromNativeId(const std::string& native_id);
+  static ProviderId FromString(const std::string& provider_id);
 
-  const std::string& GetIdUnsafe() const;
   const extensions::ExtensionId& GetExtensionId() const;
   const std::string& GetNativeId() const;
   std::string ToString() const;
@@ -69,6 +69,8 @@
                          bool watchable,
                          extensions::FileSystemProviderSource source);
 
+  // TODO(mtomasz): Remove this constructor. Callers should be using
+  // provider id, not extension id.
   ProvidedFileSystemInfo(const extensions::ExtensionId& extension_id,
                          const MountOptions& mount_options,
                          const base::FilePath& mount_path,
diff --git a/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc b/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc
index e365f975..c4123211 100644
--- a/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc
@@ -80,8 +80,8 @@
   }
 
   void TearDown() override {
-    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
-        nullptr);
+    arc_service_manager_->arc_bridge_service()->file_system()->CloseInstance(
+        &fake_file_system_);
   }
 
  protected:
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
index a59a0d11..a4704135 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -24,6 +24,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/sys_info.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/browser/chromeos/ash_config.h"
@@ -1028,7 +1029,8 @@
       extension_ime_util::GetComponentIDByInputMethodID(descriptor.id());
   if (engine_map_.find(profile) == engine_map_.end() ||
       engine_map_[profile].find(extension_id) == engine_map_[profile].end()) {
-    LOG(ERROR) << "IMEEngine for \"" << extension_id << "\" is not registered";
+    LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
+        << "IMEEngine for \"" << extension_id << "\" is not registered";
   }
   engine = engine_map_[profile][extension_id];
 
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.cc b/chrome/browser/chromeos/login/ui/login_display_host.cc
index d663805..defdcd9 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
 
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/mobile_config.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -64,6 +65,14 @@
       &LoginDisplayHost::OnAuthPrewarmDone, weak_factory_.GetWeakPtr()));
 }
 
+void LoginDisplayHost::StartDemoAppLaunch() {
+  VLOG(1) << "Login >> starting demo app.";
+  SetStatusAreaVisible(false);
+
+  demo_app_launcher_ = std::make_unique<DemoAppLauncher>();
+  demo_app_launcher_->StartDemoAppLaunch();
+}
+
 void LoginDisplayHost::OnAuthPrewarmDone() {
   auth_prewarmer_.reset();
 }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.h b/chrome/browser/chromeos/login/ui/login_display_host.h
index c05117de..2f0cb7a5 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host.h
@@ -20,6 +20,7 @@
 namespace chromeos {
 
 class AppLaunchController;
+class DemoAppLauncher;
 class LoginScreenContext;
 class OobeUI;
 class WebUILoginView;
@@ -102,7 +103,7 @@
                               bool is_auto_launch) = 0;
 
   // Starts the demo app launch.
-  virtual void StartDemoAppLaunch() = 0;
+  void StartDemoAppLaunch();
 
   // Starts ARC kiosk splash screen.
   virtual void StartArcKiosk(const AccountId& account_id) = 0;
@@ -125,6 +126,9 @@
   // Active instance of authentication prewarmer.
   std::unique_ptr<AuthPrewarmer> auth_prewarmer_;
 
+  // Demo app launcher.
+  std::unique_ptr<DemoAppLauncher> demo_app_launcher_;
+
  private:
   base::WeakPtrFactory<LoginDisplayHost> weak_factory_;
 
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_views.cc b/chrome/browser/chromeos/login/ui/login_display_host_views.cc
index 8323e32..5df61e51 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_views.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_views.cc
@@ -113,10 +113,6 @@
   NOTIMPLEMENTED();
 }
 
-void LoginDisplayHostViews::StartDemoAppLaunch() {
-  NOTIMPLEMENTED();
-}
-
 void LoginDisplayHostViews::StartArcKiosk(const AccountId& account_id) {
   NOTIMPLEMENTED();
 }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_views.h b/chrome/browser/chromeos/login/ui/login_display_host_views.h
index 6d12147..808af84 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_views.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_views.h
@@ -45,7 +45,6 @@
   void StartAppLaunch(const std::string& app_id,
                       bool diagnostic_mode,
                       bool is_auto_launch) override;
-  void StartDemoAppLaunch() override;
   void StartArcKiosk(const AccountId& account_id) override;
   void StartVoiceInteractionOobe() override;
   bool IsVoiceInteractionOobe() override;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
index d52b8e8d..7829f8e 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -37,7 +37,6 @@
 #include "chrome/browser/chromeos/first_run/first_run.h"
 #include "chrome/browser/chromeos/language_preferences.h"
 #include "chrome/browser/chromeos/login/arc_kiosk_controller.h"
-#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/login_wizard.h"
@@ -793,14 +792,6 @@
     login_display_->OnPreferencesChanged();
 }
 
-void LoginDisplayHostWebUI::StartDemoAppLaunch() {
-  VLOG(1) << "Login WebUI >> starting demo app.";
-  SetStatusAreaVisible(false);
-
-  demo_app_launcher_.reset(new DemoAppLauncher());
-  demo_app_launcher_->StartDemoAppLaunch();
-}
-
 void LoginDisplayHostWebUI::StartAppLaunch(const std::string& app_id,
                                            bool diagnostic_mode,
                                            bool auto_launch) {
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
index dab81dc..01da177 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -42,7 +42,6 @@
 namespace chromeos {
 
 class ArcKioskController;
-class DemoAppLauncher;
 class LoginDisplayWebUI;
 class WebUILoginView;
 
@@ -80,7 +79,6 @@
   void StartAppLaunch(const std::string& app_id,
                       bool diagnostic_mode,
                       bool auto_launch) override;
-  void StartDemoAppLaunch() override;
   void StartArcKiosk(const AccountId& account_id) override;
   bool IsVoiceInteractionOobe() override;
   void StartVoiceInteractionOobe() override;
@@ -207,9 +205,6 @@
   // App launch controller.
   std::unique_ptr<AppLaunchController> app_launch_controller_;
 
-  // Demo app launcher.
-  std::unique_ptr<DemoAppLauncher> demo_app_launcher_;
-
   // ARC kiosk controller.
   std::unique_ptr<ArcKioskController> arc_kiosk_controller_;
 
diff --git a/chrome/browser/chromeos/note_taking_helper_unittest.cc b/chrome/browser/chromeos/note_taking_helper_unittest.cc
index a29d442..59f42d2 100644
--- a/chrome/browser/chromeos/note_taking_helper_unittest.cc
+++ b/chrome/browser/chromeos/note_taking_helper_unittest.cc
@@ -222,7 +222,7 @@
       arc::ArcServiceManager::Get()
           ->arc_bridge_service()
           ->intent_helper()
-          ->SetInstance(nullptr);
+          ->CloseInstance(&intent_helper_);
       NoteTakingHelper::Shutdown();
       intent_helper_bridge_.reset();
       arc_test_.TearDown();
diff --git a/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc b/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc
index 15746e8f..8cbf76ea 100644
--- a/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc
+++ b/chrome/browser/chromeos/policy/system_log_uploader_unittest.cc
@@ -288,33 +288,4 @@
                     SystemLogUploader::kDefaultUploadDelayMs));
 }
 
-// Test RemovePII function.
-TEST_F(SystemLogUploaderTest, TestPII) {
-  feedback::AnonymizerTool anonymizer;
-  std::string data =
-      "aaaaaaaa [SSID=123aaaaaa]aaaaa\n"  // SSID.
-      "aaaaaaaahttp://tets.comaaaaaaa\n"  // URL.
-      "aaaaaemail@example.comaaa\n"       //  Email address.
-      "example@@1234\n"           //  No PII, it is not valid email address.
-      "255.255.155.255\n"         // IP address.
-      "aaaa123.123.45.4aaa\n"     // IP address.
-      "11:11;11::11\n"            // IP address.
-      "11::11\n"                  // IP address.
-      "11:11:abcdef:0:0:0:0:0\n"  // No PII.
-      "aa:aa:aa:aa:aa:aa";        // MAC address (BSSID).
-
-  std::string result =
-      "aaaaaaaa [SSID=1]aaaaa\n"
-      "aaaaaaaa<URL: 1>\n"
-      "<email: 1>\n"
-      "example@@1234\n"
-      "<IPv4: 1>55\n"
-      "aaaa<IPv4: 2>aaa\n"
-      "11:11;<IPv6: 1>\n"
-      "<IPv6: 1>\n"
-      "11:11:abcdef:0:0:0:0:0\n"
-      "aa:aa:aa:00:00:01";
-  EXPECT_EQ(result, SystemLogUploader::RemoveSensitiveData(&anonymizer, data));
-}
-
 }  // namespace policy
diff --git a/chrome/browser/chromeos/power/freezer_cgroup_process_manager.cc b/chrome/browser/chromeos/power/freezer_cgroup_process_manager.cc
index 1c3f361..b86be9e 100644
--- a/chrome/browser/chromeos/power/freezer_cgroup_process_manager.cc
+++ b/chrome/browser/chromeos/power/freezer_cgroup_process_manager.cc
@@ -13,6 +13,7 @@
 #include "base/macros.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/sys_info.h"
 #include "base/task_scheduler/post_task.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -59,8 +60,9 @@
                base::PathIsWritable(to_be_frozen_state_path_);
 
     if (!enabled_) {
-      LOG(WARNING) << "Cgroup freezer does not exist or is not writable. "
-                   << "Unable to freeze renderer processes.";
+      LOG_IF(WARNING, base::SysInfo::IsRunningOnChromeOS())
+          << "Cgroup freezer does not exist or is not writable. "
+          << "Unable to freeze renderer processes.";
       return;
     }
 
diff --git a/chrome/browser/chromeos/power/ml/user_activity_logger_delegate_ukm.cc b/chrome/browser/chromeos/power/ml/user_activity_logger_delegate_ukm.cc
index f37f043..cf13997 100644
--- a/chrome/browser/chromeos/power/ml/user_activity_logger_delegate_ukm.cc
+++ b/chrome/browser/chromeos/power/ml/user_activity_logger_delegate_ukm.cc
@@ -10,9 +10,9 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "components/ukm/content/source_url_recorder.h"
 #include "content/public/browser/web_contents.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
-#include "services/metrics/public/cpp/ukm_entry_builder.h"
 
 namespace chromeos {
 namespace power {
@@ -39,19 +39,12 @@
     const TabStripModel* const tab_strip_model = browser->tab_strip_model();
     DCHECK(tab_strip_model);
     for (int i = 0; i < tab_strip_model->count(); ++i) {
-      const content::WebContents* const contents =
-          tab_strip_model->GetWebContentsAt(i);
+      content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
       DCHECK(contents);
-
-      const GURL url = contents->GetLastCommittedURL();
-      if (!url.SchemeIsHTTPOrHTTPS())
-        continue;
-
-      ukm::SourceId source_id = ukm_recorder_->GetNewSourceID();
-      // We should run UpdateSourceURL here so that the url is associated with
-      // its source id.
-      ukm_recorder_->UpdateSourceURL(source_id, url);
-      source_ids_.push_back(source_id);
+      ukm::SourceId source_id =
+          ukm::GetSourceIdForWebContentsDocument(contents);
+      if (source_id != ukm::kInvalidSourceId)
+        source_ids_.push_back(source_id);
     }
   }
 }
diff --git a/chrome/browser/chromeos/settings/install_attributes.cc b/chrome/browser/chromeos/settings/install_attributes.cc
index faa0011..d536ec73 100644
--- a/chrome/browser/chromeos/settings/install_attributes.cc
+++ b/chrome/browser/chromeos/settings/install_attributes.cc
@@ -16,6 +16,7 @@
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
+#include "base/sys_info.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "chromeos/cryptohome/cryptohome_util.h"
@@ -92,7 +93,8 @@
                  weak_ptr_factory_.GetWeakPtr()));
 
   if (!base::PathExists(cache_file)) {
-    LOG(WARNING) << "Install attributes missing, first sign in";
+    LOG_IF(WARNING, base::SysInfo::IsRunningOnChromeOS())
+        << "Install attributes missing, first sign in";
     return;
   }
 
diff --git a/chrome/browser/chromeos/smb_client/smb_file_system.cc b/chrome/browser/chromeos/smb_client/smb_file_system.cc
index ea4d482..3531bcb 100644
--- a/chrome/browser/chromeos/smb_client/smb_file_system.cc
+++ b/chrome/browser/chromeos/smb_client/smb_file_system.cc
@@ -4,6 +4,10 @@
 
 #include "chrome/browser/chromeos/smb_client/smb_file_system.h"
 
+#include "base/strings/string_number_conversions.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/smb_provider_client.h"
+
 namespace chromeos {
 namespace smb_client {
 
@@ -15,12 +19,83 @@
 
 SmbFileSystem::~SmbFileSystem() {}
 
+// static
+base::File::Error SmbFileSystem::TranslateError(smbprovider::ErrorType error) {
+  DCHECK_NE(smbprovider::ERROR_NONE, error);
+
+  switch (error) {
+    case smbprovider::ERROR_OK:
+      return base::File::FILE_OK;
+    case smbprovider::ERROR_FAILED:
+      return base::File::FILE_ERROR_FAILED;
+    case smbprovider::ERROR_IN_USE:
+      return base::File::FILE_ERROR_IN_USE;
+    case smbprovider::ERROR_EXISTS:
+      return base::File::FILE_ERROR_EXISTS;
+    case smbprovider::ERROR_NOT_FOUND:
+      return base::File::FILE_ERROR_NOT_FOUND;
+    case smbprovider::ERROR_ACCESS_DENIED:
+      return base::File::FILE_ERROR_ACCESS_DENIED;
+    case smbprovider::ERROR_TOO_MANY_OPENED:
+      return base::File::FILE_ERROR_TOO_MANY_OPENED;
+    case smbprovider::ERROR_NO_MEMORY:
+      return base::File::FILE_ERROR_NO_MEMORY;
+    case smbprovider::ERROR_NO_SPACE:
+      return base::File::FILE_ERROR_NO_SPACE;
+    case smbprovider::ERROR_NOT_A_DIRECTORY:
+      return base::File::FILE_ERROR_NOT_A_DIRECTORY;
+    case smbprovider::ERROR_INVALID_OPERATION:
+      return base::File::FILE_ERROR_INVALID_OPERATION;
+    case smbprovider::ERROR_SECURITY:
+      return base::File::FILE_ERROR_SECURITY;
+    case smbprovider::ERROR_ABORT:
+      return base::File::FILE_ERROR_ABORT;
+    case smbprovider::ERROR_NOT_A_FILE:
+      return base::File::FILE_ERROR_NOT_A_FILE;
+    case smbprovider::ERROR_NOT_EMPTY:
+      return base::File::FILE_ERROR_NOT_EMPTY;
+    case smbprovider::ERROR_INVALID_URL:
+      return base::File::FILE_ERROR_INVALID_URL;
+    case smbprovider::ERROR_IO:
+      return base::File::FILE_ERROR_IO;
+    case smbprovider::ERROR_DBUS_PARSE_FAILED:
+      // DBUS_PARSE_FAILED maps to generic ERROR_FAILED
+      LOG(ERROR) << "DBUS PARSE FAILED";
+      return base::File::FILE_ERROR_FAILED;
+    default:
+      break;
+  }
+
+  NOTREACHED();
+  return base::File::FILE_ERROR_FAILED;
+}
+
+int32_t SmbFileSystem::GetMountId() const {
+  int32_t mount_id;
+  bool result =
+      base::StringToInt(file_system_info_.file_system_id(), &mount_id);
+  DCHECK(result);
+  return mount_id;
+}
+
+SmbProviderClient* SmbFileSystem::GetSmbProviderClient() const {
+  return chromeos::DBusThreadManager::Get()->GetSmbProviderClient();
+}
+
 AbortCallback SmbFileSystem::RequestUnmount(
     const storage::AsyncFileUtil::StatusCallback& callback) {
-  NOTIMPLEMENTED();
+  GetSmbProviderClient()->Unmount(
+      GetMountId(), base::BindOnce(&SmbFileSystem::HandleRequestUnmountCallback,
+                                   weak_ptr_factory_.GetWeakPtr(), callback));
   return AbortCallback();
 }
 
+void SmbFileSystem::HandleRequestUnmountCallback(
+    const storage::AsyncFileUtil::StatusCallback& callback,
+    smbprovider::ErrorType smb_error) const {
+  callback.Run(TranslateError(smb_error));
+}
+
 AbortCallback SmbFileSystem::GetMetadata(
     const base::FilePath& entry_path,
     ProvidedFileSystemInterface::MetadataFieldMask fields,
diff --git a/chrome/browser/chromeos/smb_client/smb_file_system.h b/chrome/browser/chromeos/smb_client/smb_file_system.h
index 324cc9a1..c4afa70 100644
--- a/chrome/browser/chromeos/smb_client/smb_file_system.h
+++ b/chrome/browser/chromeos/smb_client/smb_file_system.h
@@ -21,6 +21,7 @@
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
 #include "chrome/browser/chromeos/file_system_provider/watcher.h"
+#include "chromeos/dbus/smb_provider_client.h"
 #include "storage/browser/fileapi/async_file_util.h"
 #include "storage/browser/fileapi/watcher_manager.h"
 #include "url/gurl.h"
@@ -44,6 +45,8 @@
       const file_system_provider::ProvidedFileSystemInfo& file_system_info);
   ~SmbFileSystem() override;
 
+  static base::File::Error TranslateError(smbprovider::ErrorType);
+
   // ProvidedFileSystemInterface overrides.
   file_system_provider::AbortCallback RequestUnmount(
       const storage::AsyncFileUtil::StatusCallback& callback) override;
@@ -164,6 +167,14 @@
   base::WeakPtr<ProvidedFileSystemInterface> GetWeakPtr() override;
 
  private:
+  void HandleRequestUnmountCallback(
+      const storage::AsyncFileUtil::StatusCallback& callback,
+      smbprovider::ErrorType smb_error) const;
+
+  int32_t GetMountId() const;
+
+  SmbProviderClient* GetSmbProviderClient() const;
+
   file_system_provider::ProvidedFileSystemInfo file_system_info_;
   file_system_provider::OpenedFiles opened_files_;
   storage::AsyncFileUtil::EntryList entry_list_;
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc
index 96d4ca0..4caa662b 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.cc
+++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -4,8 +4,12 @@
 
 #include "chrome/browser/chromeos/smb_client/smb_service.h"
 
+#include "base/strings/string_number_conversions.h"
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/chromeos/smb_client/smb_file_system.h"
+#include "chrome/browser/chromeos/smb_client/smb_service_factory.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/smb_provider_client.h"
 
 using chromeos::file_system_provider::Service;
 
@@ -18,15 +22,45 @@
       capabilities_(false, false, false, extensions::SOURCE_NETWORK),
       // TODO(baileyberro): Localize this string, so it shows correctly in all
       // languages. See l10n_util::GetStringUTF8.
-      name_("SMB Shares") {
+      name_("SMB Shares"),
+      weak_ptr_factory_(this) {
   GetProviderService()->RegisterProvider(std::make_unique<SmbService>(profile));
 }
 
 SmbService::~SmbService() {}
 
-base::File::Error SmbService::Mount(
-    const file_system_provider::MountOptions& options) {
-  return GetProviderService()->MountFileSystem(provider_id_, options);
+// static
+SmbService* SmbService::Get(content::BrowserContext* context) {
+  return SmbServiceFactory::Get(context);
+}
+
+void SmbService::Mount(const file_system_provider::MountOptions& options,
+                       const std::string& share_path,
+                       MountResponse callback) {
+  chromeos::DBusThreadManager::Get()->GetSmbProviderClient()->Mount(
+      share_path, base::BindOnce(&SmbService::OnMountResponse,
+                                 weak_ptr_factory_.GetWeakPtr(),
+                                 base::Passed(&callback), options));
+}
+
+void SmbService::OnMountResponse(
+    MountResponse callback,
+    const file_system_provider::MountOptions& options,
+    smbprovider::ErrorType error,
+    int32_t mount_id) {
+  if (error != smbprovider::ERROR_OK) {
+    DCHECK(mount_id >= 0);
+    std::move(callback).Run(SmbFileSystem::TranslateError(error));
+    return;
+  }
+
+  file_system_provider::MountOptions mount_options(options);
+  mount_options.file_system_id = base::NumberToString(mount_id);
+
+  base::File::Error providerServiceMountResult =
+      GetProviderService()->MountFileSystem(GetId(), mount_options);
+
+  std::move(callback).Run(providerServiceMountResult);
 }
 
 Service* SmbService::GetProviderService() const {
diff --git a/chrome/browser/chromeos/smb_client/smb_service.h b/chrome/browser/chromeos/smb_client/smb_service.h
index c73142b3d..ce685aa9 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.h
+++ b/chrome/browser/chromeos/smb_client/smb_service.h
@@ -10,10 +10,12 @@
 
 #include "base/files/file.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/chromeos/file_system_provider/provider_interface.h"
 #include "chrome/browser/chromeos/file_system_provider/service.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chromeos/dbus/smb_provider_client.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 namespace chromeos {
@@ -29,12 +31,27 @@
 // Creates and manages an smb file system.
 class SmbService : public KeyedService, public ProviderInterface {
  public:
+  using MountResponse = base::OnceCallback<void(base::File::Error error)>;
+
   explicit SmbService(Profile* profile);
   ~SmbService() override;
 
-  // Mounts an SMB file system, passing |options| on to
-  // file_system_provider::Service::MountFileSystem().
-  base::File::Error Mount(const file_system_provider::MountOptions& options);
+  // Gets the singleton instance for the |context|.
+  static SmbService* Get(content::BrowserContext* context);
+
+  // Starts the process of mounting an SMB file system.
+  // Calls SmbProviderClient::Mount().
+  void Mount(const file_system_provider::MountOptions& options,
+             const std::string& share_path,
+             MountResponse callback);
+
+  // Completes the mounting of an SMB file system, passing |options| on to
+  // file_system_provider::Service::MountFileSystem(). Passes error status to
+  // callback.
+  void OnMountResponse(MountResponse callback,
+                       const file_system_provider::MountOptions& options,
+                       smbprovider::ErrorType error,
+                       int32_t mount_id);
 
   // ProviderInterface overrides.
   std::unique_ptr<ProvidedFileSystemInterface> CreateProvidedFileSystem(
@@ -52,6 +69,8 @@
   Capabilities capabilities_;
   std::string name_;
 
+  base::WeakPtrFactory<SmbService> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(SmbService);
 };
 
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc
index 6def3028..24ddf90 100644
--- a/chrome/browser/chromeos/tether/tether_service_unittest.cc
+++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -609,13 +609,13 @@
 }
 
 TEST_F(TetherServiceTest, TestFeatureFlagDisabled) {
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndDisableFeature(features::kInstantTethering);
-
   EXPECT_FALSE(TetherService::Get(profile_.get()));
 }
 
 TEST_F(TetherServiceTest, TestFeatureFlagEnabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(features::kInstantTethering);
+
   TetherService* tether_service = TetherService::Get(profile_.get());
   ASSERT_TRUE(tether_service);
 
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
index 6894047..9caffa1b 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
@@ -133,7 +133,8 @@
 void GetPartOfMessageArguments(IPC::Message* message,
                                const base::DictionaryValue** out,
                                ExtensionMsg_DispatchEvent::Param* param) {
-  ASSERT_EQ(ExtensionMsg_DispatchEvent::ID, message->type());
+  ASSERT_EQ(static_cast<uint32_t>(ExtensionMsg_DispatchEvent::ID),
+            message->type());
   ASSERT_TRUE(ExtensionMsg_DispatchEvent::Read(message, param));
   const base::ListValue& list = std::get<1>(*param);
   ASSERT_EQ(1u, list.GetSize());
@@ -167,7 +168,8 @@
  private:
   // IPC::Sender
   bool Send(IPC::Message* message) override {
-    EXPECT_EQ(ExtensionMsg_DispatchEvent::ID, message->type());
+    EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_DispatchEvent::ID),
+              message->type());
 
     EXPECT_FALSE(task_queue_.empty());
     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 2843718a..86dd5e5 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1682,6 +1682,11 @@
 const char kChromeHomeClearUrlOnOpenDescription[] =
     "Clear omnibox URL when the bottom sheet is opened.";
 
+const char kChromeHomeEnableSurveyName[] = "Enable Chrome Home survey";
+const char kChromeHomeEnableSurveyDescription[] =
+    "If enabled, the survey process will allow surveys using sample "
+    "parameters.";
+
 const char kChromeHomeInactivitySheetExpansionName[] =
     "Expansion of Chrome Home bottom sheet on startup";
 const char kChromeHomeInactivitySheetExpansionDescription[] =
@@ -1707,6 +1712,11 @@
 const char kChromeHomePromoDescription[] =
     "Enable showing the opt-in/out Chrome Home promo.";
 
+const char kChromeHomeShowGoogleGName[] = "Chrome Home Show Google G";
+const char kChromeHomeShowGoogleGDescription[] =
+    "Show the Google G when the url is cleared. The flag to clear the url "
+    "when the sheet is opened must also be set.";
+
 const char kChromeHomeSwipeLogicName[] = "Chrome Home Swipe Logic";
 const char kChromeHomeSwipeLogicDescription[] =
     "Various swipe logic options for Chrome Home for sheet expansion.";
@@ -1983,12 +1993,6 @@
 const char kOfflineBookmarksDescription[] =
     "Enable saving bookmarked pages for offline viewing.";
 
-const char kOfflinePagesAsyncDownloadName[] =
-    R"*(Enables showing "DOWNLOAD WHEN ONLINE" button in error pages.)*";
-const char kOfflinePagesAsyncDownloadDescription[] =
-    R"*(Enables showing "DOWNLOAD WHEN ONLINE" button in error pages such )*"
-    R"*(that the user can click on it to download the page later.)*";
-
 const char kOfflinePagesCtName[] = "Enable Offline Pages CT features.";
 const char kOfflinePagesCtDescription[] = "Enable Offline Pages CT features.";
 
@@ -2824,6 +2828,11 @@
 const char kAshDisableSmoothScreenRotationDescription[] =
     "Disable smooth rotation animations.";
 
+const char kAshEnableDisplayMoveWindowAccelsName[] =
+    "Enable shortcuts for moving window between displays.";
+const char kAshEnableDisplayMoveWindowAccelsDescription[] =
+    "Enable shortcuts for moving window between displays.";
+
 const char kAshEnableKeyboardShortcutViewerName[] =
     "Enable keyboard shortcut viewer.";
 const char kAshEnableKeyboardShortcutViewerDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index e3791292..31b93f4 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1035,6 +1035,9 @@
 extern const char kChromeHomeClearUrlOnOpenName[];
 extern const char kChromeHomeClearUrlOnOpenDescription[];
 
+extern const char kChromeHomeEnableSurveyName[];
+extern const char kChromeHomeEnableSurveyDescription[];
+
 extern const char kChromeHomeInactivitySheetExpansionName[];
 extern const char kChromeHomeInactivitySheetExpansionDescription[];
 
@@ -1050,6 +1053,9 @@
 extern const char kChromeHomePromoName[];
 extern const char kChromeHomePromoDescription[];
 
+extern const char kChromeHomeShowGoogleGName[];
+extern const char kChromeHomeShowGoogleGDescription[];
+
 extern const char kChromeHomeSwipeLogicName[];
 extern const char kChromeHomeSwipeLogicDescription[];
 extern const char kChromeHomeSwipeLogicRestrictArea[];
@@ -1218,9 +1224,6 @@
 extern const char kOfflineBookmarksName[];
 extern const char kOfflineBookmarksDescription[];
 
-extern const char kOfflinePagesAsyncDownloadName[];
-extern const char kOfflinePagesAsyncDownloadDescription[];
-
 extern const char kOfflinePagesCtName[];
 extern const char kOfflinePagesCtDescription[];
 
@@ -1752,6 +1755,9 @@
 extern const char kAshDisableSmoothScreenRotationName[];
 extern const char kAshDisableSmoothScreenRotationDescription[];
 
+extern const char kAshEnableDisplayMoveWindowAccelsName[];
+extern const char kAshEnableDisplayMoveWindowAccelsDescription[];
+
 extern const char kAshEnableKeyboardShortcutViewerName[];
 extern const char kAshEnableKeyboardShortcutViewerDescription[];
 
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index 82f7dbd2..783505f 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -55,7 +55,6 @@
 #include "components/nacl/common/features.h"
 #include "components/offline_pages/core/request_header/offline_page_navigation_ui_data.h"
 #include "components/offline_pages/features/features.h"
-#include "components/policy/content/policy_blacklist_navigation_throttle.h"
 #include "components/policy/core/common/cloud/policy_header_io_helper.h"
 #include "components/previews/content/previews_content_util.h"
 #include "components/previews/content/previews_io_data.h"
@@ -233,7 +232,8 @@
     const GURL& url,
     const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
     ui::PageTransition page_transition,
-    bool has_user_gesture) {
+    bool has_user_gesture,
+    bool is_whitelisted) {
   // If there is no longer a WebContents, the request may have raced with tab
   // closing. Don't fire the external request. (It may have been a prerender.)
   content::WebContents* web_contents = web_contents_getter.Run();
@@ -249,18 +249,6 @@
     return;
   }
 
-  bool is_whitelisted = false;
-  Profile* profile =
-      Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  PolicyBlacklistService* service =
-      PolicyBlacklistFactory::GetForProfile(profile);
-  if (service) {
-    const policy::URLBlacklist::URLBlacklistState url_state =
-        service->GetURLBlacklistState(url);
-    is_whitelisted =
-        url_state == policy::URLBlacklist::URLBlacklistState::URL_IN_WHITELIST;
-  }
-
   // If the URL is in whitelist, we launch it without asking the user and
   // without any additional security checks. Since the URL is whitelisted,
   // we assume it can be executed.
@@ -599,6 +587,18 @@
 bool ChromeResourceDispatcherHostDelegate::HandleExternalProtocol(
     const GURL& url,
     content::ResourceRequestInfo* info) {
+  // Get the state, if |url| is in blacklist, whitelist or in none of those.
+  ProfileIOData* io_data =
+      ProfileIOData::FromResourceContext(info->GetContext());
+  const policy::URLBlacklist::URLBlacklistState url_state =
+      io_data->GetURLBlacklistState(url);
+  if (url_state == policy::URLBlacklist::URLBlacklistState::URL_IN_BLACKLIST) {
+    // It's a link with custom scheme and it's blacklisted. We return false here
+    // and let it process as a normal URL. Eventually chrome_network_delegate
+    // will see it's in the blacklist and the user will be shown the blocked
+    // content page.
+    return false;
+  }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   // External protocols are disabled for guests. An exception is made for the
@@ -622,10 +622,13 @@
     return false;
 #endif  // defined(ANDROID)
 
+  const bool is_whitelisted =
+      url_state == policy::URLBlacklist::URLBlacklistState::URL_IN_WHITELIST;
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::BindOnce(&LaunchURL, url, info->GetWebContentsGetterForRequest(),
-                     info->GetPageTransition(), info->HasUserGesture()));
+                     info->GetPageTransition(), info->HasUserGesture(),
+                     is_whitelisted));
   return true;
 }
 
diff --git a/chrome/browser/media/media_storage_id_salt_unittest.cc b/chrome/browser/media/media_storage_id_salt_unittest.cc
index 6bfc849..f12dd44 100644
--- a/chrome/browser/media/media_storage_id_salt_unittest.cc
+++ b/chrome/browser/media/media_storage_id_salt_unittest.cc
@@ -20,7 +20,7 @@
 
   MediaStorageIdSalt::RegisterProfilePrefs(prefs.registry());
   std::vector<uint8_t> salt = MediaStorageIdSalt::GetSalt(&prefs);
-  EXPECT_EQ(MediaStorageIdSalt::kSaltLength, salt.size());
+  EXPECT_EQ(static_cast<size_t>(MediaStorageIdSalt::kSaltLength), salt.size());
 }
 
 TEST(MediaStorageIdSalt, Recreate) {
@@ -28,13 +28,15 @@
 
   MediaStorageIdSalt::RegisterProfilePrefs(prefs.registry());
   std::vector<uint8_t> original_salt = MediaStorageIdSalt::GetSalt(&prefs);
-  EXPECT_EQ(MediaStorageIdSalt::kSaltLength, original_salt.size());
+  EXPECT_EQ(static_cast<size_t>(MediaStorageIdSalt::kSaltLength),
+            original_salt.size());
 
   // Now that the salt is created, mess it up and then try fetching it again
   // (should generate a new salt and log an error).
   prefs.SetString(prefs::kMediaStorageIdSalt, "123");
   std::vector<uint8_t> new_salt = MediaStorageIdSalt::GetSalt(&prefs);
-  EXPECT_EQ(MediaStorageIdSalt::kSaltLength, new_salt.size());
+  EXPECT_EQ(static_cast<size_t>(MediaStorageIdSalt::kSaltLength),
+            new_salt.size());
   EXPECT_NE(original_salt, new_salt);
 }
 
@@ -43,10 +45,10 @@
 
   MediaStorageIdSalt::RegisterProfilePrefs(prefs.registry());
   std::vector<uint8_t> salt1 = MediaStorageIdSalt::GetSalt(&prefs);
-  EXPECT_EQ(MediaStorageIdSalt::kSaltLength, salt1.size());
+  EXPECT_EQ(static_cast<size_t>(MediaStorageIdSalt::kSaltLength), salt1.size());
 
   // Fetch the salt again. Should be the same value.
   std::vector<uint8_t> salt2 = MediaStorageIdSalt::GetSalt(&prefs);
-  EXPECT_EQ(MediaStorageIdSalt::kSaltLength, salt2.size());
+  EXPECT_EQ(static_cast<size_t>(MediaStorageIdSalt::kSaltLength), salt2.size());
   EXPECT_EQ(salt1, salt2);
 }
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc
index 3dc7f949..f46d41a 100644
--- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.cc
@@ -25,7 +25,8 @@
 
 }  // namespace
 
-DialMediaSinkService::DialMediaSinkService(content::BrowserContext* context) {
+DialMediaSinkService::DialMediaSinkService(content::BrowserContext* context)
+    : impl_(nullptr, base::OnTaskRunnerDeleter(nullptr)) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   auto* profile = Profile::FromBrowserContext(context);
   request_context_ = profile->GetRequestContext();
@@ -34,8 +35,6 @@
 
 DialMediaSinkService::~DialMediaSinkService() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (impl_)
-    impl_->task_runner()->DeleteSoon(FROM_HERE, impl_.release());
 }
 
 void DialMediaSinkService::Start(
@@ -80,7 +79,8 @@
                                 base::Unretained(impl_.get())));
 }
 
-std::unique_ptr<DialMediaSinkServiceImpl> DialMediaSinkService::CreateImpl(
+std::unique_ptr<DialMediaSinkServiceImpl, base::OnTaskRunnerDeleter>
+DialMediaSinkService::CreateImpl(
     const OnSinksDiscoveredCallback& sink_discovery_cb,
     const OnDialSinkAddedCallback& dial_sink_added_cb,
     const scoped_refptr<net::URLRequestContextGetter>& request_context) {
@@ -92,11 +92,14 @@
 
   // Note: The SequencedTaskRunner needs to be IO thread because DialRegistry
   // and URLRequestContextGetter run on IO thread.
-  return std::make_unique<DialMediaSinkServiceImpl>(
-      std::move(connector), sink_discovery_cb, dial_sink_added_cb,
-      request_context,
+  scoped_refptr<base::SequencedTaskRunner> task_runner =
       content::BrowserThread::GetTaskRunnerForThread(
-          content::BrowserThread::IO));
+          content::BrowserThread::IO);
+  return std::unique_ptr<DialMediaSinkServiceImpl, base::OnTaskRunnerDeleter>(
+      new DialMediaSinkServiceImpl(std::move(connector), sink_discovery_cb,
+                                   dial_sink_added_cb, request_context,
+                                   task_runner),
+      base::OnTaskRunnerDeleter(task_runner));
 }
 
 }  // namespace media_router
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h
index c96f8454..f446346 100644
--- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h
+++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service.h
@@ -72,13 +72,14 @@
   friend class DialMediaSinkServiceTest;
 
   // Marked virtual for tests.
-  virtual std::unique_ptr<DialMediaSinkServiceImpl> CreateImpl(
+  virtual std::unique_ptr<DialMediaSinkServiceImpl, base::OnTaskRunnerDeleter>
+  CreateImpl(
       const OnSinksDiscoveredCallback& sink_discovery_cb,
       const OnDialSinkAddedCallback& dial_sink_added_cb,
       const scoped_refptr<net::URLRequestContextGetter>& request_context);
 
   // Created on the UI thread, used and destroyed on its SequencedTaskRunner.
-  std::unique_ptr<DialMediaSinkServiceImpl> impl_;
+  std::unique_ptr<DialMediaSinkServiceImpl, base::OnTaskRunnerDeleter> impl_;
 
   // Passed to |impl_| when |Start| is called.
   scoped_refptr<net::URLRequestContextGetter> request_context_;
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc
index 309b921..c85b054 100644
--- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc
@@ -71,13 +71,17 @@
       : DialMediaSinkService(context), task_runner_(task_runner) {}
   ~TestDialMediaSinkService() override = default;
 
-  std::unique_ptr<DialMediaSinkServiceImpl> CreateImpl(
-      const OnSinksDiscoveredCallback& sinks_discovered_cb,
-      const OnDialSinkAddedCallback& dial_sink_added_cb,
-      const scoped_refptr<net::URLRequestContextGetter>& request_context)
+  std::unique_ptr<DialMediaSinkServiceImpl, base::OnTaskRunnerDeleter>
+  CreateImpl(const OnSinksDiscoveredCallback& sinks_discovered_cb,
+             const OnDialSinkAddedCallback& dial_sink_added_cb,
+             const scoped_refptr<net::URLRequestContextGetter>& request_context)
       override {
-    auto mock_impl = std::make_unique<MockDialMediaSinkServiceImpl>(
-        sinks_discovered_cb, dial_sink_added_cb, request_context, task_runner_);
+    auto mock_impl = std::unique_ptr<MockDialMediaSinkServiceImpl,
+                                     base::OnTaskRunnerDeleter>(
+        new MockDialMediaSinkServiceImpl(sinks_discovered_cb,
+                                         dial_sink_added_cb, request_context,
+                                         task_runner_),
+        base::OnTaskRunnerDeleter(task_runner_));
     mock_impl_ = mock_impl.get();
     return mock_impl;
   }
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
index 46ef622..a5b5beb 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.cc
@@ -90,7 +90,8 @@
 
 CastMediaSinkService::CastMediaSinkService(
     content::BrowserContext* browser_context)
-    : browser_context_(browser_context) {
+    : impl_(nullptr, base::OnTaskRunnerDeleter(nullptr)),
+      browser_context_(browser_context) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 }
 
@@ -101,8 +102,6 @@
     dns_sd_registry_->RemoveObserver(this);
     dns_sd_registry_ = nullptr;
   }
-  if (impl_)
-    impl_->task_runner()->DeleteSoon(FROM_HERE, impl_.release());
 }
 
 void CastMediaSinkService::Start(
@@ -128,12 +127,19 @@
   }
 }
 
-std::unique_ptr<CastMediaSinkServiceImpl> CastMediaSinkService::CreateImpl(
+std::unique_ptr<CastMediaSinkServiceImpl, base::OnTaskRunnerDeleter>
+CastMediaSinkService::CreateImpl(
     const OnSinksDiscoveredCallback& sinks_discovered_cb) {
-  return std::make_unique<CastMediaSinkServiceImpl>(
-      sinks_discovered_cb, cast_channel::CastSocketService::GetInstance(),
-      DiscoveryNetworkMonitor::GetInstance(),
-      Profile::FromBrowserContext(browser_context_)->GetRequestContext());
+  cast_channel::CastSocketService* cast_socket_service =
+      cast_channel::CastSocketService::GetInstance();
+  scoped_refptr<base::SequencedTaskRunner> task_runner =
+      cast_socket_service->task_runner();
+  return std::unique_ptr<CastMediaSinkServiceImpl, base::OnTaskRunnerDeleter>(
+      new CastMediaSinkServiceImpl(
+          sinks_discovered_cb, cast_socket_service,
+          DiscoveryNetworkMonitor::GetInstance(),
+          Profile::FromBrowserContext(browser_context_)->GetRequestContext()),
+      base::OnTaskRunnerDeleter(task_runner));
 }
 
 void CastMediaSinkService::ForceSinkDiscoveryCallback() {
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
index d768408..7e777a7 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h
@@ -68,8 +68,8 @@
   virtual void OnUserGesture();
 
   // Marked virtual for tests.
-  virtual std::unique_ptr<CastMediaSinkServiceImpl> CreateImpl(
-      const OnSinksDiscoveredCallback& sinks_discovered_cb);
+  virtual std::unique_ptr<CastMediaSinkServiceImpl, base::OnTaskRunnerDeleter>
+  CreateImpl(const OnSinksDiscoveredCallback& sinks_discovered_cb);
   void SetDnsSdRegistryForTest(DnsSdRegistry* registry);
 
  private:
@@ -91,7 +91,7 @@
   DnsSdRegistry* dns_sd_registry_ = nullptr;
 
   // Created on the UI thread, used and destroyed on its SequencedTaskRunner.
-  std::unique_ptr<CastMediaSinkServiceImpl> impl_;
+  std::unique_ptr<CastMediaSinkServiceImpl, base::OnTaskRunnerDeleter> impl_;
 
   // List of cast sinks found in current round of mDNS discovery.
   std::vector<MediaSinkInternal> cast_sinks_;
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc
index 4172c745..a510b8f1 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc
@@ -91,10 +91,13 @@
         network_monitor_(network_monitor) {}
   ~TestCastMediaSinkService() override = default;
 
-  std::unique_ptr<CastMediaSinkServiceImpl> CreateImpl(
-      const OnSinksDiscoveredCallback& sinks_discovered_cb) override {
-    auto mock_impl = std::make_unique<MockCastMediaSinkServiceImpl>(
-        sinks_discovered_cb, cast_socket_service_, network_monitor_);
+  std::unique_ptr<CastMediaSinkServiceImpl, base::OnTaskRunnerDeleter>
+  CreateImpl(const OnSinksDiscoveredCallback& sinks_discovered_cb) override {
+    auto mock_impl = std::unique_ptr<MockCastMediaSinkServiceImpl,
+                                     base::OnTaskRunnerDeleter>(
+        new MockCastMediaSinkServiceImpl(
+            sinks_discovered_cb, cast_socket_service_, network_monitor_),
+        base::OnTaskRunnerDeleter(cast_socket_service_->task_runner()));
     mock_impl_ = mock_impl.get();
     return mock_impl;
   }
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc
index b287f74..e78807d 100644
--- a/chrome/browser/metrics/ukm_browsertest.cc
+++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -123,6 +123,17 @@
   Browser* incognito_browser = CreateIncognitoBrowser();
   EXPECT_FALSE(ukm_enabled());
 
+  // Opening another regular browser mustn't enable UKM.
+  Browser* regular_browser = CreateBrowser(profile);
+  EXPECT_FALSE(ukm_enabled());
+
+  // Opening and closing another Incognito browser mustn't enable UKM.
+  CloseBrowserSynchronously(CreateIncognitoBrowser());
+  EXPECT_FALSE(ukm_enabled());
+
+  CloseBrowserSynchronously(regular_browser);
+  EXPECT_FALSE(ukm_enabled());
+
   CloseBrowserSynchronously(incognito_browser);
   EXPECT_TRUE(ukm_enabled());
   // Client ID should not have been reset.
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 44e551b..b806d9dd 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -36,6 +36,7 @@
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/data_usage/core/data_use_aggregator.h"
 #include "components/domain_reliability/monitor.h"
+#include "components/policy/core/browser/url_blacklist_manager.h"
 #include "components/prefs/pref_member.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_thread.h"
@@ -204,6 +205,7 @@
       force_google_safe_search_(nullptr),
       force_youtube_restrict_(nullptr),
       allowed_domains_for_apps_(nullptr),
+      url_blacklist_manager_(NULL),
       experimental_web_platform_features_enabled_(
           base::CommandLine::ForCurrentProcess()->HasSwitch(
               switches::kEnableExperimentalWebPlatformFeatures)),
@@ -276,6 +278,23 @@
     net::URLRequest* request,
     const net::CompletionCallback& callback,
     GURL* new_url) {
+  // TODO(joaodasilva): This prevents extensions from seeing URLs that are
+  // blocked. However, an extension might redirect the request to another URL,
+  // which is not blocked.
+
+  const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
+  int error = net::ERR_BLOCKED_BY_ADMINISTRATOR;
+  if (info && content::IsResourceTypeFrame(info->GetResourceType()) &&
+      url_blacklist_manager_ &&
+      url_blacklist_manager_->ShouldBlockRequestForFrame(
+          request->url(), &error)) {
+    // URL access blocked by policy.
+    request->net_log().AddEvent(
+        net::NetLogEventType::CHROME_POLICY_ABORTED_REQUEST,
+        net::NetLog::StringCallback("url",
+                                    &request->url().possibly_invalid_spec()));
+    return error;
+  }
 
   extensions_delegate_->ForwardStartRequestStatus(request);
 
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index 964b589..ae49e8a 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -49,6 +49,10 @@
 class URLRequest;
 }
 
+namespace policy {
+class URLBlacklistManager;
+}
+
 // ChromeNetworkDelegate is the central point from within the chrome code to
 // add hooks into the network stack.
 class ChromeNetworkDelegate : public net::NetworkDelegateImpl {
@@ -63,6 +67,11 @@
   // Pass through to ChromeExtensionsNetworkDelegate::set_extension_info_map().
   void set_extension_info_map(extensions::InfoMap* extension_info_map);
 
+  void set_url_blacklist_manager(
+      const policy::URLBlacklistManager* url_blacklist_manager) {
+    url_blacklist_manager_ = url_blacklist_manager;
+  }
+
   // If |profile| is nullptr or not set, events will be broadcast to all
   // profiles, otherwise they will only be sent to the specified profile.
   // Also pass through to ChromeExtensionsNetworkDelegate::set_profile().
@@ -215,6 +224,7 @@
   StringPrefMember* allowed_domains_for_apps_;
 
   // Weak, owned by our owner.
+  const policy::URLBlacklistManager* url_blacklist_manager_;
   std::unique_ptr<domain_reliability::DomainReliabilityMonitor>
       domain_reliability_monitor_;
 
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc
index 81793c4f..2a047ca 100644
--- a/chrome/browser/net/errorpage_browsertest.cc
+++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -244,77 +244,20 @@
   DISALLOW_COPY_AND_ASSIGN(FailFirstNRequestsInterceptor);
 };
 
-// An interceptor that serves LinkDoctor responses.  It also allows waiting
-// until a certain number of requests have been sent.
-// TODO(mmenke):  Wait until responses have been received instead.
+// An interceptor that serves LinkDoctor responses.  It also notifies the
+// provided owner every time there is a new request.
 class LinkDoctorInterceptor : public net::URLRequestInterceptor {
  public:
-  LinkDoctorInterceptor() : num_requests_(0),
-                            requests_to_wait_for_(-1),
-                            weak_factory_(this) {
-  }
-
-  ~LinkDoctorInterceptor() override {}
+  explicit LinkDoctorInterceptor(class ErrorPageTest* owner) : owner_(owner) {}
+  ~LinkDoctorInterceptor() override = default;
 
   // net::URLRequestInterceptor implementation
   net::URLRequestJob* MaybeInterceptRequest(
       net::URLRequest* request,
-      net::NetworkDelegate* network_delegate) const override {
-    DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::BindOnce(&LinkDoctorInterceptor::RequestCreated,
-                       weak_factory_.GetWeakPtr()));
-
-    base::FilePath root_http;
-    PathService::Get(chrome::DIR_TEST_DATA, &root_http);
-    return new net::URLRequestMockHTTPJob(
-        request, network_delegate,
-        root_http.AppendASCII("mock-link-doctor.json"));
-  }
-
-  void WaitForRequests(int32_t requests_to_wait_for) {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    DCHECK_EQ(-1, requests_to_wait_for_);
-    DCHECK(!run_loop_);
-
-    if (requests_to_wait_for >= num_requests_)
-      return;
-
-    requests_to_wait_for_ = requests_to_wait_for;
-    run_loop_.reset(new base::RunLoop());
-    run_loop_->Run();
-    run_loop_.reset();
-    requests_to_wait_for_ = -1;
-    EXPECT_EQ(num_requests_, requests_to_wait_for);
-  }
-
-  // It is up to the caller to wait until all relevant requests has been
-  // created, either through calling WaitForRequests or some other manner,
-  // before calling this method.
-  int32_t num_requests() const {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    return num_requests_;
-  }
+      net::NetworkDelegate* network_delegate) const override;
 
  private:
-  void RequestCreated() {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-    num_requests_++;
-    if (num_requests_ == requests_to_wait_for_)
-      run_loop_->Quit();
-  }
-
-  // These are only used on the UI thread.
-  int32_t num_requests_;
-  int32_t requests_to_wait_for_;
-  std::unique_ptr<base::RunLoop> run_loop_;
-
-  // This prevents any risk of flake if any test doesn't wait for a request
-  // it sent.  Mutable so it can be accessed from a const function.
-  mutable base::WeakPtrFactory<LinkDoctorInterceptor> weak_factory_;
+  ErrorPageTest* owner_;
 
   DISALLOW_COPY_AND_ASSIGN(LinkDoctorInterceptor);
 };
@@ -363,8 +306,8 @@
     HISTORY_NAVIGATE_FORWARD,
   };
 
-  ErrorPageTest() : link_doctor_interceptor_(NULL) {}
-  ~ErrorPageTest() override {}
+  ErrorPageTest() = default;
+  ~ErrorPageTest() override = default;
 
   // Navigates the active tab to a mock url created for the file at |file_path|.
   // Needed for StaleCacheStatus and StaleCacheStatusFailedCorrections tests.
@@ -473,15 +416,17 @@
             (testing::AssertionFailure() << "Exception message is " << result));
   }
 
-  LinkDoctorInterceptor* link_doctor_interceptor() {
-    return link_doctor_interceptor_;
+  void RequestCreated() {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    num_requests_++;
+    if (num_requests_ == requests_to_wait_for_)
+      run_loop_->Quit();
   }
 
  protected:
   void SetUpOnMainThread() override {
-    link_doctor_interceptor_ = new LinkDoctorInterceptor();
     std::unique_ptr<net::URLRequestInterceptor> owned_interceptor(
-        link_doctor_interceptor_);
+        new LinkDoctorInterceptor(this));
     // Ownership of the |interceptor_| is passed to an object the IO thread, but
     // a pointer is kept in the test fixture.  As soon as anything calls
     // URLRequestFilter::ClearHandlers(), |interceptor_| can become invalid.
@@ -509,6 +454,30 @@
 #endif
   }
 
+  void WaitForRequests(int32_t requests_to_wait_for) {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    DCHECK_EQ(-1, requests_to_wait_for_);
+    DCHECK(!run_loop_);
+
+    if (requests_to_wait_for >= num_requests_)
+      return;
+
+    requests_to_wait_for_ = requests_to_wait_for;
+    run_loop_.reset(new base::RunLoop());
+    run_loop_->Run();
+    run_loop_.reset();
+    requests_to_wait_for_ = -1;
+    EXPECT_EQ(num_requests_, requests_to_wait_for);
+  }
+
+  // It is up to the caller to wait until all relevant requests has been
+  // created, either through calling WaitForRequests or some other manner,
+  // before calling this method.
+  int32_t num_requests() const {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    return num_requests_;
+  }
+
  private:
   // Navigates the browser the indicated direction in the history and waits for
   // |num_navigations| to occur and the title to change to |expected_title|.
@@ -540,9 +509,29 @@
     test_navigation_observer.Wait();
   }
 
-  LinkDoctorInterceptor* link_doctor_interceptor_;
+ private:
+  // These are only used on the UI thread.
+  int32_t num_requests_ = 0;
+  int32_t requests_to_wait_for_ = -1;
+  std::unique_ptr<base::RunLoop> run_loop_;
 };
 
+net::URLRequestJob* LinkDoctorInterceptor::MaybeInterceptRequest(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) const {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&ErrorPageTest::RequestCreated, base::Unretained(owner_)));
+
+  base::FilePath root_http;
+  PathService::Get(chrome::DIR_TEST_DATA, &root_http);
+  return new net::URLRequestMockHTTPJob(
+      request, network_delegate,
+      root_http.AppendASCII("mock-link-doctor.json"));
+}
+
 class TestFailProvisionalLoadObserver : public content::WebContentsObserver {
  public:
   explicit TestFailProvisionalLoadObserver(content::WebContents* contents)
@@ -591,7 +580,7 @@
 
   ExpectDisplayingLocalErrorPage(browser(), net::ERR_FILE_NOT_FOUND);
   // Should not request Link Doctor corrections for local errors.
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
   // Only errors on HTTP/HTTPS pages should display a diagnostics button.
   EXPECT_FALSE(IsDisplayingDiagnosticsLink(browser()));
 }
@@ -604,7 +593,7 @@
 
   ExpectDisplayingLocalErrorPage(browser(), net::ERR_FAILED);
   // Should not request Link Doctor corrections for this error.
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // Test that a DNS error occuring in the main frame redirects to an error page.
@@ -614,7 +603,7 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 }
 
 // Test that a DNS error occuring in the main frame does not result in an
@@ -625,7 +614,7 @@
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 }
 
 // Test that a DNS error occuring in the main frame does not result in an
@@ -636,16 +625,16 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   NavigateToFileURL("title3.html");
 
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(2, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(2, num_requests());
 
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
-  EXPECT_EQ(2, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(2, num_requests());
 }
 
 // Test that a DNS error occuring in the main frame does not result in an
@@ -656,19 +645,19 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   NavigateToFileURL("title3.html");
 
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(2, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(2, num_requests());
 
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
 
   GoForwardAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(3, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(3, num_requests());
 }
 
 // Test that a DNS error occuring in the main frame does not result in an
@@ -679,22 +668,22 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   NavigateToFileURL("title2.html");
 
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(2, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(2, num_requests());
 
   GoBackAndWaitForTitle("Title Of More Awesomeness", 1);
 
   GoForwardAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(3, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(3, num_requests());
 
   GoForwardAndWaitForTitle("Title Of Awesomeness", 1);
-  EXPECT_EQ(3, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(3, num_requests());
 }
 
 // Test that the search link on a DNS error page works.
@@ -704,7 +693,7 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -726,8 +715,8 @@
   // There should have been another Link Doctor request, for tracking purposes.
   // Have to wait for it, since the search page does not depend on having
   // sent the tracking request.
-  link_doctor_interceptor()->WaitForRequests(2);
-  EXPECT_EQ(2, link_doctor_interceptor()->num_requests());
+  WaitForRequests(2);
+  EXPECT_EQ(2, num_requests());
 
   // Check the path and query string.
   std::string url;
@@ -741,7 +730,7 @@
   // Go back to the error page, to make sure the history is correct.
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(3, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(3, num_requests());
 }
 
 // Test that the reload button on a DNS error page works.
@@ -751,7 +740,7 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -771,8 +760,8 @@
   // for the new error page, and one for tracking purposes.  Have to make sure
   // to wait for the tracking request, since the new error page does not depend
   // on it.
-  link_doctor_interceptor()->WaitForRequests(3);
-  EXPECT_EQ(3, link_doctor_interceptor()->num_requests());
+  WaitForRequests(3);
+  EXPECT_EQ(3, num_requests());
 }
 
 // Test that the reload button on a DNS error page works after a same document
@@ -785,7 +774,7 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -798,7 +787,7 @@
   // Page being displayed should not change.
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
   // No new requests should have been issued.
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   // Clicking the reload button should load the error page again, and there
   // should be two commits, as before.
@@ -815,8 +804,8 @@
   // for the new error page, and one for tracking purposes.  Have to make sure
   // to wait for the tracking request, since the new error page does not depend
   // on it.
-  link_doctor_interceptor()->WaitForRequests(3);
-  EXPECT_EQ(3, link_doctor_interceptor()->num_requests());
+  WaitForRequests(3);
+  EXPECT_EQ(3, num_requests());
 }
 
 // Test that clicking links on a DNS error page works.
@@ -826,7 +815,7 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -853,8 +842,8 @@
   // There should have been a tracking request to the correction service.  Have
   // to make sure to wait the tracking request, since the new page does not
   // depend on it.
-  link_doctor_interceptor()->WaitForRequests(2);
-  EXPECT_EQ(2, link_doctor_interceptor()->num_requests());
+  WaitForRequests(2);
+  EXPECT_EQ(2, num_requests());
 }
 
 // Test that a DNS error occuring in an iframe does not result in showing
@@ -868,7 +857,7 @@
   EXPECT_EQ(2,
       browser()->tab_strip_model()->GetActiveWebContents()->
           GetController().GetEntryCount());
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // This test fails regularly on win_rel trybots. See crbug.com/121540
@@ -887,7 +876,7 @@
   ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/iframe_dns_error.html"));
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // This test fails regularly on win_rel trybots. See crbug.com/121540
@@ -905,7 +894,7 @@
   NavigateToFileURL("iframe_dns_error.html");
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
   GoForwardAndWaitForTitle("Blah", 1);
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // Test that a DNS error occuring in an iframe, once the main document is
@@ -973,7 +962,7 @@
     EXPECT_EQ(fail_url, fail_observer.fail_url());
     EXPECT_EQ(2, wc->GetController().GetEntryCount());
   }
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // Checks that navigation corrections are not loaded when we receive an actual
@@ -982,7 +971,7 @@
   ASSERT_TRUE(embedded_test_server()->Start());
   NavigateToURLAndWaitForTitle(embedded_test_server()->GetURL("/page404.html"),
                                "SUCCESS", 1);
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // Checks that navigation corrections are loaded in response to a 404 page with
@@ -996,7 +985,7 @@
   // This depends on the non-internationalized error ID string in
   // localized_error.cc.
   ExpectDisplayingNavigationCorrections(browser(), "HTTP ERROR 404");
-  EXPECT_EQ(1, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(1, num_requests());
 }
 
 // Checks that a local error page is shown in response to a 500 error page
@@ -1009,7 +998,7 @@
   // This depends on the non-internationalized error ID string in
   // localized_error.cc.
   ExpectDisplayingLocalErrorPage(browser(), "HTTP ERROR 500");
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // Checks that when an error occurs, the stale cache status of the page
@@ -1053,7 +1042,7 @@
   ui_test_utils::NavigateToURLWithPost(browser(), test_url);
   EXPECT_TRUE(ProbeStaleCopyValue(false));
   EXPECT_FALSE(IsDisplayingText(browser(), GetShowSavedButtonLabel()));
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 
   // Clear the cache and reload the same URL; confirm the error page is told
   // that there is no cached copy.
@@ -1065,7 +1054,7 @@
   ui_test_utils::NavigateToURL(browser(), test_url);
   EXPECT_TRUE(ProbeStaleCopyValue(false));
   EXPECT_FALSE(IsDisplayingText(browser(), GetShowSavedButtonLabel()));
-  EXPECT_EQ(0, link_doctor_interceptor()->num_requests());
+  EXPECT_EQ(0, num_requests());
 }
 
 // Check that the easter egg is present and initialised and is not disabled.
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index 12398d9..78d6d141 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -56,7 +56,8 @@
     return io_thread_network_context_.get();
   }
 
-  if (!network_service_network_context_) {
+  if (!network_service_network_context_ ||
+      network_service_network_context_.encountered_error()) {
     content::mojom::NetworkService* network_service =
         content::GetNetworkService();
     if (!is_quic_allowed_)
@@ -132,6 +133,10 @@
   proxy_config_monitor_.FlushForTesting();
 }
 
+void SystemNetworkContextManager::FlushNetworkInterfaceForTesting() {
+  network_service_network_context_.FlushForTesting();
+}
+
 content::mojom::NetworkContextParamsPtr
 SystemNetworkContextManager::CreateNetworkContextParams() {
   // TODO(mmenke): Set up parameters here (in memory cookie store, etc).
diff --git a/chrome/browser/net/system_network_context_manager.h b/chrome/browser/net/system_network_context_manager.h
index 515e605..5ec05485 100644
--- a/chrome/browser/net/system_network_context_manager.h
+++ b/chrome/browser/net/system_network_context_manager.h
@@ -67,6 +67,9 @@
 
   // Flushes all pending proxy configuration changes.
   void FlushProxyConfigMonitorForTesting();
+  // Call |FlushForTesting()| on Network Service related interfaces. For test
+  // use only.
+  void FlushNetworkInterfaceForTesting();
 
  private:
   // Creates parameters for the NetworkContext. May only be called once, since
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index b967e223..ba6778f0 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -52,6 +52,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/sessions/content/content_record_password_state.h"
 #include "components/signin/core/browser/signin_manager.h"
+#include "components/ukm/content/source_url_recorder.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_security_policy.h"
@@ -487,23 +488,14 @@
 }
 #endif
 
-ukm::UkmRecorder* ChromePasswordManagerClient::GetUkmRecorder() {
-  return ukm::UkmRecorder::Get();
-}
-
 ukm::SourceId ChromePasswordManagerClient::GetUkmSourceId() {
-  // TODO(crbug.com/732846): The UKM Source should be recycled (e.g. from the
-  // web contents), once the UKM framework provides a mechanism for that.
-  if (!ukm_source_id_)
-    ukm_source_id_ = ukm::UkmRecorder::GetNewSourceID();
-  return *ukm_source_id_;
+  return ukm::GetSourceIdForWebContentsDocument(web_contents());
 }
 
 PasswordManagerMetricsRecorder&
 ChromePasswordManagerClient::GetMetricsRecorder() {
   if (!metrics_recorder_) {
-    metrics_recorder_.emplace(GetUkmRecorder(), GetUkmSourceId(),
-                              GetMainFrameURL());
+    metrics_recorder_.emplace(GetUkmSourceId(), GetMainFrameURL());
   }
   return metrics_recorder_.value();
 }
@@ -514,7 +506,6 @@
     return;
 
   if (!navigation_handle->IsSameDocument()) {
-    ukm_source_id_.reset();
     // Send any collected metrics by destroying the metrics recorder.
     metrics_recorder_.reset();
   }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index e24901e..3c21a23e 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -129,7 +129,6 @@
   void LogPasswordReuseDetectedEvent() override;
 #endif
 
-  ukm::UkmRecorder* GetUkmRecorder() override;
   ukm::SourceId GetUkmSourceId() override;
   password_manager::PasswordManagerMetricsRecorder& GetMetricsRecorder()
       override;
@@ -228,10 +227,6 @@
 
   std::unique_ptr<password_manager::LogManager> log_manager_;
 
-  // If set, this stores a ukm::SourceId that is bound to the last committed
-  // navigation of the tab owning this ChromePasswordManagerClient.
-  base::Optional<ukm::SourceId> ukm_source_id_;
-
   // Recorder of metrics that is associated with the last committed navigation
   // of the WebContents owning this ChromePasswordManagerClient. May be unset at
   // times. Sends statistics on destruction.
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc b/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc
index da37ef6..4125387 100644
--- a/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc
+++ b/chrome/browser/password_manager/save_password_infobar_delegate_android_unittest.cc
@@ -183,12 +183,12 @@
   SCOPED_TRACE(::testing::Message() << "dismissal_reason = "
                                     << static_cast<int64_t>(dismissal_reason));
 
+  ukm::SourceId expected_source_id = ukm::UkmRecorder::GetNewSourceID();
   ukm::TestAutoSetUkmRecorder test_ukm_recorder;
   {
     // Setup metrics recorder
     auto recorder = base::MakeRefCounted<PasswordFormMetricsRecorder>(
-        true /*is_main_frame_secure*/, &test_ukm_recorder,
-        test_ukm_recorder.GetNewSourceID(), GURL("https://www.example.com/"));
+        true /*is_main_frame_secure*/, expected_source_id);
 
     // Exercise delegate.
     std::unique_ptr<MockPasswordFormManager> password_form_manager(
@@ -218,8 +218,7 @@
       test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* entry : entries) {
-    test_ukm_recorder.ExpectEntrySourceHasUrl(entry,
-                                              GURL("https://www.example.com/"));
+    EXPECT_EQ(expected_source_id, entry->source_id);
     test_ukm_recorder.ExpectEntryMetric(entry,
                                         UkmEntry::kSaving_Prompt_ShownName, 1);
     test_ukm_recorder.ExpectEntryMetric(
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 6a862154..e134289 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -724,6 +724,11 @@
   { key::kSitePerProcess,
     prefs::kSitePerProcess,
     base::Value::Type::BOOLEAN },
+
+  { key::kAbusiveExperienceInterventionEnforce,
+    prefs::kAbusiveExperienceInterventionEnforce,
+    base::Value::Type::BOOLEAN },
+
 };
 // clang-format on
 
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index e0cee2a..385f6fcb 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -56,6 +56,7 @@
 #include "chrome/browser/task_manager/task_manager_interface.h"
 #include "chrome/browser/tracing/chrome_tracing_delegate.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
+#include "chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h"
 #include "chrome/browser/ui/browser_ui_prefs.h"
 #include "chrome/browser/ui/navigation_correction_tab_observer.h"
 #include "chrome/browser/ui/network_profile_bubble.h"
@@ -173,6 +174,7 @@
 #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h"
 #include "chrome/browser/android/ntp/content_suggestions_notifier_service.h"
 #include "chrome/browser/android/ntp/recent_tabs_page_prefs.h"
+#include "chrome/browser/android/oom_intervention/oom_intervention_decider.h"
 #include "chrome/browser/android/preferences/browser_prefs_android.h"
 #include "chrome/browser/geolocation/geolocation_permission_context_android.h"
 #include "chrome/browser/ntp_snippets/download_suggestions_provider.h"
@@ -513,6 +515,7 @@
   RegisterBrowserUserPrefs(registry);
   safe_browsing::RegisterProfilePrefs(registry);
   secure_origin_whitelist::RegisterProfilePrefs(registry);
+  SafeBrowsingTriggeredPopupBlocker::RegisterProfilePrefs(registry);
   SessionStartupPref::RegisterProfilePrefs(registry);
   signin::RegisterAccountConsistencyProfilePrefs(registry);
   syncer::SyncPrefs::RegisterProfilePrefs(registry);
@@ -594,6 +597,7 @@
   ntp_snippets::RecentTabSuggestionsProvider::RegisterProfilePrefs(registry);
   ntp_snippets::SubscriptionManagerImpl::RegisterProfilePrefs(registry);
   OmniboxFieldTrial::RegisterProfilePrefs(registry);
+  OomInterventionDecider::RegisterProfilePrefs(registry);
 #endif  // defined(OS_ANDROID)
 
 #if !defined(OS_ANDROID)
diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc
index d2cbc7e..c75a3a2 100644
--- a/chrome/browser/printing/pdf_to_emf_converter.cc
+++ b/chrome/browser/printing/pdf_to_emf_converter.cc
@@ -25,11 +25,14 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/common/chrome_utility_printing_messages.h"
+#include "chrome/common/printing/pdf_to_emf_converter.mojom.h"
 #include "chrome/grit/generated_resources.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/utility_process_host.h"
 #include "content/public/browser/utility_process_host_client.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/platform_handle.h"
 #include "printing/emf_win.h"
 #include "printing/pdf_render_settings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -95,6 +98,55 @@
   DISALLOW_COPY_AND_ASSIGN(TempFile);
 };
 
+class PdfToEmfConverterClientImpl : public mojom::PdfToEmfConverterClient {
+ public:
+  explicit PdfToEmfConverterClientImpl(
+      mojom::PdfToEmfConverterClientRequest request)
+      : binding_(this, std::move(request)) {}
+
+ private:
+  // mojom::PdfToEmfConverterClient implementation.
+  void PreCacheFontCharacters(
+      const std::vector<uint8_t>& logfont_data,
+      const base::string16& characters,
+      PreCacheFontCharactersCallback callback) override {
+    // TODO(scottmg): pdf/ppapi still require the renderer to be able to
+    // precache GDI fonts (http://crbug.com/383227), even when using
+    // DirectWrite. Eventually this shouldn't be added and should be moved to
+    // FontCacheDispatcher too. http://crbug.com/356346.
+
+    // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here
+    // too. Except that for True Type fonts, GetTextMetrics will not load the
+    // font in memory. The only way windows seem to load properly, it is to
+    // create a similar device (like the one in which we print), then do an
+    // ExtTextOut, as we do in the printing thread, which is sandboxed.
+    const LOGFONT* logfont =
+        reinterpret_cast<const LOGFONT*>(&logfont_data.at(0));
+
+    HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr);
+    HFONT font_handle = CreateFontIndirect(logfont);
+    DCHECK(font_handle != nullptr);
+
+    HGDIOBJ old_font = SelectObject(hdc, font_handle);
+    DCHECK(old_font != nullptr);
+
+    ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, characters.c_str(),
+               characters.length(), nullptr);
+
+    SelectObject(hdc, old_font);
+    DeleteObject(font_handle);
+
+    HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
+
+    if (metafile)
+      DeleteEnhMetaFile(metafile);
+
+    std::move(callback).Run();
+  }
+
+  mojo::Binding<mojom::PdfToEmfConverterClient> binding_;
+};
+
 using ScopedTempFile = std::unique_ptr<TempFile>;
 
 // Wrapper for Emf to keep only file handle in memory, and load actual data only
@@ -162,10 +214,10 @@
       const PdfRenderSettings& settings);
 
   void Start(const scoped_refptr<base::RefCountedMemory>& data,
-             const PdfConverter::StartCallback& start_callback);
+             PdfConverter::StartCallback start_callback);
 
   void GetPage(int page_number,
-               const PdfConverter::GetPageCallback& get_page_callback);
+               PdfConverter::GetPageCallback get_page_callback);
 
   void Stop();
 
@@ -173,15 +225,11 @@
   void OnProcessCrashed(int exit_code) override;
   void OnProcessLaunchFailed(int exit_code) override;
 
-  // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
-  // sync message replies.
-  bool Send(IPC::Message* msg);
-
  private:
   class GetPageCallbackData {
    public:
     GetPageCallbackData(int page_number, PdfConverter::GetPageCallback callback)
-        : page_number_(page_number), callback_(callback) {}
+        : page_number_(page_number), callback_(std::move(callback)) {}
 
     GetPageCallbackData(GetPageCallbackData&& other) {
       *this = std::move(other);
@@ -189,13 +237,15 @@
 
     GetPageCallbackData& operator=(GetPageCallbackData&& rhs) {
       page_number_ = rhs.page_number_;
-      callback_ = rhs.callback_;
+      callback_ = std::move(rhs.callback_);
       file_ = std::move(rhs.file_);
       return *this;
     }
 
     int page_number() const { return page_number_; }
-    const PdfConverter::GetPageCallback& callback() const { return callback_; }
+    PdfConverter::GetPageCallback TakeCallback() {
+      return std::move(callback_);
+    }
     ScopedTempFile TakeFile() { return std::move(file_); }
     void set_file(ScopedTempFile file) { file_ = std::move(file); }
 
@@ -217,16 +267,14 @@
   base::string16 GetName() const;
   // Create a metafileplayer subclass file from a temporary file.
   std::unique_ptr<MetafilePlayer> GetFileFromTemp(ScopedTempFile temp_file);
-  // Send the messages to Start, GetPage, and Stop.
-  void SendStartMessage(IPC::PlatformFileForTransit transit);
-  void SendGetPageMessage(int page_number, IPC::PlatformFileForTransit transit);
-  void SendStopMessage();
 
   // Message handlers:
-  void OnPageCount(int page_count);
+  void OnPageCount(mojom::PdfToEmfConverterFactoryPtr factory_keep_alive,
+                   mojom::PdfToEmfConverterPtr converter,
+                   uint32_t page_count);
   void OnPageDone(bool success, float scale_factor);
 
-  void OnFailed();
+  void OnFailed(const std::string& error_message);
   void OnTempPdfReady(ScopedTempFile pdf);
   void OnTempFileReady(GetPageCallbackData* callback_data,
                        ScopedTempFile temp_file);
@@ -255,6 +303,11 @@
 
   const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
 
+  std::unique_ptr<PdfToEmfConverterClientImpl>
+      pdf_to_emf_converter_client_impl_;
+
+  mojom::PdfToEmfConverterPtr pdf_to_emf_converter_;
+
   DISALLOW_COPY_AND_ASSIGN(PdfConverterUtilityProcessHostClient);
 };
 
@@ -282,18 +335,17 @@
 
   void Start(const scoped_refptr<base::RefCountedMemory>& data,
              const PdfRenderSettings& conversion_settings,
-             const StartCallback& start_callback);
+             StartCallback start_callback);
 
-  void GetPage(int page_number,
-               const GetPageCallback& get_page_callback) override;
+  void GetPage(int page_number, GetPageCallback get_page_callback) override;
 
   // Helps to cancel callbacks if this object is destroyed.
-  void RunCallback(const base::Closure& callback);
+  void RunCallback(base::OnceClosure callback);
 
   void Start(
       const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
       const scoped_refptr<base::RefCountedMemory>& data,
-      const StartCallback& start_callback);
+      StartCallback start_callback);
 
  private:
   scoped_refptr<PdfConverterUtilityProcessHostClient> utility_client_;
@@ -424,17 +476,18 @@
 
 void PdfConverterUtilityProcessHostClient::Start(
     const scoped_refptr<base::RefCountedMemory>& data,
-    const PdfConverter::StartCallback& start_callback) {
+    PdfConverter::StartCallback start_callback) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data,
-                   start_callback));
+        base::BindOnce(&PdfConverterUtilityProcessHostClient::Start, this, data,
+                       std::move(start_callback)));
     return;
   }
 
   // Store callback before any OnFailed() call to make it called on failure.
-  start_callback_ = start_callback;
+  DCHECK(start_callback);
+  start_callback_ = std::move(start_callback);
 
   // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load
   // gdiplus.dll, change how rendering happens, and not be able to correctly
@@ -443,6 +496,7 @@
                               this, base::ThreadTaskRunnerHandle::Get())
                               ->AsWeakPtr();
   utility_process_host_->SetName(GetName());
+  utility_process_host_->Start();
 
   base::PostTaskAndReplyWithResult(
       blocking_task_runner_.get(), FROM_HERE,
@@ -453,79 +507,107 @@
 void PdfConverterUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!utility_process_host_ || !pdf)
-    return OnFailed();
-  // Should reply with OnPageCount().
-  SendStartMessage(
-      IPC::GetPlatformFileForTransit(pdf->file().GetPlatformFile(), false));
+    return OnFailed(std::string("Failed to create temporary PDF file."));
+
+  mojom::PdfToEmfConverterFactoryPtr pdf_to_emf_converter_factory_ptr;
+  utility_process_host_->BindInterface(
+      mojom::PdfToEmfConverterFactory::Name_,
+      mojo::MakeRequest(&pdf_to_emf_converter_factory_ptr).PassMessagePipe());
+
+  pdf_to_emf_converter_factory_ptr.set_connection_error_handler(base::BindOnce(
+      &PdfConverterUtilityProcessHostClient::OnFailed, this,
+      std::string("Connection to PdfToEmfConverterFactory error.")));
+
+  mojom::PdfToEmfConverterClientPtr pdf_to_emf_converter_client_ptr;
+  pdf_to_emf_converter_client_impl_ =
+      std::make_unique<PdfToEmfConverterClientImpl>(
+          mojo::MakeRequest(&pdf_to_emf_converter_client_ptr));
+
+  pdf_to_emf_converter_factory_ptr->CreateConverter(
+      mojo::WrapPlatformFile(pdf->file().TakePlatformFile()), settings_,
+      std::move(pdf_to_emf_converter_client_ptr),
+      base::BindOnce(&PdfConverterUtilityProcessHostClient::OnPageCount, this,
+                     std::move(pdf_to_emf_converter_factory_ptr)));
 }
 
-void PdfConverterUtilityProcessHostClient::OnPageCount(int page_count) {
+void PdfConverterUtilityProcessHostClient::OnPageCount(
+    mojom::PdfToEmfConverterFactoryPtr factory_keep_alive,
+    mojom::PdfToEmfConverterPtr converter,
+    uint32_t page_count) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (start_callback_.is_null())
-    return OnFailed();
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                          base::Bind(&PdfConverterImpl::RunCallback, converter_,
-                                     base::Bind(start_callback_, page_count)));
-  start_callback_.Reset();
+  DCHECK(!pdf_to_emf_converter_.is_bound());
+  pdf_to_emf_converter_ = std::move(converter);
+
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&PdfConverterImpl::RunCallback, converter_,
+                     base::BindOnce(std::move(start_callback_), page_count)));
 }
 
 void PdfConverterUtilityProcessHostClient::GetPage(
     int page_number,
-    const PdfConverter::GetPageCallback& get_page_callback) {
+    PdfConverter::GetPageCallback get_page_callback) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(&PdfConverterUtilityProcessHostClient::GetPage, this,
-                   page_number, get_page_callback));
+        base::BindOnce(&PdfConverterUtilityProcessHostClient::GetPage, this,
+                       page_number, std::move(get_page_callback)));
     return;
   }
 
   // Store callback before any OnFailed() call to make it called on failure.
-  get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback));
+  get_page_callbacks_.push(
+      GetPageCallbackData(page_number, std::move(get_page_callback)));
 
   if (!utility_process_host_)
-    return OnFailed();
+    return OnFailed(std::string("No process utility host."));
 
   base::PostTaskAndReplyWithResult(
       blocking_task_runner_.get(), FROM_HERE,
-      base::Bind(&CreateTempFile, &temp_dir_),
-      base::Bind(&PdfConverterUtilityProcessHostClient::OnTempFileReady, this,
-                 &get_page_callbacks_.back()));
+      base::BindOnce(&CreateTempFile, &temp_dir_),
+      base::BindOnce(&PdfConverterUtilityProcessHostClient::OnTempFileReady,
+                     this, &get_page_callbacks_.back()));
 }
 
 void PdfConverterUtilityProcessHostClient::OnTempFileReady(
     GetPageCallbackData* callback_data,
     ScopedTempFile temp_file) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(pdf_to_emf_converter_.is_bound());
+
   if (!utility_process_host_ || !temp_file)
-    return OnFailed();
-  IPC::PlatformFileForTransit transit = IPC::GetPlatformFileForTransit(
-      temp_file->file().GetPlatformFile(), false);
+    return OnFailed(std::string("Error creating utility process host"));
+
+  // We need to dup the file as mojo::WrapPlatformFile takes ownership of the
+  // passed file.
+  base::File temp_file_copy = temp_file->file().Duplicate();
+  pdf_to_emf_converter_->ConvertPage(
+      callback_data->page_number(),
+      mojo::WrapPlatformFile(temp_file_copy.TakePlatformFile()),
+      base::BindOnce(&PdfConverterUtilityProcessHostClient::OnPageDone, this));
   callback_data->set_file(std::move(temp_file));
-  // Should reply with OnPageDone().
-  SendGetPageMessage(callback_data->page_number(), transit);
 }
 
 void PdfConverterUtilityProcessHostClient::OnPageDone(bool success,
                                                       float scale_factor) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (get_page_callbacks_.empty())
-    return OnFailed();
+    return OnFailed(std::string("No get_page callbacks."));
   GetPageCallbackData& data = get_page_callbacks_.front();
   std::unique_ptr<MetafilePlayer> file;
 
   if (success) {
     ScopedTempFile temp_file = data.TakeFile();
     if (!temp_file)  // Unexpected message from utility process.
-      return OnFailed();
+      return OnFailed("No temp file.");
     file = GetFileFromTemp(std::move(temp_file));
   }
 
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
-      base::Bind(&PdfConverterImpl::RunCallback, converter_,
-                 base::Bind(data.callback(), data.page_number(), scale_factor,
-                            base::Passed(&file))));
+      base::BindOnce(&PdfConverterImpl::RunCallback, converter_,
+                     base::BindOnce(data.TakeCallback(), data.page_number(),
+                                    scale_factor, std::move(file))));
   get_page_callbacks_.pop();
 }
 
@@ -536,29 +618,28 @@
         base::Bind(&PdfConverterUtilityProcessHostClient::Stop, this));
     return;
   }
-  SendStopMessage();
+  // Disconnect the PdfToEmfConverterPtr, it will lead to the closing of the
+  // utility process.
+  pdf_to_emf_converter_.reset();
 }
 
 void PdfConverterUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
-  OnFailed();
+  OnFailed("Utility process host crashed.");
 }
 
 void PdfConverterUtilityProcessHostClient::OnProcessLaunchFailed(
     int exit_code) {
-  OnFailed();
+  OnFailed("Process launch failed");
 }
 
-bool PdfConverterUtilityProcessHostClient::Send(IPC::Message* msg) {
-  if (utility_process_host_)
-    return utility_process_host_->Send(msg);
-  delete msg;
-  return false;
-}
-
-void PdfConverterUtilityProcessHostClient::OnFailed() {
+void PdfConverterUtilityProcessHostClient::OnFailed(
+    const std::string& error_message) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (!start_callback_.is_null())
-    OnPageCount(0);
+  LOG(ERROR) << "Failed to convert PDF: " << error_message;
+  if (!start_callback_.is_null()) {
+    OnPageCount(mojom::PdfToEmfConverterFactoryPtr(),
+                mojom::PdfToEmfConverterPtr(), 0);
+  }
   while (!get_page_callbacks_.empty())
     OnPageDone(false, 0.0f);
   utility_process_host_.reset();
@@ -599,39 +680,13 @@
 
 bool PdfConverterUtilityProcessHostClient::OnMessageReceived(
     const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(PdfConverterUtilityProcessHostClient, message)
-    IPC_MESSAGE_HANDLER(
-        ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
-    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
-                        OnPageDone)
-    IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters,
-                        OnPreCacheFontCharacters)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
+  return false;
 }
 
 base::string16 PdfConverterUtilityProcessHostClient::GetName() const {
   return l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PDF_CONVERTOR_NAME);
 }
 
-void PdfConverterUtilityProcessHostClient::SendGetPageMessage(
-    int page_number,
-    IPC::PlatformFileForTransit transit) {
-  Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number,
-                                                              transit));
-}
-
-void PdfConverterUtilityProcessHostClient::SendStartMessage(
-    IPC::PlatformFileForTransit transit) {
-  Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_));
-}
-
-void PdfConverterUtilityProcessHostClient::SendStopMessage() {
-  Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
-}
-
 // Pdf Converter Impl and subclasses
 PdfConverterImpl::PdfConverterImpl() : weak_ptr_factory_(this) {}
 
@@ -641,22 +696,22 @@
 }
 
 void PdfConverterImpl::Start(
-      const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
-      const scoped_refptr<base::RefCountedMemory>& data,
-      const StartCallback& start_callback) {
-    DCHECK(!utility_client_);
-    utility_client_ = utility_client;
-    utility_client_->Start(data, start_callback);
+    const scoped_refptr<PdfConverterUtilityProcessHostClient>& utility_client,
+    const scoped_refptr<base::RefCountedMemory>& data,
+    StartCallback start_callback) {
+  DCHECK(!utility_client_);
+  utility_client_ = utility_client;
+  utility_client_->Start(data, std::move(start_callback));
 }
 
 void PdfConverterImpl::GetPage(int page_number,
-                               const GetPageCallback& get_page_callback) {
-  utility_client_->GetPage(page_number, get_page_callback);
+                               GetPageCallback get_page_callback) {
+  utility_client_->GetPage(page_number, std::move(get_page_callback));
 }
 
-void PdfConverterImpl::RunCallback(const base::Closure& callback) {
+void PdfConverterImpl::RunCallback(base::OnceClosure callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  callback.Run();
+  std::move(callback).Run();
 }
 
 }  // namespace
@@ -667,13 +722,12 @@
 std::unique_ptr<PdfConverter> PdfConverter::StartPdfConverter(
     const scoped_refptr<base::RefCountedMemory>& data,
     const PdfRenderSettings& conversion_settings,
-    const StartCallback& start_callback) {
+    StartCallback start_callback) {
   std::unique_ptr<PdfConverterImpl> converter =
       base::MakeUnique<PdfConverterImpl>();
-  converter->Start(
-      new PdfConverterUtilityProcessHostClient(converter->GetWeakPtr(),
-                                               conversion_settings),
-          data, start_callback);
+  converter->Start(new PdfConverterUtilityProcessHostClient(
+                       converter->GetWeakPtr(), conversion_settings),
+                   data, std::move(start_callback));
   return std::move(converter);
 }
 
diff --git a/chrome/browser/printing/pdf_to_emf_converter.h b/chrome/browser/printing/pdf_to_emf_converter.h
index 9990400a..9bad0f4f 100644
--- a/chrome/browser/printing/pdf_to_emf_converter.h
+++ b/chrome/browser/printing/pdf_to_emf_converter.h
@@ -17,11 +17,11 @@
 
 class PdfConverter {
  public:
-  using StartCallback = base::Callback<void(int page_count)>;
+  using StartCallback = base::OnceCallback<void(int page_count)>;
   using GetPageCallback =
-      base::Callback<void(int page_number,
-                          float scale_factor,
-                          std::unique_ptr<MetafilePlayer> file)>;
+      base::OnceCallback<void(int page_number,
+                              float scale_factor,
+                              std::unique_ptr<MetafilePlayer> file)>;
   virtual ~PdfConverter();
 
   // Starts conversion of PDF provided as |data|. Calls |start_callback|
@@ -29,14 +29,13 @@
   static std::unique_ptr<PdfConverter> StartPdfConverter(
       const scoped_refptr<base::RefCountedMemory>& data,
       const PdfRenderSettings& conversion_settings,
-      const StartCallback& start_callback);
+      StartCallback start_callback);
 
   // Requests conversion of the page. |page_number| is 0-base page number in
   // PDF provided in Start() call.
   // Calls |get_page_callback| after conversion. |emf| of callback in not NULL
   // if conversion succeeded.
-  virtual void GetPage(int page_number,
-                       const GetPageCallback& get_page_callback) = 0;
+  virtual void GetPage(int page_number, GetPageCallback get_page_callback) = 0;
 };
 }  // namespace printing
 
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc
index 77b41a51..e8b4a70c 100644
--- a/chrome/browser/printing/print_job.cc
+++ b/chrome/browser/printing/print_job.cc
@@ -23,11 +23,11 @@
 #include "chrome/browser/printing/print_job_worker.h"
 #include "content/public/browser/notification_service.h"
 #include "printing/printed_document.h"
-#include "printing/printed_page.h"
 
 #if defined(OS_WIN)
 #include "chrome/browser/printing/pdf_to_emf_converter.h"
 #include "printing/pdf_render_settings.h"
+#include "printing/printed_page_win.h"
 #endif
 
 using base::TimeDelta;
@@ -130,8 +130,8 @@
   is_job_pending_ = true;
 
   // Tell everyone!
-  scoped_refptr<JobEventDetails> details(new JobEventDetails(
-      JobEventDetails::NEW_DOC, 0, document_.get(), nullptr));
+  scoped_refptr<JobEventDetails> details(
+      new JobEventDetails(JobEventDetails::NEW_DOC, 0, document_.get()));
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_PRINT_JOB_EVENT,
       content::Source<PrintJob>(this),
@@ -176,7 +176,7 @@
   }
   // Make sure a Cancel() is broadcast.
   scoped_refptr<JobEventDetails> details(
-      new JobEventDetails(JobEventDetails::FAILED, 0, nullptr, nullptr));
+      new JobEventDetails(JobEventDetails::FAILED, 0, nullptr));
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_PRINT_JOB_EVENT,
       content::Source<PrintJob>(this),
@@ -218,23 +218,23 @@
 
   void Start(const scoped_refptr<base::RefCountedMemory>& data,
              const PdfRenderSettings& conversion_settings,
-             const PdfConverter::StartCallback& start_callback) {
-    converter_ = PdfConverter::StartPdfConverter(
-          data, conversion_settings, start_callback);
+             PdfConverter::StartCallback start_callback) {
+    converter_ = PdfConverter::StartPdfConverter(data, conversion_settings,
+                                                 std::move(start_callback));
   }
 
-  void GetMorePages(const PdfConverter::GetPageCallback& get_page_callback) {
+  void GetMorePages(PdfConverter::GetPageCallback get_page_callback) {
     const int kMaxNumberOfTempFilesPerDocument = 3;
     while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument &&
            current_page_ < page_count_) {
       ++pages_in_progress_;
-      converter_->GetPage(current_page_++, get_page_callback);
+      converter_->GetPage(current_page_++, std::move(get_page_callback));
     }
   }
 
-  void OnPageProcessed(const PdfConverter::GetPageCallback& get_page_callback) {
+  void OnPageProcessed(PdfConverter::GetPageCallback get_page_callback) {
     --pages_in_progress_;
-    GetMorePages(get_page_callback);
+    GetMorePages(std::move(get_page_callback));
     // Release converter if we don't need this any more.
     if (!pages_in_progress_ && current_page_ >= page_count_)
       converter_.reset();
@@ -407,8 +407,8 @@
   // Stop the worker thread.
   Stop();
 
-  scoped_refptr<JobEventDetails> details(new JobEventDetails(
-      JobEventDetails::JOB_DONE, 0, document_.get(), nullptr));
+  scoped_refptr<JobEventDetails> details(
+      new JobEventDetails(JobEventDetails::JOB_DONE, 0, document_.get()));
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_PRINT_JOB_EVENT,
       content::Source<PrintJob>(this),
@@ -464,18 +464,25 @@
   base::RunLoop::QuitCurrentWhenIdleDeprecated();
 }
 
-// Takes settings_ ownership and will be deleted in the receiving thread.
+#if defined(OS_WIN)
 JobEventDetails::JobEventDetails(Type type,
                                  int job_id,
                                  PrintedDocument* document,
                                  PrintedPage* page)
     : document_(document), page_(page), type_(type), job_id_(job_id) {}
+#endif
+
+JobEventDetails::JobEventDetails(Type type,
+                                 int job_id,
+                                 PrintedDocument* document)
+    : document_(document), type_(type), job_id_(job_id) {}
 
 JobEventDetails::~JobEventDetails() {
 }
 
 PrintedDocument* JobEventDetails::document() const { return document_.get(); }
 
+#if defined(OS_WIN)
 PrintedPage* JobEventDetails::page() const { return page_.get(); }
-
+#endif
 }  // namespace printing
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h
index 417a1be0..9b57e52 100644
--- a/chrome/browser/printing/print_job.h
+++ b/chrome/browser/printing/print_job.h
@@ -25,7 +25,9 @@
 class MetafilePlayer;
 class PrintJobWorker;
 class PrintedDocument;
+#if defined(OS_WIN)
 class PrintedPage;
+#endif
 class PrinterQuery;
 
 // Manages the print work for a specific document. Talks to the printer through
@@ -206,14 +208,19 @@
 #endif
   };
 
+#if defined(OS_WIN)
   JobEventDetails(Type type,
                   int job_id,
                   PrintedDocument* document,
                   PrintedPage* page);
+#endif
+  JobEventDetails(Type type, int job_id, PrintedDocument* document);
 
   // Getters.
   PrintedDocument* document() const;
+#if defined(OS_WIN)
   PrintedPage* page() const;
+#endif
   Type type() const {
     return type_;
   }
@@ -225,7 +232,9 @@
   ~JobEventDetails();
 
   scoped_refptr<PrintedDocument> document_;
+#if defined(OS_WIN)
   scoped_refptr<PrintedPage> page_;
+#endif
   const Type type_;
   int job_id_;
 
diff --git a/chrome/browser/printing/print_job_manager.cc b/chrome/browser/printing/print_job_manager.cc
index 29e5d0163..c733e6f 100644
--- a/chrome/browser/printing/print_job_manager.cc
+++ b/chrome/browser/printing/print_job_manager.cc
@@ -11,7 +11,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "printing/printed_document.h"
-#include "printing/printed_page.h"
 
 namespace printing {
 
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 425a05f..b4ff1b3 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -28,7 +28,6 @@
 #include "content/public/browser/web_contents.h"
 #include "printing/print_job_constants.h"
 #include "printing/printed_document.h"
-#include "printing/printed_page.h"
 #include "printing/printing_utils.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -36,6 +35,10 @@
 #include "chrome/browser/android/tab_android.h"
 #endif
 
+#if defined(OS_WIN)
+#include "printing/printed_page_win.h"
+#endif
+
 using content::BrowserThread;
 
 namespace printing {
@@ -96,10 +99,8 @@
 void NotificationCallback(PrintJobWorkerOwner* print_job,
                           JobEventDetails::Type detail_type,
                           int job_id,
-                          PrintedDocument* document,
-                          PrintedPage* page) {
-  JobEventDetails* details =
-      new JobEventDetails(detail_type, job_id, document, page);
+                          PrintedDocument* document) {
+  JobEventDetails* details = new JobEventDetails(detail_type, job_id, document);
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_PRINT_JOB_EVENT,
       // We know that is is a PrintJob object in this circumstance.
@@ -114,6 +115,22 @@
                                         base::Bind(callback, result)));
 }
 
+#if defined(OS_WIN)
+void PageNotificationCallback(PrintJobWorkerOwner* print_job,
+                              JobEventDetails::Type detail_type,
+                              int job_id,
+                              PrintedDocument* document,
+                              PrintedPage* page) {
+  JobEventDetails* details =
+      new JobEventDetails(detail_type, job_id, document, page);
+  content::NotificationService::current()->Notify(
+      chrome::NOTIFICATION_PRINT_JOB_EVENT,
+      // We know that is is a PrintJob object in this circumstance.
+      content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
+      content::Details<JobEventDetails>(details));
+}
+#endif
+
 }  // namespace
 
 PrintJobWorker::PrintJobWorker(int render_process_id,
@@ -303,6 +320,15 @@
   document_ = new_document;
 }
 
+void PrintJobWorker::PostWaitForPage() {
+  // We need to wait for the page to be available.
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(&PrintJobWorker::OnNewPage, weak_factory_.GetWeakPtr()),
+      base::TimeDelta::FromMilliseconds(500));
+}
+
+#if defined(OS_WIN)
 void PrintJobWorker::OnNewPage() {
   if (!document_.get())  // Spurious message.
     return;
@@ -322,18 +348,12 @@
     // We have enough information to initialize page_number_.
     page_number_.Init(document_->settings(), page_count);
   }
-  DCHECK_NE(page_number_, PageNumber::npos());
 
+  DCHECK_NE(page_number_, PageNumber::npos());
   while (true) {
-    // Is the page available?
     scoped_refptr<PrintedPage> page = document_->GetPage(page_number_.ToInt());
     if (!page.get()) {
-      // We need to wait for the page to be available.
-      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE,
-          base::BindOnce(&PrintJobWorker::OnNewPage,
-                         weak_factory_.GetWeakPtr()),
-          base::TimeDelta::FromMilliseconds(500));
+      PostWaitForPage();
       break;
     }
     // The page is there, print it.
@@ -346,6 +366,24 @@
     }
   }
 }
+#else
+void PrintJobWorker::OnNewPage() {
+  if (!document_.get())  // Spurious message.
+    return;
+
+  // message_loop() could return NULL when the print job is cancelled.
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+  const MetafilePlayer* metafile = document_->GetMetafile();
+  if (!metafile) {
+    PostWaitForPage();
+    return;
+  }
+  SpoolJob();
+  // Don't touch this anymore since the instance could be destroyed.
+  OnDocumentDone();
+}
+#endif  // defined(OS_WIN)
 
 void PrintJobWorker::Cancel() {
   // This is the only function that can be called from any thread.
@@ -393,12 +431,13 @@
   owner_->PostTask(FROM_HERE,
                    base::Bind(&NotificationCallback, base::RetainedRef(owner_),
                               JobEventDetails::DOC_DONE, job_id,
-                              base::RetainedRef(document_), nullptr));
+                              base::RetainedRef(document_)));
 
   // Makes sure the variables are reinitialized.
   document_ = NULL;
 }
 
+#if defined(OS_WIN)
 void PrintJobWorker::SpoolPage(PrintedPage* page) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK_NE(page_number_, PageNumber::npos());
@@ -410,11 +449,7 @@
   }
 
   // Actual printing.
-#if defined(OS_WIN) || defined(OS_MACOSX)
   document_->RenderPrintedPage(*page, printing_context_->context());
-#elif defined(OS_POSIX)
-  document_->RenderPrintedPage(*page, printing_context_.get());
-#endif
 
   // Postprocess.
   if (printing_context_->PageDone() != PrintingContext::OK) {
@@ -422,16 +457,20 @@
     return;
   }
 
-// Signal everyone that the page is printed. No one cares about this except
-// on Windows.
-#if defined(OS_WIN)
-  owner_->PostTask(
-      FROM_HERE,
-      base::Bind(&NotificationCallback, base::RetainedRef(owner_),
-                 JobEventDetails::PAGE_DONE, printing_context_->job_id(),
-                 base::RetainedRef(document_), base::RetainedRef(page)));
-#endif
+  // Signal everyone that the page is printed.
+  owner_->PostTask(FROM_HERE,
+                   base::BindRepeating(
+                       &PageNotificationCallback, base::RetainedRef(owner_),
+                       JobEventDetails::PAGE_DONE, printing_context_->job_id(),
+                       base::RetainedRef(document_), base::RetainedRef(page)));
 }
+#else
+void PrintJobWorker::SpoolJob() {
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
+  if (!document_->RenderPrintedDocument(printing_context_.get()))
+    OnFailure();
+}
+#endif
 
 void PrintJobWorker::OnFailure() {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
@@ -439,10 +478,10 @@
   // We may loose our last reference by broadcasting the FAILED event.
   scoped_refptr<PrintJobWorkerOwner> handle(owner_);
 
-  owner_->PostTask(FROM_HERE,
-                   base::Bind(&NotificationCallback, base::RetainedRef(owner_),
-                              JobEventDetails::FAILED, 0,
-                              base::RetainedRef(document_), nullptr));
+  owner_->PostTask(
+      FROM_HERE, base::BindRepeating(
+                     &NotificationCallback, base::RetainedRef(owner_),
+                     JobEventDetails::FAILED, 0, base::RetainedRef(document_)));
   Cancel();
 
   // Makes sure the variables are reinitialized.
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
index ac79af4..11e2c85 100644
--- a/chrome/browser/printing/print_job_worker.h
+++ b/chrome/browser/printing/print_job_worker.h
@@ -11,6 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread.h"
+#include "build/build_config.h"
 #include "chrome/browser/printing/printer_query.h"
 #include "content/public/browser/browser_thread.h"
 #include "printing/page_number.h"
@@ -98,8 +99,17 @@
   // and DEFAULT_INIT_DONE. These three are sent through PrintJob::InitDone().
   class NotificationTask;
 
+  // Posts a task to call OnNewPage(). Used to wait for pages/document to be
+  // available.
+  void PostWaitForPage();
+
+#if defined(OS_WIN)
   // Renders a page in the printer.
   void SpoolPage(PrintedPage* page);
+#else
+  // Renders the document to the printer.
+  void SpoolJob();
+#endif
 
   // Closes the job since spooling is done.
   void OnDocumentDone();
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 65563d1..7e50be37 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -147,6 +147,12 @@
 
 void PrintViewManagerBase::OnDidPrintPage(
     const PrintHostMsg_DidPrintPage_Params& params) {
+// TODO(rbpotter): Remove this check once there are no more spurious
+// DidPrintPage messages.
+#if !defined(OS_WIN)
+  if (!expecting_first_page_)
+    return;
+#endif
   // Ready to composite. Starting a print job.
   if (!OpportunisticallyCreatePrintJob(params.document_cookie))
     return;
@@ -250,8 +256,8 @@
   }
 
   // Update the rendered document. It will send notifications to the listener.
-  document->SetPage(params.page_number, std::move(metafile), params.page_size,
-                    params.content_area);
+  document->SetDocument(std::move(metafile), params.page_size,
+                        params.content_area);
 
   ShouldQuitFromInnerMessageLoop();
 #endif
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index fec54fa5..7ebfcede 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -44,7 +44,6 @@
 #include "chrome/browser/plugins/plugin_prefs_factory.h"
 #include "chrome/browser/policy/cloud/policy_header_service_factory.h"
 #include "chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.h"
-#include "chrome/browser/policy/policy_helpers.h"
 #include "chrome/browser/policy/profile_policy_connector_factory.h"
 #include "chrome/browser/policy/schema_registry_service_factory.h"
 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
@@ -81,7 +80,6 @@
 #include "chrome/browser/web_data_service_factory.h"
 #include "chrome/common/features.h"
 #include "components/feature_engagement/features.h"
-#include "components/policy/content/policy_blacklist_navigation_throttle.h"
 #include "components/spellcheck/spellcheck_build_features.h"
 #include "extensions/features/features.h"
 #include "ppapi/features/features.h"
@@ -335,8 +333,6 @@
   prerender::PrerenderMessageFilter::EnsureShutdownNotifierFactoryBuilt();
   ProfileSyncServiceFactory::GetInstance();
   ProtocolHandlerRegistryFactory::GetInstance();
-  PolicyBlacklistFactory::GetInstance()->SetBlacklistOverride(
-      base::BindRepeating(policy::OverrideBlacklistForURL));
 #if defined(OS_ANDROID)
   SearchPermissionsService::Factory::GetInstance();
 #endif
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 49f919a9..d7ccd7a5c 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -64,6 +64,7 @@
 #include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
 #include "components/net_log/chrome_net_log.h"
+#include "components/policy/core/browser/url_blacklist_manager.h"
 #include "components/policy/core/common/cloud/policy_header_io_helper.h"
 #include "components/policy/core/common/cloud/policy_header_service.h"
 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
@@ -555,6 +556,17 @@
         policy::PolicyCertServiceFactory::CreateForProfile(profile);
   }
 #endif
+  // The URLBlacklistManager has to be created on the UI thread to register
+  // observers of |pref_service|, and it also has to clean up on
+  // ShutdownOnUIThread to release these observers on the right thread.
+  // Don't pass it in |profile_params_| to make sure it is correctly cleaned up,
+  // in particular when this ProfileIOData isn't |initialized_| during deletion.
+  scoped_refptr<base::SequencedTaskRunner> background_task_runner =
+      base::CreateSequencedTaskRunnerWithTraits(
+          {base::MayBlock(), base::TaskPriority::BACKGROUND});
+  url_blacklist_manager_.reset(new policy::URLBlacklistManager(
+      pref_service, background_task_runner, io_task_runner,
+      base::Bind(policy::OverrideBlacklistForURL)));
 
   // The CTPolicyManager shares the same constraints of needing to be cleaned
   // up on the UI thread.
@@ -1082,6 +1094,8 @@
   }
 #endif
 
+  chrome_network_delegate->set_url_blacklist_manager(
+      url_blacklist_manager_.get());
   chrome_network_delegate->set_profile(profile_params_->profile);
   chrome_network_delegate->set_profile_path(profile_params_->path);
   chrome_network_delegate->set_cookie_settings(
@@ -1432,6 +1446,8 @@
   enable_metrics_.Destroy();
   safe_browsing_enabled_.Destroy();
   network_prediction_options_.Destroy();
+  if (url_blacklist_manager_)
+    url_blacklist_manager_->ShutdownOnUIThread();
   if (ct_policy_manager_)
     ct_policy_manager_->Shutdown();
   if (chrome_http_user_agent_settings_)
@@ -1489,3 +1505,8 @@
   DCHECK(!cookie_settings_.get());
   cookie_settings_ = cookie_settings;
 }
+
+policy::URLBlacklist::URLBlacklistState ProfileIOData::GetURLBlacklistState(
+    const GURL& url) const {
+  return url_blacklist_manager_->GetURLBlacklistState(url);
+}
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index a8d52e05..6fc8cd3 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -25,6 +25,7 @@
 #include "chrome/browser/profiles/storage_partition_descriptor.h"
 #include "chrome/common/features.h"
 #include "components/content_settings/core/common/content_settings_types.h"
+#include "components/policy/core/browser/url_blacklist_manager.h"
 #include "components/prefs/pref_member.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/resource_context.h"
@@ -91,6 +92,7 @@
 namespace policy {
 class PolicyCertVerifier;
 class PolicyHeaderIOHelper;
+class URLBlacklistManager;
 }  // namespace policy
 
 namespace previews {
@@ -244,6 +246,11 @@
     return previews_io_data_.get();
   }
 
+  // This function is to be used to check if the |url| is defined in
+  // blacklist or whitelist policy.
+  virtual policy::URLBlacklist::URLBlacklistState GetURLBlacklistState(
+      const GURL& url) const;
+
   // Returns the predictor service for this Profile. Returns nullptr if there is
   // no Predictor, as is the case with OffTheRecord profiles.
   virtual chrome_browser_net::Predictor* GetPredictor();
@@ -574,6 +581,7 @@
   BooleanPrefMember enable_metrics_;
 
   // Pointed to by NetworkDelegate.
+  mutable std::unique_ptr<policy::URLBlacklistManager> url_blacklist_manager_;
   mutable std::unique_ptr<policy::PolicyHeaderIOHelper> policy_header_helper_;
 
   // Pointed to by URLRequestContext.
diff --git a/chrome/browser/resource_coordinator/lifecycle_unit_source.h b/chrome/browser/resource_coordinator/lifecycle_unit_source.h
new file mode 100644
index 0000000..89f7e53
--- /dev/null
+++ b/chrome/browser/resource_coordinator/lifecycle_unit_source.h
@@ -0,0 +1,25 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LIFECYCLE_UNIT_SOURCE_H_
+#define CHROME_BROWSER_RESOURCE_COORDINATOR_LIFECYCLE_UNIT_SOURCE_H_
+
+namespace resource_coordinator {
+
+class LifecycleUnitSourceObserver;
+
+// Interface for a class that creates and destroys LifecycleUnits.
+class LifecycleUnitSource {
+ public:
+  virtual ~LifecycleUnitSource() = default;
+
+  // Adds / removes an observer that is notified when a LifecycleUnit is created
+  // or destroyed by this LifecycleUnitSource.
+  virtual void AddObserver(LifecycleUnitSourceObserver* observer) = 0;
+  virtual void RemoveObserver(LifecycleUnitSourceObserver* observer) = 0;
+};
+
+}  // namespace resource_coordinator
+
+#endif  // CHROME_BROWSER_RESOURCE_COORDINATOR_LIFECYCLE_UNIT_SOURCE_H_
diff --git a/chrome/browser/resource_coordinator/lifecycle_unit_source_base.cc b/chrome/browser/resource_coordinator/lifecycle_unit_source_base.cc
new file mode 100644
index 0000000..e6c317a
--- /dev/null
+++ b/chrome/browser/resource_coordinator/lifecycle_unit_source_base.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/resource_coordinator/lifecycle_unit_source_base.h"
+
+#include "chrome/browser/resource_coordinator/lifecycle_unit_source_observer.h"
+
+namespace resource_coordinator {
+
+LifecycleUnitSourceBase::LifecycleUnitSourceBase() = default;
+LifecycleUnitSourceBase::~LifecycleUnitSourceBase() = default;
+
+void LifecycleUnitSourceBase::AddObserver(
+    LifecycleUnitSourceObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void LifecycleUnitSourceBase::RemoveObserver(
+    LifecycleUnitSourceObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void LifecycleUnitSourceBase::NotifyLifecycleUnitCreated(
+    LifecycleUnit* lifecycle_unit) {
+  for (LifecycleUnitSourceObserver& observer : observers_)
+    observer.OnLifecycleUnitCreated(lifecycle_unit);
+}
+
+void LifecycleUnitSourceBase::NotifyLifecycleUnitDestroyed(
+    LifecycleUnit* lifecycle_unit) {
+  for (LifecycleUnitSourceObserver& observer : observers_)
+    observer.OnLifecycleUnitDestroyed(lifecycle_unit);
+}
+
+}  // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/lifecycle_unit_source_base.h b/chrome/browser/resource_coordinator/lifecycle_unit_source_base.h
new file mode 100644
index 0000000..829ceec
--- /dev/null
+++ b/chrome/browser/resource_coordinator/lifecycle_unit_source_base.h
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LIFECYCLE_UNIT_SOURCE_BASE_H_
+#define CHROME_BROWSER_RESOURCE_COORDINATOR_LIFECYCLE_UNIT_SOURCE_BASE_H_
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "chrome/browser/resource_coordinator/lifecycle_unit_source.h"
+
+namespace resource_coordinator {
+
+class LifecycleUnit;
+
+// Base class for a class that creates and destroys LifecycleUnits.
+class LifecycleUnitSourceBase : public LifecycleUnitSource {
+ public:
+  LifecycleUnitSourceBase();
+  ~LifecycleUnitSourceBase() override;
+
+  // LifecycleUnitSource:
+  void AddObserver(LifecycleUnitSourceObserver* observer) override;
+  void RemoveObserver(LifecycleUnitSourceObserver* observer) override;
+
+ protected:
+  // Notifies observers that a LifecycleUnit was created / destroyed.
+  void NotifyLifecycleUnitCreated(LifecycleUnit* lifecycle_unit);
+  void NotifyLifecycleUnitDestroyed(LifecycleUnit* lifecycle_unit);
+
+ private:
+  // Observers notified when a LifecycleUnit is created or destroyed.
+  base::ObserverList<LifecycleUnitSourceObserver> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(LifecycleUnitSourceBase);
+};
+
+}  // namespace resource_coordinator
+
+#endif  // CHROME_BROWSER_RESOURCE_COORDINATOR_LIFECYCLE_UNIT_SOURCE_BASE_H_
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_observer.h b/chrome/browser/resource_coordinator/tab_lifecycle_observer.h
index 58df03c..b096957 100644
--- a/chrome/browser/resource_coordinator/tab_lifecycle_observer.h
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_observer.h
@@ -19,7 +19,9 @@
   virtual void OnDiscardedStateChange(content::WebContents* contents,
                                       bool is_discarded) = 0;
 
-  // Invoked when
+  // Invoked when the auto-discardable state of |contents| changes.
+  // |is_auto_discardable| indicates whether |contents| can be automatically
+  // discarded.
   virtual void OnAutoDiscardableStateChange(content::WebContents* contents,
                                             bool is_auto_discardable) = 0;
 
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
new file mode 100644
index 0000000..77a46c7
--- /dev/null
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
@@ -0,0 +1,110 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/resource_coordinator/tab_lifecycle_unit.h"
+
+#include "base/logging.h"
+#include "chrome/browser/resource_coordinator/tab_lifecycle_observer.h"
+#include "chrome/browser/resource_coordinator/time.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
+
+namespace resource_coordinator {
+
+TabLifecycleUnit::TabLifecycleUnit(
+    base::ObserverList<TabLifecycleObserver>* observers,
+    content::WebContents* web_contents,
+    TabStripModel* tab_strip_model)
+    : observers_(observers),
+      web_contents_(web_contents),
+      tab_strip_model_(tab_strip_model) {
+  DCHECK(observers_);
+  DCHECK(GetWebContents());
+  DCHECK(tab_strip_model_);
+}
+
+TabLifecycleUnit::~TabLifecycleUnit() = default;
+
+void TabLifecycleUnit::SetTabStripModel(TabStripModel* tab_strip_model) {
+  DCHECK(tab_strip_model);
+  tab_strip_model = tab_strip_model_;
+}
+
+void TabLifecycleUnit::SetWebContents(content::WebContents* web_contents) {
+  DCHECK(web_contents);
+  web_contents_ = web_contents;
+}
+
+void TabLifecycleUnit::SetFocused(bool focused) {
+  const bool was_focused = last_focused_time_ == base::TimeTicks::Max();
+  if (focused == was_focused)
+    return;
+  last_focused_time_ = focused ? base::TimeTicks::Max() : NowTicks();
+
+  // TODO(fdoray): Reload the tab if discarded. https://crbug.com/775644
+}
+
+base::string16 TabLifecycleUnit::GetTitle() const {
+  return GetWebContents()->GetTitle();
+}
+
+std::string TabLifecycleUnit::GetIconURL() const {
+  auto* last_committed_entry =
+      GetWebContents()->GetController().GetLastCommittedEntry();
+  if (!last_committed_entry)
+    return std::string();
+  const auto& favicon = last_committed_entry->GetFavicon();
+  return favicon.valid ? favicon.url.spec() : std::string();
+}
+
+LifecycleUnit::SortKey TabLifecycleUnit::GetSortKey() const {
+  return SortKey(last_focused_time_);
+}
+
+LifecycleUnit::State TabLifecycleUnit::GetState() const {
+  return state_;
+}
+
+int TabLifecycleUnit::GetEstimatedMemoryFreedOnDiscardKB() const {
+  // TODO(fdoray): Implement this. https://crbug.com/775644
+  return 0;
+}
+
+bool TabLifecycleUnit::CanDiscard(DiscardReason reason) const {
+  // TODO(fdoray): Implement this. https://crbug.com/775644
+  return false;
+}
+
+bool TabLifecycleUnit::Discard(DiscardReason discard_reason) {
+  // TODO(fdoray): Implement this. https://crbug.com/775644
+  return false;
+}
+
+content::WebContents* TabLifecycleUnit::GetWebContents() const {
+  return web_contents_;
+}
+
+bool TabLifecycleUnit::IsAutoDiscardable() const {
+  return auto_discardable_;
+}
+
+void TabLifecycleUnit::SetAutoDiscardable(bool auto_discardable) {
+  if (auto_discardable_ == auto_discardable)
+    return;
+  auto_discardable_ = auto_discardable;
+  for (auto& observer : *observers_)
+    observer.OnAutoDiscardableStateChange(GetWebContents(), auto_discardable_);
+}
+
+void TabLifecycleUnit::DiscardTab() {
+  Discard(DiscardReason::kExternal);
+}
+
+bool TabLifecycleUnit::IsDiscarded() const {
+  return GetState() == State::DISCARDED;
+}
+
+}  // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.h b/chrome/browser/resource_coordinator/tab_lifecycle_unit.h
new file mode 100644
index 0000000..5c88a7b
--- /dev/null
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.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 CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_LIFECYCLE_UNIT_H_
+#define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_LIFECYCLE_UNIT_H_
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "base/time/time.h"
+#include "chrome/browser/resource_coordinator/lifecycle_unit.h"
+#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h"
+
+class TabStripModel;
+
+namespace content {
+class WebContents;
+}  // namespace content
+
+namespace resource_coordinator {
+
+class TabLifecycleObserver;
+
+// Represents a tab.
+class TabLifecycleUnit : public LifecycleUnit, public TabLifecycleUnitExternal {
+ public:
+  // |observers| is a list of observers to notify when the discarded state or
+  // the auto-discardable state of this tab changes. It can be modified outside
+  // of this TabLifecycleUnit, but only on the sequence on which this
+  // constructor is invoked. |web_contents| and |tab_strip_model| are the
+  // WebContents and TabStripModel associated with this tab.
+  TabLifecycleUnit(base::ObserverList<TabLifecycleObserver>* observers,
+                   content::WebContents* web_contents,
+                   TabStripModel* tab_strip_model);
+  ~TabLifecycleUnit() override;
+
+  // Sets the TabStripModel associated with this tab. The source that created
+  // this TabLifecycleUnit is responsible for calling this when the tab moves to
+  // a different TabStripModel.
+  void SetTabStripModel(TabStripModel* tab_strip_model);
+
+  // Sets the WebContents associated with this tab. The source that created this
+  // TabLifecycleUnit is responsible for calling this when the tab's WebContents
+  // changes (e.g. when the tab is discarded or when prerendered or distilled
+  // content is displayed).
+  void SetWebContents(content::WebContents* web_contents);
+
+  // Invoked when the tab gains or loses focus.
+  void SetFocused(bool focused);
+
+  // LifecycleUnit:
+  base::string16 GetTitle() const override;
+  std::string GetIconURL() const override;
+  SortKey GetSortKey() const override;
+  State GetState() const override;
+  int GetEstimatedMemoryFreedOnDiscardKB() const override;
+  bool CanDiscard(DiscardReason reason) const override;
+  bool Discard(DiscardReason discard_reason) override;
+
+  // TabLifecycleUnitExternal:
+  content::WebContents* GetWebContents() const override;
+  bool IsAutoDiscardable() const override;
+  void SetAutoDiscardable(bool auto_discardable) override;
+  void DiscardTab() override;
+  bool IsDiscarded() const override;
+
+ private:
+  // List of observers to notify when the discarded state or the auto-
+  // discardable state of this tab changes.
+  base::ObserverList<TabLifecycleObserver>* observers_;
+
+  // The WebContents associated with this tab.
+  content::WebContents* web_contents_;
+
+  // TabStripModel to which this tab belongs.
+  TabStripModel* tab_strip_model_;
+
+  // Current state of this tab.
+  State state_ = State::LOADED;
+
+  // Last time at which this tab was focused, or TimeTicks::Max() if it is
+  // currently focused.
+  base::TimeTicks last_focused_time_;
+
+  // When this is false, CanDiscard() always returns false.
+  bool auto_discardable_ = true;
+
+  DISALLOW_COPY_AND_ASSIGN(TabLifecycleUnit);
+};
+
+}  // namespace resource_coordinator
+
+#endif  // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_LIFECYCLE_UNIT_H_
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
new file mode 100644
index 0000000..de172b47
--- /dev/null
+++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
@@ -0,0 +1,108 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/resource_coordinator/tab_lifecycle_unit.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "chrome/browser/resource_coordinator/tab_lifecycle_observer.h"
+#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h"
+#include "chrome/browser/resource_coordinator/time.h"
+#include "chrome/browser/ui/tabs/tab_strip_model_impl.h"
+#include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/web_contents.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace resource_coordinator {
+
+namespace {
+
+constexpr base::TimeDelta kShortDelay = base::TimeDelta::FromSeconds(1);
+
+class MockTabLifecycleObserver : public TabLifecycleObserver {
+ public:
+  MockTabLifecycleObserver() = default;
+
+  MOCK_METHOD2(OnDiscardedStateChange,
+               void(content::WebContents* contents, bool is_discarded));
+  MOCK_METHOD2(OnAutoDiscardableStateChange,
+               void(content::WebContents* contents, bool is_auto_discardable));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockTabLifecycleObserver);
+};
+
+}  // namespace
+
+class TabLifecycleUnitTest : public ChromeRenderViewHostTestHarness {
+ protected:
+  TabLifecycleUnitTest() : scoped_set_tick_clock_for_testing_(&test_clock_) {
+    observers_.AddObserver(&observer_);
+  }
+
+  void SetUp() override {
+    ChromeRenderViewHostTestHarness::SetUp();
+    tab_strip_model_ = std::make_unique<TabStripModelImpl>(
+        &tab_strip_model_delegate_, profile());
+    tab_strip_model_->AppendWebContents(web_contents(), true);
+  }
+
+  void TearDown() override {
+    tab_strip_model_.reset();
+    ChromeRenderViewHostTestHarness::TearDown();
+  }
+
+  testing::StrictMock<MockTabLifecycleObserver> observer_;
+  base::ObserverList<TabLifecycleObserver> observers_;
+  std::unique_ptr<TabStripModel> tab_strip_model_;
+  base::SimpleTestTickClock test_clock_;
+
+ private:
+  TestTabStripModelDelegate tab_strip_model_delegate_;
+  ScopedSetTickClockForTesting scoped_set_tick_clock_for_testing_;
+
+  DISALLOW_COPY_AND_ASSIGN(TabLifecycleUnitTest);
+};
+
+TEST_F(TabLifecycleUnitTest, SetFocused) {
+  test_clock_.Advance(kShortDelay);
+  TabLifecycleUnit tab_lifecycle_unit(&observers_, web_contents(),
+                                      tab_strip_model_.get());
+  EXPECT_EQ(base::TimeTicks(),
+            tab_lifecycle_unit.GetSortKey().last_focused_time);
+
+  test_clock_.Advance(kShortDelay);
+  tab_lifecycle_unit.SetFocused(true);
+  EXPECT_EQ(base::TimeTicks::Max(),
+            tab_lifecycle_unit.GetSortKey().last_focused_time);
+
+  test_clock_.Advance(kShortDelay);
+  tab_lifecycle_unit.SetFocused(false);
+  EXPECT_EQ(test_clock_.NowTicks(),
+            tab_lifecycle_unit.GetSortKey().last_focused_time);
+}
+
+TEST_F(TabLifecycleUnitTest, AutoDiscardable) {
+  TabLifecycleUnit tab_lifecycle_unit(&observers_, web_contents(),
+                                      tab_strip_model_.get());
+  EXPECT_TRUE(tab_lifecycle_unit.IsAutoDiscardable());
+
+  EXPECT_CALL(observer_, OnAutoDiscardableStateChange(web_contents(), false));
+  tab_lifecycle_unit.SetAutoDiscardable(false);
+  testing::Mock::VerifyAndClear(&observer_);
+  EXPECT_FALSE(tab_lifecycle_unit.IsAutoDiscardable());
+
+  EXPECT_CALL(observer_, OnAutoDiscardableStateChange(web_contents(), true));
+  tab_lifecycle_unit.SetAutoDiscardable(true);
+  testing::Mock::VerifyAndClear(&observer_);
+  EXPECT_TRUE(tab_lifecycle_unit.IsAutoDiscardable());
+}
+
+}  // namespace resource_coordinator
diff --git a/chrome/browser/resources/chromeos/keyboard_overlay.js b/chrome/browser/resources/chromeos/keyboard_overlay.js
index 4f700ab..6076d409 100644
--- a/chrome/browser/resources/chromeos/keyboard_overlay.js
+++ b/chrome/browser/resources/chromeos/keyboard_overlay.js
@@ -290,6 +290,15 @@
 }
 
 /**
+ * Tests if accelerators for moving window between displays are enabled.
+ * @return {boolean} True if accelerators for moving window between displays
+ * feature is enabled.
+ */
+function isDisplayMoveWindowAccelsEnabled() {
+  return loadTimeData.getBoolean('displayMoveWindowAccelsEnabled');
+}
+
+/**
  * Converts a single hex number to a character.
  * @param {string} hex Hexadecimal string.
  * @return {string} Unicode values of hexadecimal string.
@@ -602,6 +611,14 @@
       continue;
     }
 
+    if ((shortcutId == 'keyboardOverlayMoveWindowToBelowDisplay' ||
+         shortcutId == 'keyboardOverlayMoveWindowToLeftDisplay' ||
+         shortcutId == 'keyboardOverlayMoveWindowToRightDisplay' ||
+         shortcutId == 'keyboardOverlayMoveWindowToAboveDisplay') &&
+        !isDisplayMoveWindowAccelsEnabled()) {
+      continue;
+    }
+
     if (shortcutId) {
       classes.push('is-shortcut');
       classes.push('keyboard-overlay-shortcut-key-background');
diff --git a/chrome/browser/resources/chromeos/select_to_speak/options.html b/chrome/browser/resources/chromeos/select_to_speak/options.html
index aa4828f..500b225 100644
--- a/chrome/browser/resources/chromeos/select_to_speak/options.html
+++ b/chrome/browser/resources/chromeos/select_to_speak/options.html
@@ -26,6 +26,9 @@
         <span class="i18n" msgid="options_rate_description"
               id="rate_description"></span>
         <select id="rate" aria-labelledby="rate_description">
+          <!-- If these options are changed, make sure to update the
+               SelectToSpeak.speechRateToEnum_ function and add new
+               enums in tools/metrics/histograms/enums.xml -->
           <option value="0.5" class="i18n" msgid="options_rate_slowest">
           </option>
           <option value="0.75" class="i18n" msgid="options_rate_slow">
diff --git a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js
index a0bad97..035f1487 100644
--- a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js
+++ b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js
@@ -673,13 +673,34 @@
   },
 
   /**
+   * Converts the speech rate into an enum based on
+   * tools/metrics/histograms/enums.xml.
+   * These values are persisted to logs. Entries should not be
+   * renumbered and numeric values should never be reused.
+   * @return {number} the current speech rate as an int for metrics.
+   */
+  speechRateToSparceHistogramInt_: function() {
+    return this.speechRate_ * 100;
+  },
+
+  /**
    * Records an event that Select-to-Speak has begun speaking.
    */
   recordStartEvent_: function() {
-    // TODO(katie): Add tracking for speech rate, how STS was activated,
-    // whether word highlighting is on or off (as histograms?).
     chrome.metricsPrivate.recordUserAction(
         'Accessibility.CrosSelectToSpeak.StartSpeech');
+    chrome.metricsPrivate.recordSparseValue(
+        'Accessibility.CrosSelectToSpeak.SpeechRate',
+        this.speechRateToSparceHistogramInt_());
+    chrome.metricsPrivate.recordValue(
+        {
+          metricName: 'Accessibility.CrosSelectToSpeak.WordHighlighting',
+          type: chrome.metricsPrivate.MetricTypeType.HISTOGRAM_LINEAR,
+          min: 1,     // According to histogram.h, this should be 1 for enums.
+          max: 2,     // Maximum should be exclusive.
+          buckets: 3  // Number of buckets: 0, 1 and overflowing 2.
+        },
+        this.wordHighlight_ ? 1 : 0);
   },
 
   /**
@@ -714,6 +735,9 @@
                 }
                 if (prefs['highlightColor']) {
                   this.highlightColor_ = prefs['highlightColor'];
+                } else {
+                  chrome.storage.sync.set(
+                      {'highlightColor': this.highlightColor_});
                 }
               }).bind(this));
         }).bind(this);
diff --git a/chrome/browser/resources/chromeos/select_to_speak/test_support.js b/chrome/browser/resources/chromeos/select_to_speak/test_support.js
index 9f1cd08..34a0a276c 100644
--- a/chrome/browser/resources/chromeos/select_to_speak/test_support.js
+++ b/chrome/browser/resources/chromeos/select_to_speak/test_support.js
@@ -30,5 +30,7 @@
 };
 
 chrome.metricsPrivate = {
-  recordUserAction: function() {}
+  recordUserAction: function() {},
+  recordValue: function() {},
+  MetricTypeType: {HISTOGRAM_LINEAR: 1}
 };
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css
index 590792ad..57aebd6 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -54,6 +54,7 @@
 body {
   background-attachment: fixed !important;
   cursor: default;
+  display: none;
   font-family: arial, sans-serif;
   font-size: small;
   height: 100%;
@@ -61,6 +62,10 @@
   overflow-x: hidden;
 }
 
+body.inited {
+  display: block;
+}
+
 /* Button defaults vary by platform. Reset CSS so that the NTP can use buttons
  * as a kind of clickable div. */
 button {
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html
index e11e189..4766016 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.html
+++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -7,8 +7,6 @@
   <link rel="stylesheet" href="chrome-search://local-ntp/theme.css"></link>
   <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp.css"></link>
   <link rel="stylesheet" href="chrome-search://local-ntp/voice.css"></link>
-  <script src="chrome-search://local-ntp/config.js"
-      {{CONFIG_INTEGRITY}}></script>
   <script src="chrome-search://local-ntp/local-ntp.js"
       {{LOCAL_NTP_INTEGRITY}}></script>
   <script src="chrome-search://local-ntp/voice.js"
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js
index d2f77c0..55b4513b 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -73,6 +73,7 @@
   FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused',
   HIDE_FAKEBOX_AND_LOGO: 'hide-fakebox-logo',
   HIDE_NOTIFICATION: 'mv-notice-hide',
+  INITED: 'inited',  // Reveals the <body> once init() is done.
   LEFT_ALIGN_ATTRIBUTION: 'left-align-attribution',
   // Vertically centers the most visited section for a non-Google provided page.
   NON_GOOGLE_PAGE: 'non-google-page',
@@ -732,6 +733,17 @@
   };
 
   window.addEventListener('message', handlePostMessage);
+
+  document.body.classList.add(CLASSES.INITED);
+}
+
+
+function loadConfig() {
+  var configScript = document.createElement('script');
+  configScript.type = 'text/javascript';
+  configScript.src = 'chrome-search://local-ntp/config.js';
+  configScript.onload = init;
+  document.head.appendChild(configScript);
 }
 
 
@@ -739,7 +751,7 @@
  * Binds event listeners.
  */
 function listen() {
-  document.addEventListener('DOMContentLoaded', init);
+  document.addEventListener('DOMContentLoaded', loadConfig);
 }
 
 
diff --git a/chrome/browser/resources/print_preview/data/app_state.js b/chrome/browser/resources/print_preview/data/app_state.js
index 68d75b8..d945682d 100644
--- a/chrome/browser/resources/print_preview/data/app_state.js
+++ b/chrome/browser/resources/print_preview/data/app_state.js
@@ -26,7 +26,6 @@
   VENDOR_OPTIONS: 'vendorOptions'
 };
 
-
 /**
  * @typedef {{id: string,
  *            origin: print_preview.DestinationOrigin,
@@ -58,11 +57,15 @@
 
 cr.define('print_preview', function() {
   'use strict';
-  class AppState {
+  class AppState extends cr.EventTarget {
     /**
      * Object used to get and persist the print preview application state.
+     * @param {!print_preview.DestinationStore} destinationStore The destination
+     *     store, used to track destination selection changes.
      */
-    constructor() {
+    constructor(destinationStore) {
+      super();
+
       /**
        * Internal representation of application state.
        * Must contain only plain objects or classes that override the
@@ -85,6 +88,18 @@
        * @private {!print_preview.NativeLayer}
        */
       this.nativeLayer_ = print_preview.NativeLayer.getInstance();
+
+      /**
+       * Destination store object for tracking recent destinations.
+       * @private {!print_preview.DestinationStore}
+       */
+      this.destinationStore_ = destinationStore;
+
+      /**
+       * Event tracker used to track event listeners.
+       * @private {!EventTracker}
+       */
+      this.tracker_ = new EventTracker();
     }
 
     /**
@@ -99,14 +114,6 @@
     }
 
     /**
-     * @return {boolean} Whether the selected destination is valid.
-     */
-    isSelectedDestinationValid() {
-      const selected = this.selectedDestination;
-      return !!selected && !!selected.id && !!selected.origin;
-    }
-
-    /**
      * @return {?Array<!print_preview.AppStateRecentDestination>} The
      *     AppState.NUM_DESTINATIONS_ most recent destinations.
      */
@@ -180,10 +187,20 @@
     }
 
     /**
-     * Sets to initialized state. Now object will accept persist requests.
+     * Sets to initialized state. Now object will accept persist requests and
+     * monitor for destination changes.
      */
     setInitialized() {
       this.isInitialized_ = true;
+      this.tracker_.add(
+          this.destinationStore_,
+          print_preview.DestinationStore.EventType
+              .SELECTED_DESTINATION_CAPABILITIES_READY,
+          this.persistSelectedDestination_.bind(this));
+      this.tracker_.add(
+          this.destinationStore_,
+          print_preview.DestinationStore.EventType.DESTINATION_SELECT,
+          this.persistSelectedDestination_.bind(this));
     }
 
     /**
@@ -203,16 +220,19 @@
     }
 
     /**
-     * Persists the selected destination.
-     * @param {!print_preview.Destination} dest Destination to persist.
+     * Persists the selected destination from the destination store.
+     * @private
      */
-    persistSelectedDestination(dest) {
-      if (!this.isInitialized_)
+    persistSelectedDestination_() {
+      assert(this.isInitialized_);
+
+      const destination = this.destinationStore_.selectedDestination;
+      if (!destination)
         return;
 
       // Determine if this destination is already in the recent destinations,
       // and where in the array it is located.
-      const newDestination = makeRecentDestination(dest);
+      const newDestination = makeRecentDestination(assert(destination));
       let indexFound =
           this.state_[print_preview.AppStateField.RECENT_DESTINATIONS]
               .findIndex(function(recent) {
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js
index cd83d8f6..4cc03c4 100644
--- a/chrome/browser/resources/print_preview/data/destination_store.js
+++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -126,11 +126,10 @@
      * A data store that stores destinations and dispatches events when the
      * data store changes.
      * @param {!print_preview.UserInfo} userInfo User information repository.
-     * @param {!print_preview.AppState} appState Application state.
      * @param {!WebUIListenerTracker} listenerTracker Tracker for WebUI
      *     listeners added in DestinationStore constructor.
      */
-    constructor(userInfo, appState, listenerTracker) {
+    constructor(userInfo, listenerTracker) {
       super();
 
       /**
@@ -146,12 +145,6 @@
       this.userInfo_ = userInfo;
 
       /**
-       * Used to load and persist the selected destination.
-       * @private {!print_preview.AppState}
-       */
-      this.appState_ = appState;
-
-      /**
        * Used to track metrics.
        * @private {!print_preview.DestinationSearchMetricsContext}
        */
@@ -267,6 +260,13 @@
       this.useSystemDefaultAsDefault_ =
           loadTimeData.getBoolean('useSystemDefaultPrinter');
 
+
+      /**
+       * The recent print destinations, set when the store is initialized.
+       * @private {!Array<!print_preview.AppStateRecentDestination>}
+       */
+      this.recentDestinations_ = [];
+
       this.reset_();
 
       this.addWebUIEventListeners_(listenerTracker);
@@ -288,23 +288,16 @@
     }
 
     /**
-     * @param {?string} filterAccount Account to filter recent destinations by.
-     * @return {!Array<!print_preview.Destination>} List of recent destinations
+     * Gets the destination, if any, matching |account|, |id|, and |origin| in
+     * the destination map.
+     * @param {!print_preview.DestinationOrigin} origin The origin of the
+     *     destination.
+     * @param {string} id The destination ID
+     * @param {string} account The account the destination is associated with.
+     * @return {?print_preview.Destination}
      */
-    getRecentDestinations(filterAccount) {
-      let recentDestinations = [];
-      this.appState_.recentDestinations.forEach(function(recentDestination) {
-        const origin = recentDestination.origin;
-        const id = recentDestination.id;
-        const account = recentDestination.account || '';
-        const destination =
-            this.destinationMap_[this.getDestinationKey_(origin, id, account)];
-        if (destination &&
-            (!destination.account || destination.account == filterAccount)) {
-          recentDestinations.push(destination);
-        }
-      }.bind(this));
-      return recentDestinations;
+    getDestination(origin, id, account) {
+      return this.destinationMap_[this.getDestinationKey_(origin, id, account)];
     }
 
     /**
@@ -353,25 +346,38 @@
     }
 
     /**
+     * @param {(?print_preview.Destination |
+     *          ?print_preview.AppStateRecentDestination)} destination
+     * @return {boolean} Whether the destination is valid.
+     */
+    isDestinationValid(destination) {
+      return !!destination && !!destination.id && !!destination.origin;
+    }
+
+    /**
      * Initializes the destination store. Sets the initially selected
      * destination. If any inserted destinations match this ID, that destination
-     * will be automatically selected. This method must be called after the
-     * print_preview.AppState has been initialized.
+     * will be automatically selected.
      * @param {boolean} isInAppKioskMode Whether the print preview is in App
      *     Kiosk mode.
      * @param {string} systemDefaultDestinationId ID of the system default
      *     destination.
      * @param {?string} serializedDefaultDestinationSelectionRulesStr Serialized
      *     default destination selection rules.
+     * @param {!Array<!print_preview.AppStateRecentDestination>}
+     *     recentDestinations The recent print destinations.
      */
     init(
         isInAppKioskMode, systemDefaultDestinationId,
-        serializedDefaultDestinationSelectionRulesStr) {
+        serializedDefaultDestinationSelectionRulesStr, recentDestinations) {
       this.pdfPrinterEnabled_ = !isInAppKioskMode;
       this.systemDefaultDestinationId_ = systemDefaultDestinationId;
       this.createLocalPdfPrintDestination_();
 
-      if (!this.appState_.isSelectedDestinationValid()) {
+      const isRecentDestinationValid = recentDestinations.length > 0 &&
+          this.isDestinationValid(recentDestinations[0]);
+
+      if (!isRecentDestinationValid) {
         const destinationMatch = this.convertToDestinationMatch_(
             serializedDefaultDestinationSelectionRulesStr);
         if (destinationMatch) {
@@ -381,11 +387,12 @@
       }
 
       if (this.systemDefaultDestinationId_.length == 0 &&
-          !this.appState_.isSelectedDestinationValid()) {
+          !isRecentDestinationValid) {
         this.selectPdfDestination_();
         return;
       }
 
+      this.recentDestinations_ = recentDestinations;
       let origin = null;
       let id = '';
       let account = '';
@@ -394,33 +401,30 @@
       let extensionId = '';
       let extensionName = '';
       let foundDestination = false;
-      if (this.appState_.recentDestinations) {
-        // Run through the destinations forward. As soon as we find a
-        // destination, don't select any future destinations, just mark
-        // them recent. Otherwise, there is a race condition between selecting
-        // destinations/updating the print ticket and this selecting a new
-        // destination that causes random print preview errors.
-        for (let i = 0; i < this.appState_.recentDestinations.length; i++) {
-          origin = this.appState_.recentDestinations[i].origin;
-          id = this.appState_.recentDestinations[i].id;
-          account = this.appState_.recentDestinations[i].account || '';
-          name = this.appState_.recentDestinations[i].displayName || '';
-          capabilities = this.appState_.recentDestinations[i].capabilities;
-          extensionId = this.appState_.recentDestinations[i].extensionId || '';
-          extensionName =
-              this.appState_.recentDestinations[i].extensionName || '';
-          const candidate = this.destinationMap_[this.getDestinationKey_(
-              origin, id, account)];
-          if (candidate != null) {
-            if (!foundDestination && !this.useSystemDefaultAsDefault_)
-              this.selectDestination(candidate);
-            candidate.isRecent = true;
-            foundDestination = true;
-          } else if (!foundDestination && !this.useSystemDefaultAsDefault_) {
-            foundDestination = this.fetchPreselectedDestination_(
-                origin, id, account, name, capabilities, extensionId,
-                extensionName);
-          }
+      // Run through the destinations forward. As soon as we find a
+      // destination, don't select any future destinations, just mark
+      // them recent. Otherwise, there is a race condition between selecting
+      // destinations/updating the print ticket and this selecting a new
+      // destination that causes random print preview errors.
+      for (let destination of recentDestinations) {
+        origin = destination.origin;
+        id = destination.id;
+        account = destination.account || '';
+        name = destination.displayName || '';
+        capabilities = destination.capabilities;
+        extensionId = destination.extensionId || '';
+        extensionName = destination.extensionName || '';
+        const candidate =
+            this.destinationMap_[this.getDestinationKey_(origin, id, account)];
+        if (candidate != null) {
+          candidate.isRecent = true;
+          if (!foundDestination && !this.useSystemDefaultAsDefault_)
+            this.selectDestination(candidate);
+          foundDestination = true;
+        } else if (!foundDestination && !this.useSystemDefaultAsDefault_) {
+          foundDestination = this.fetchPreselectedDestination_(
+              origin, id, account, name, capabilities, extensionId,
+              extensionName);
         }
       }
 
@@ -606,10 +610,9 @@
      * @private
      */
     convertPreselectedToDestinationMatch_() {
-      if (this.appState_.isSelectedDestinationValid()) {
+      if (this.isDestinationValid(this.selectedDestination_)) {
         return this.createExactDestinationMatch_(
-            this.appState_.selectedDestination.origin,
-            this.appState_.selectedDestination.id);
+            this.selectedDestination_.origin, this.selectedDestination_.id);
       }
       if (this.systemDefaultDestinationId_.length > 0) {
         return this.createExactDestinationMatch_(
@@ -690,7 +693,6 @@
       // Update and persist selected destination.
       this.selectedDestination_ = destination;
       this.selectedDestination_.isRecent = true;
-      this.appState_.persistSelectedDestination(this.selectedDestination_);
       // Adjust metrics.
       if (destination.cloudID &&
           this.destinations_.some(function(otherDestination) {
@@ -1006,7 +1008,6 @@
       if (this.selectedDestination_ &&
           (existingDestination == this.selectedDestination_ ||
            destination == this.selectedDestination_)) {
-        this.appState_.persistSelectedDestination(this.selectedDestination_);
         cr.dispatchSimpleEvent(
             this,
             DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY);
@@ -1041,7 +1042,7 @@
       const existingDestination = this.destinationMap_[key];
       if (existingDestination == null) {
         destination.isRecent |=
-            this.appState_.recentDestinations.some(function(recent) {
+            this.recentDestinations_.some(function(recent) {
               return (
                   destination.id == recent.id &&
                   destination.origin == recent.origin);
@@ -1293,8 +1294,7 @@
     //    and Destination.origin by complex ID.
     /**
      * Returns key to be used with {@code destinationMap_}.
-     * @param {print_preview.DestinationOrigin | string} origin Destination
-     *     origin.
+     * @param {!print_preview.DestinationOrigin} origin Destination origin.
      * @param {string} id Destination id.
      * @param {string} account User account destination is registered for.
      * @private
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index e7ba6397..23024d0 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -65,11 +65,19 @@
     this.userInfo_ = new print_preview.UserInfo();
 
     /**
+     * Data store which holds print destinations.
+     * @type {!print_preview.DestinationStore}
+     * @private
+     */
+    this.destinationStore_ = new print_preview.DestinationStore(
+        this.userInfo_, this.listenerTracker);
+
+    /**
      * Application state.
      * @type {!print_preview.AppState}
      * @private
      */
-    this.appState_ = new print_preview.AppState();
+    this.appState_ = new print_preview.AppState(this.destinationStore_);
 
     /**
      * Data model that holds information about the document to print.
@@ -79,14 +87,6 @@
     this.documentInfo_ = new print_preview.DocumentInfo();
 
     /**
-     * Data store which holds print destinations.
-     * @type {!print_preview.DestinationStore}
-     * @private
-     */
-    this.destinationStore_ = new print_preview.DestinationStore(
-        this.userInfo_, this.appState_, this.listenerTracker);
-
-    /**
      * Data store which holds printer sharing invitations.
      * @type {!print_preview.InvitationStore}
      * @private
@@ -116,7 +116,8 @@
      * @private
      */
     this.destinationSearch_ = new print_preview.DestinationSearch(
-        this.destinationStore_, this.invitationStore_, this.userInfo_);
+        this.destinationStore_, this.invitationStore_, this.userInfo_,
+        this.appState_);
     this.addChild(this.destinationSearch_);
 
     /**
@@ -747,7 +748,8 @@
           settings.unitType, settings.shouldPrintSelectionOnly);
       this.destinationStore_.init(
           settings.isInAppKioskMode, settings.printerName,
-          settings.serializedDefaultDestinationSelectionRulesStr);
+          settings.serializedDefaultDestinationSelectionRulesStr,
+          this.appState_.recentDestinations || []);
       this.appState_.setInitialized();
 
       // This is only visible in the task manager.
diff --git a/chrome/browser/resources/print_preview/search/destination_search.js b/chrome/browser/resources/print_preview/search/destination_search.js
index 8aa3456d..2262082c 100644
--- a/chrome/browser/resources/print_preview/search/destination_search.js
+++ b/chrome/browser/resources/print_preview/search/destination_search.js
@@ -16,10 +16,12 @@
    *     holding printer sharing invitations.
    * @param {!print_preview.UserInfo} userInfo Event target that contains
    *     information about the logged in user.
+   * @param {!print_preview.AppState} appState Contains recent destination list.
    * @constructor
    * @extends {print_preview.Overlay}
    */
-  function DestinationSearch(destinationStore, invitationStore, userInfo) {
+  function DestinationSearch(
+      destinationStore, invitationStore, userInfo, appState) {
     print_preview.Overlay.call(this);
 
     /**
@@ -41,6 +43,13 @@
     this.userInfo_ = userInfo;
 
     /**
+     * Contains recent destinations that are currently set to be persisted into
+     * the sticky settings.
+     * @private {!print_preview.AppState}
+     */
+    this.appState_ = appState;
+
+    /**
      * Currently displayed printer sharing invitation.
      * @private {print_preview.Invitation}
      */
@@ -308,12 +317,33 @@
     },
 
     /**
+     * @param {?string} filterAccount Account to filter recent destinations by.
+     * @return {!Array<!print_preview.Destination>} List of recent destinations
+     * @private
+     */
+    getRecentDestinations_(filterAccount) {
+      let recentDestinations = [];
+      this.appState_.recentDestinations.forEach((recentDestination) => {
+        const origin = recentDestination.origin;
+        const id = recentDestination.id;
+        const account = recentDestination.account || '';
+        const destination =
+            this.destinationStore_.getDestination(origin, id, account);
+        if (destination &&
+            (!destination.account || destination.account == filterAccount)) {
+          recentDestinations.push(destination);
+        }
+      });
+      return recentDestinations;
+    },
+
+    /**
      * Renders all of the destinations in the destination store.
      * @private
      */
     renderDestinations_: function() {
-      const recentDestinations = this.destinationStore_.getRecentDestinations(
-          this.userInfo_.activeUser);
+      const recentDestinations =
+          this.getRecentDestinations_(this.userInfo_.activeUser);
       const localDestinations = [];
       const cloudDestinations = [];
       const unregisteredCloudDestinations = [];
@@ -650,8 +680,8 @@
      * @private
      */
     onDestinationStoreSelect_: function() {
-      const recentDestinations = this.destinationStore_.getRecentDestinations(
-          this.userInfo_.activeUser);
+      const recentDestinations =
+          this.getRecentDestinations_(this.userInfo_.activeUser);
       this.recentList_.updateDestinations(recentDestinations);
       this.reflowLists_();
     },
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html
index 955204a..8de3bb8 100644
--- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html
+++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html
@@ -18,7 +18,7 @@
 <dom-module id="settings-chrome-cleanup-page">
   <template>
     <style include="settings-shared">
-      #cleaning-spinner {
+      #waiting-spinner {
         height: 20px;
         width: 20px;
       }
@@ -86,30 +86,25 @@
         padding: 15px var(--settings-box-row-padding);
       }
     </style>
-    <div class$="settings-box first [[getTopSettingsBoxClass_(showDetails_)]]">
+    <div class$="settings-box first
+                 [[getTopSettingsBoxClass_(showExplanation_)]]">
       <div class="status-icon-container">
-        <paper-spinner id="cleaning-spinner" active="[[isRemoving_]]"
-            hidden="[[!isRemoving_]]">
+        <paper-spinner id="waiting-spinner" hidden="[[!isWaitingForResult_]]"
+            active="[[isWaitingForResult_]]">
         </paper-spinner>
-        <iron-icon icon="[[statusIcon_]]" hidden="[[isRemoving_]]"
-            class$="[[statusIconClassName_]]" id="status-icon"></iron-icon>
+        <iron-icon id="status-icon" hidden="[[isWaitingForResult_]]"
+            icon="[[statusIcon_]]" class$="[[statusIconClassName_]]">
+        </iron-icon>
       </div>
       <div class="start">
-        <span>[[title_]]</span>
-        <template is="dom-if" if="[[showDetails_]]">
-          <!-- Force line break to display learn-more inlined with
-               chromeCleanupExplanationRemove or with the title_ (if
-               showDetails_ is false) despite these two elements being on
-               different lines. -->
-          <div></div>
-          <span class="secondary">
-            $i18n{chromeCleanupExplanationRemove}
-          </span>
-        </template>
-        <a id="learn-more" href="$i18n{chromeCleanupLearnMoreUrl}"
-            on-tap="learnMore_" target="_blank" hidden="[[!showLearnMore_]]">
-          $i18n{learnMore}
-        </a>
+        <div>[[title_]]</div>
+        <div hidden="[[!showExplanation_]]">
+          <span class="secondary">[[explanation_]]</span>
+          <a id="learn-more" href="$i18n{chromeCleanupLearnMoreUrl}"
+              on-tap="learnMore_" target="_blank" hidden="[[!showLearnMore_]]">
+            $i18n{learnMore}
+          </a>
+        </div>
       </div>
       <template is="dom-if" if="[[showActionButton_]]">
         <div class="separator"></div>
@@ -126,7 +121,7 @@
         on-settings-boolean-control-change="changeLogsPermission_">
     </settings-toggle-button>
     <div id="show-files-button" class="settings-box" actionable
-        on-tap="toggleExpandButton_" hidden="[[!showDetails_]]">
+        on-tap="toggleExpandButton_" hidden="[[!showItemsToRemove_]]">
       <div class="start">
         $i18n{chromeCleanupLinkShowFiles}
       </div>
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
index bb612ac..cc82717c 100644
--- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
+++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
@@ -37,10 +37,14 @@
  * @enum {string}
  */
 settings.ChromeCleanerCardState = {
-  HIDDEN_CARD: 'hidden_card',
+  HIDDEN_CARD: 'hidden',
+  SCANNING_OFFERED: 'scanning_offered',
+  SCANNING: 'scanning',
   CLEANUP_OFFERED: 'cleanup_offered',
   CLEANING: 'cleaning',
   REBOOT_REQUIRED: 'reboot_required',
+  SCANNING_FOUND_NOTHING: 'scanning_found_nothing',
+  SCANNING_FAILED: 'scanning_failed',
   CLEANUP_SUCCEEDED: 'cleanup_succeeded',
   CLEANING_FAILED: 'cleanup_failed',
 };
@@ -51,10 +55,20 @@
  */
 settings.ChromeCleanupCardFlags = {
   NONE: 0,
-  SHOW_DETAILS: 1 << 0,
-  SHOW_LOGS_PERMISSIONS: 1 << 1,
-  SHOW_LEARN_MORE: 1 << 2,
-  IS_REMOVING: 1 << 3,
+  SHOW_LOGS_PERMISSIONS: 1 << 0,
+  SHOW_LEARN_MORE: 1 << 1,
+  WAITING_FOR_RESULT: 1 << 2,
+  SHOW_ITEMS_TO_REMOVE: 1 << 3,
+};
+
+/**
+ * Identifies an ongoing scanning/cleanup action.
+ * @enum {number}
+ */
+settings.ChromeCleanupOngoingAction = {
+  NONE: 0,
+  SCANNING: 1,
+  CLEANING: 2,
 };
 
 /**
@@ -76,6 +90,7 @@
 /**
  * @typedef {{
  *   title: ?string,
+ *   explanation: ?string,
  *   icon: ?settings.ChromeCleanupCardIcon,
  *   actionButton: ?settings.ChromeCleanupCardActionButton,
  *   flags: number,
@@ -108,7 +123,13 @@
     },
 
     /** @private */
-    isRemoving_: {
+    explanation_: {
+      type: String,
+      value: '',
+    },
+
+    /** @private */
+    isWaitingForResult_: {
       type: Boolean,
       value: '',
     },
@@ -126,9 +147,9 @@
     },
 
     /** @private */
-    showDetails_: {
+    showExplanation_: {
       type: Boolean,
-      value: false,
+      computed: 'computeShowExplanation_(explanation_)',
     },
 
     /**
@@ -148,6 +169,12 @@
     },
 
     /** @private */
+    showItemsToRemove_: {
+      type: Boolean,
+      value: false,
+    },
+
+    /** @private */
     filesToRemoveListExpanded_: {
       type: Boolean,
       value: false,
@@ -200,14 +227,36 @@
    *                 !settings.ChromeCleanupCardComponents>} */
   cardStateToComponentsMap_: null,
 
+  /** @private {settings.ChromeCleanupOngoingAction} */
+  ongoingAction_: settings.ChromeCleanupOngoingAction.NONE,
+
+  /** @private {boolean} */
+  userInitiatedCleanupsEnabled_: false,
+
+  /**
+   * If true, the scan offered view is rendered on state idle, regardless of
+   * the idle reason received from the cleaner controller. The goal is to
+   * ignore previous interactions (such as completed cleanups) perfomed on
+   * other tabs or if this tab is reloaded.
+   * Set to false whenever there is a transition to a non-idle state while the
+   * current tab is open.
+   * @private {boolean}
+   */
+  renderScanOfferedByDefault_: true,
+
   /** @override */
   attached: function() {
+    this.userInitiatedCleanupsEnabled_ =
+        loadTimeData.getBoolean('userInitiatedCleanupsEnabled');
     this.browserProxy_ = settings.ChromeCleanupProxyImpl.getInstance();
     this.cardStateToComponentsMap_ = this.buildCardStateToComponentsMap_();
 
     this.addWebUIListener('chrome-cleanup-on-idle', this.onIdle_.bind(this));
     this.addWebUIListener(
         'chrome-cleanup-on-scanning', this.onScanning_.bind(this));
+    // Note: both reporter running and scanning share the same UI.
+    this.addWebUIListener(
+        'chrome-cleanup-on-reporter-running', this.onScanning_.bind(this));
     this.addWebUIListener(
         'chrome-cleanup-on-infected', this.onInfected_.bind(this));
     this.addWebUIListener(
@@ -224,7 +273,7 @@
 
   /**
    * Implements the action for the only visible button in the UI, which can be
-   * either to start a cleanup or to restart the computer.
+   * either to start an action such as a cleanup or to restart the computer.
    * @private
    */
   proceed_: function() {
@@ -278,21 +327,91 @@
   },
 
   /**
+   * @param {string} explanation
+   * @return {boolean}
+   * @private
+   */
+  computeShowExplanation_: function(explanation) {
+    return explanation != '';
+  },
+
+  /**
    * Listener of event 'chrome-cleanup-on-idle'.
-   * @param {number} idleReason
+   * @param {string} idleReason
    * @private
    */
   onIdle_: function(idleReason) {
-    if (idleReason == settings.ChromeCleanupIdleReason.CLEANING_SUCCEEDED) {
+    this.ongoingAction_ = settings.ChromeCleanupOngoingAction.NONE;
+
+    // If user-initiated cleanups are disabled, then the card will be shown at
+    // the top of the settings page.
+    if (!this.userInitiatedCleanupsEnabled_) {
+      if (idleReason == settings.ChromeCleanupIdleReason.INITIAL) {
+        this.dismiss_(settings.ChromeCleanupDismissSource.OTHER);
+        return;
+      }
+
+      // When user-initiated cleanups are disabled, scanning-related idle
+      // reasons are not expected. Show an error message for all reasons other
+      // than |CLEANING_SUCCEEDED| and |INITIAL|.
       this.renderCleanupCard_(
-          settings.ChromeCleanerCardState.CLEANUP_SUCCEEDED, []);
-    } else if (idleReason == settings.ChromeCleanupIdleReason.INITIAL) {
-      this.dismiss_(settings.ChromeCleanupDismissSource.OTHER);
-    } else {
-      // Scanning-related idle reasons are unexpected. Show an error message for
-      // all reasons other than |CLEANING_SUCCEEDED| and |INITIAL|.
-      this.renderCleanupCard_(
-          settings.ChromeCleanerCardState.CLEANING_FAILED, []);
+          idleReason == settings.ChromeCleanupIdleReason.CLEANING_SUCCEEDED ?
+              settings.ChromeCleanerCardState.CLEANUP_SUCCEEDED :
+              settings.ChromeCleanerCardState.CLEANING_FAILED);
+      return;
+    }
+
+    // Ignore the idle reason and render the scan offered view if no
+    // interaction happened on this tab.
+    if (this.renderScanOfferedByDefault_) {
+      idleReason = settings.ChromeCleanupIdleReason.INITIAL;
+    }
+
+    switch (idleReason) {
+      case settings.ChromeCleanupIdleReason.INITIAL:
+        this.renderCleanupCard_(
+            settings.ChromeCleanerCardState.SCANNING_OFFERED);
+        break;
+
+      case settings.ChromeCleanupIdleReason.SCANNING_FOUND_NOTHING:
+      case settings.ChromeCleanupIdleReason.REPORTER_FOUND_NOTHING:
+        this.renderCleanupCard_(
+            settings.ChromeCleanerCardState.SCANNING_FOUND_NOTHING);
+        break;
+
+      case settings.ChromeCleanupIdleReason.SCANNING_FAILED:
+      case settings.ChromeCleanupIdleReason.REPORTER_FAILED:
+        this.renderCleanupCard_(
+            settings.ChromeCleanerCardState.SCANNING_FAILED);
+        break;
+
+      case settings.ChromeCleanupIdleReason.CONNECTION_LOST:
+        if (this.ongoingAction_ ==
+            settings.ChromeCleanupOngoingAction.SCANNING) {
+          this.renderCleanupCard_(
+              settings.ChromeCleanerCardState.SCANNING_FAILED);
+        } else {
+          assert(
+              this.ongoingAction_ ==
+              settings.ChromeCleanupOngoingAction.CLEANING);
+          this.renderCleanupCard_(
+              settings.ChromeCleanerCardState.CLEANING_FAILED);
+        }
+        break;
+
+      case settings.ChromeCleanupIdleReason.CLEANING_FAILED:
+      case settings.ChromeCleanupIdleReason.USER_DECLINED_CLEANUP:
+        this.renderCleanupCard_(
+            settings.ChromeCleanerCardState.CLEANING_FAILED);
+        break;
+
+      case settings.ChromeCleanupIdleReason.CLEANING_SUCCEEDED:
+        this.renderCleanupCard_(
+            settings.ChromeCleanerCardState.CLEANUP_SUCCEEDED);
+        break;
+
+      default:
+        assert(false, `Unknown idle reason: ${idleReason}`);
     }
   },
 
@@ -303,7 +422,12 @@
    * @private
    */
   onScanning_: function() {
-    this.renderCleanupCard_(settings.ChromeCleanerCardState.HIDDEN_CARD, []);
+    this.ongoingAction_ = settings.ChromeCleanupOngoingAction.SCANNING;
+    this.renderScanOfferedByDefault_ = false;
+    this.renderCleanupCard_(
+        this.userInitiatedCleanupsEnabled_ ?
+            settings.ChromeCleanerCardState.SCANNING :
+            settings.ChromeCleanerCardState.HIDDEN_CARD);
   },
 
   /**
@@ -313,6 +437,8 @@
    * @private
    */
   onInfected_: function(files) {
+    this.ongoingAction_ = settings.ChromeCleanupOngoingAction.NONE;
+    this.renderScanOfferedByDefault_ = false;
     this.renderCleanupCard_(
         settings.ChromeCleanerCardState.CLEANUP_OFFERED, files);
   },
@@ -325,6 +451,8 @@
    * @private
    */
   onCleaning_: function(files) {
+    this.ongoingAction_ = settings.ChromeCleanupOngoingAction.CLEANING;
+    this.renderScanOfferedByDefault_ = false;
     this.renderCleanupCard_(settings.ChromeCleanerCardState.CLEANING, files);
   },
 
@@ -335,23 +463,25 @@
    * @private
    */
   onRebootRequired_: function() {
-    this.renderCleanupCard_(
-        settings.ChromeCleanerCardState.REBOOT_REQUIRED, []);
+    this.ongoingAction_ = settings.ChromeCleanupOngoingAction.NONE;
+    this.renderScanOfferedByDefault_ = false;
+    this.renderCleanupCard_(settings.ChromeCleanerCardState.REBOOT_REQUIRED);
   },
 
   /**
    * Renders the cleanup card given the state and list of files.
    * @param {!settings.ChromeCleanerCardState} state The card state to be
    *     rendered.
-   * @param {!Array<string>} files The list of files to present to the user.
+   * @param {Array<string>=} opt_files The list of files to present to the user.
    * @private
    */
-  renderCleanupCard_: function(state, files) {
+  renderCleanupCard_: function(state, opt_files) {
     var components = this.cardStateToComponentsMap_.get(state);
     assert(components);
 
-    this.filesToRemove_ = files;
+    this.filesToRemove_ = opt_files || [];
     this.title_ = components.title || '';
+    this.explanation_ = components.explanation || '';
     this.updateIcon_(components.icon);
     this.updateActionButton_(components.actionButton);
     this.updateCardFlags_(components.flags);
@@ -399,18 +529,18 @@
    * @private
    */
   updateCardFlags_: function(flags) {
-    this.showDetails_ =
-        (flags & settings.ChromeCleanupCardFlags.SHOW_DETAILS) != 0;
     this.showLogsPermission_ =
         (flags & settings.ChromeCleanupCardFlags.SHOW_LOGS_PERMISSIONS) != 0;
     this.showLearnMore_ =
         (flags & settings.ChromeCleanupCardFlags.SHOW_LEARN_MORE) != 0;
-    this.isRemoving_ =
-        (flags & settings.ChromeCleanupCardFlags.IS_REMOVING) != 0;
+    this.isWaitingForResult_ =
+        (flags & settings.ChromeCleanupCardFlags.WAITING_FOR_RESULT) != 0;
+    this.showItemsToRemove_ =
+        (flags & settings.ChromeCleanupCardFlags.SHOW_ITEMS_TO_REMOVE) != 0;
 
     // Files to remove list should only be expandable if details are being
     // shown, otherwise it will add extra padding at the bottom of the card.
-    if (!this.showDetails_)
+    if (!this.showExplanation_)
       this.filesToRemoveListExpanded_ = false;
   },
 
@@ -450,11 +580,26 @@
    * @private
    */
   dismiss_: function(source) {
-    this.renderCleanupCard_(settings.ChromeCleanerCardState.HIDDEN_CARD, []);
+    // If user initiated cleanups are enabled, the card won't be shown at the
+    // top of the settings page and the dismiss button should never be rendered.
+    assert(!this.userInitiatedCleanupsEnabled_);
+
+    this.renderCleanupCard_(settings.ChromeCleanerCardState.HIDDEN_CARD);
     this.browserProxy_.dismissCleanupPage(source);
   },
 
   /**
+   * Sends an action to the browser proxy to start scanning.
+   * @private
+   */
+  startScanning_: function() {
+    assert(this.userInitiatedCleanupsEnabled_);
+
+    this.browserProxy_.startScanning(
+        this.$.chromeCleanupLogsUploadControl.checked);
+  },
+
+  /**
    * Sends an action to the browser proxy to start the cleanup.
    * @private
    */
@@ -484,7 +629,7 @@
      */
     var icons = {
       // Card's icon indicates a cleanup offer.
-      REMOVE: {
+      SYSTEM: {
         statusIcon: 'settings:security',
         statusIconClassName: 'status-icon-remove',
       },
@@ -507,6 +652,11 @@
      * @enum {settings.ChromeCleanupCardActionButton}
      */
     var actionButtons = {
+      FIND: {
+        label: this.i18n('chromeCleanupFindButtonLable'),
+        doAction: this.startScanning_.bind(this),
+      },
+
       REMOVE: {
         label: this.i18n('chromeCleanupRemoveButtonLabel'),
         doAction: this.startCleanup_.bind(this),
@@ -529,9 +679,17 @@
         doAction: this.dismiss_.bind(
             this,
             settings.ChromeCleanupDismissSource.CLEANUP_FAILURE_DONE_BUTTON),
-      },
+      }
     };
 
+    // If user-initiated cleanups are enabled, there is no need for a custom
+    // link to the Help Center article, as all settings page sections contain
+    // a help link by default.
+    var learnMoreIfUserInitiatedCleanupsDisabled =
+        this.userInitiatedCleanupsEnabled_ ?
+        0 :
+        settings.ChromeCleanupCardFlags.SHOW_LEARN_MORE;
+
     return new Map([
       [
         settings.ChromeCleanerCardState.HIDDEN_CARD, {
@@ -544,26 +702,29 @@
       [
         settings.ChromeCleanerCardState.CLEANUP_OFFERED, {
           title: this.i18n('chromeCleanupTitleRemove'),
-          icon: icons.REMOVE,
+          explanation: this.i18n('chromeCleanupExplanationRemove'),
+          icon: icons.SYSTEM,
           actionButton: actionButtons.REMOVE,
-          flags: settings.ChromeCleanupCardFlags.SHOW_DETAILS |
-              settings.ChromeCleanupCardFlags.SHOW_LOGS_PERMISSIONS |
-              settings.ChromeCleanupCardFlags.SHOW_LEARN_MORE,
+          flags: settings.ChromeCleanupCardFlags.SHOW_LOGS_PERMISSIONS |
+              settings.ChromeCleanupCardFlags.SHOW_ITEMS_TO_REMOVE |
+              learnMoreIfUserInitiatedCleanupsDisabled,
         }
       ],
       [
         settings.ChromeCleanerCardState.CLEANING, {
           title: this.i18n('chromeCleanupTitleRemoving'),
+          explanation: this.i18n('chromeCleanupExplanationRemove'),
           icon: null,
           actionButton: null,
-          flags: settings.ChromeCleanupCardFlags.SHOW_DETAILS |
-              settings.ChromeCleanupCardFlags.IS_REMOVING |
-              settings.ChromeCleanupCardFlags.SHOW_LEARN_MORE,
+          flags: settings.ChromeCleanupCardFlags.WAITING_FOR_RESULT |
+              learnMoreIfUserInitiatedCleanupsDisabled |
+              settings.ChromeCleanupCardFlags.SHOW_ITEMS_TO_REMOVE,
         }
       ],
       [
         settings.ChromeCleanerCardState.REBOOT_REQUIRED, {
           title: this.i18n('chromeCleanupTitleRestart'),
+          explanation: null,
           icon: icons.DONE,
           actionButton: actionButtons.RESTART_COMPUTER,
           flags: settings.ChromeCleanupCardFlags.NONE,
@@ -572,18 +733,60 @@
       [
         settings.ChromeCleanerCardState.CLEANUP_SUCCEEDED, {
           title: this.i18n('chromeCleanupTitleRemoved'),
+          explanation: null,
           icon: icons.DONE,
-          actionButton: actionButtons.DISMISS_CLEANUP_SUCCESS,
+          actionButton: this.userInitiatedCleanupsEnabled_ ?
+              null :
+              actionButtons.DISMISS_CLEANUP_SUCCESS,
           flags: settings.ChromeCleanupCardFlags.NONE,
         }
       ],
       [
         settings.ChromeCleanerCardState.CLEANING_FAILED, {
           title: this.i18n('chromeCleanupTitleErrorCantRemove'),
+          explanation: this.i18n('chromeCleanupExplanationCleanupError'),
           icon: icons.WARNING,
-          actionButton: actionButtons.DISMISS_CLEANUP_FAILURE,
-          flags: settings.ChromeCleanupCardFlags.SHOW_LEARN_MORE |
-              settings.ChromeCleanupCardFlags.NONE,
+          actionButton: this.userInitiatedCleanupsEnabled_ ?
+              null :
+              actionButtons.DISMISS_CLEANUP_FAILURE,
+          flags: learnMoreIfUserInitiatedCleanupsDisabled,
+        }
+      ],
+      [
+        settings.ChromeCleanerCardState.SCANNING_OFFERED, {
+          title: this.i18n('chromeCleanupTitleFindAndRemove'),
+          explanation: this.i18n('chromeCleanupExplanationFindAndRemove'),
+          icon: icons.SYSTEM,
+          actionButton: actionButtons.FIND,
+          flags: settings.ChromeCleanupCardFlags.SHOW_LOGS_PERMISSIONS,
+        }
+      ],
+      [
+        settings.ChromeCleanerCardState.SCANNING, {
+          title: this.i18n('chromeCleanupTitleScanning'),
+          explanation: null,
+          icon: null,
+          actionButton: null,
+          flags: settings.ChromeCleanupCardFlags.WAITING_FOR_RESULT,
+        }
+      ],
+      [
+        // TODO(crbug.com/776538): Could we offer to reset settings here?
+        settings.ChromeCleanerCardState.SCANNING_FOUND_NOTHING, {
+          title: this.i18n('chromeCleanupTitleNothingFound'),
+          explanation: null,
+          icon: icons.DONE,
+          actionButton: null,
+          flags: settings.ChromeCleanupCardFlags.NONE,
+        }
+      ],
+      [
+        settings.ChromeCleanerCardState.SCANNING_FAILED, {
+          title: this.i18n('chromeCleanupTitleScanningFailed'),
+          explanation: this.i18n('chromeCleanupExplanationScanError'),
+          icon: icons.WARNING,
+          actionButton: null,
+          flags: learnMoreIfUserInitiatedCleanupsDisabled,
         }
       ],
     ]);
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js
index f9e0583..76b3158 100644
--- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js
+++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_proxy.js
@@ -12,6 +12,12 @@
     registerChromeCleanerObserver() {}
 
     /**
+     * Starts scanning the user's computer.
+     * @param {boolean} logsUploadEnabled
+     */
+    startScanning(logsUploadEnabled) {}
+
+    /**
      * Starts a cleanup on the user's computer.
      * @param {boolean} logsUploadEnabled
      */
@@ -56,6 +62,11 @@
     }
 
     /** @override */
+    startScanning(logsUploadEnabled) {
+      chrome.send('startScanning', [logsUploadEnabled]);
+    }
+
+    /** @override */
     startCleanup(logsUploadEnabled) {
       chrome.send('startCleanup', [logsUploadEnabled]);
     }
diff --git a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp
index d170ab31..3159cd1 100644
--- a/chrome/browser/resources/settings/people_page/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/people_page/compiled_resources2.gyp
@@ -140,6 +140,7 @@
       'target_name': 'password_prompt_dialog',
       'dependencies': [
         '../compiled_resources2.gyp:route',
+        '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted',
         '<(EXTERNS_GYP):quick_unlock_private',
         'lock_screen_constants',
       ],
diff --git a/chrome/browser/resources/settings/people_page/password_prompt_dialog.js b/chrome/browser/resources/settings/people_page/password_prompt_dialog.js
index 5115c11f1..f7e485da 100644
--- a/chrome/browser/resources/settings/people_page/password_prompt_dialog.js
+++ b/chrome/browser/resources/settings/people_page/password_prompt_dialog.js
@@ -136,11 +136,14 @@
       // The password might have been cleared during the duration of the
       // getActiveModes call.
       this.passwordInvalid_ = !valid && !!this.password_;
+
+      // Select the whole password if user entered an incorrect password.
       // Return focus to the password input if it lost focus while being checked
       // (user pressed confirm button).
-      if (this.passwordInvalid_ &&
-          this.shadowRoot.activeElement != this.$.passwordInput) {
-        this.$.passwordInput.focus();
+      if (this.passwordInvalid_) {
+        this.$.passwordInput.inputElement.select();
+        if (!this.$.passwordInput.focused)
+          this.$.passwordInput.focus();
       }
 
       if (valid) {
diff --git a/chrome/browser/resources/settings/reset_page/reset_page.html b/chrome/browser/resources/settings/reset_page/reset_page.html
index 44214d07..82b9c6c 100644
--- a/chrome/browser/resources/settings/reset_page/reset_page.html
+++ b/chrome/browser/resources/settings/reset_page/reset_page.html
@@ -27,13 +27,13 @@
         <div class="settings-box first two-line" id="resetProfile"
             on-tap="onShowResetProfileDialog_" actionable>
           <div class="start">
-            $i18n{resetPageTitle}
+            $i18n{resetTrigger}
             <div class="secondary" id="resetProfileSecondary">
-              $i18n{resetPageDescription}
+              $i18n{resetTriggerDescription}
             </div>
           </div>
           <button id="resetProfileArrow" is="paper-icon-button-light"
-              class="subpage-arrow" aria-label="$i18n{resetPageTitle}"
+              class="subpage-arrow" aria-label="$i18n{resetTrigger}"
               aria-describedby="resetProfileSecondary"></button>
         </div>
         <!-- Keep a single instance of reset-profile-dialog on purpose, to
@@ -60,7 +60,6 @@
           </settings-powerwash-dialog>
         </template>
 </if>
-<!-- This needs to be conditioned to a feature being enabled. -->
 <if expr="_google_chrome and is_win">
         <template is="dom-if" if="[[userInitiatedCleanupsEnabled_]]" restamp>
           <div class="settings-box two-line" id="chromeCleanupSubpageTrigger"
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
index b7c6519..f59afeb 100644
--- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
+++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
@@ -65,7 +65,7 @@
       return loadTimeData.getStringF(
           'triggeredResetPageTitle', this.triggeredResetToolName_);
     }
-    return loadTimeData.getStringF('resetPageTitle');
+    return loadTimeData.getStringF('resetTrigger');
   },
 
   /** @override */
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
index ebc9ff6..59e3a1c5 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
@@ -211,6 +211,14 @@
 ChromeCleanerController::~ChromeCleanerController() = default;
 
 bool ChromeCleanerControllerImpl::ShouldShowCleanupInSettingsUI() {
+  // When user-initiated cleanups are enabled, the cleanup card is always shown,
+  // since it's not rendered at the top of chrome://settings.
+  if (delegate_->UserInitiatedCleanupsFeatureEnabled())
+    return true;
+
+  // When user-initiated cleanups are disabled, the cleanup card is only shown
+  // when the controller's current state provides useful information about a
+  // cleanup to the user.
   return state_ == State::kInfected || state_ == State::kCleaning ||
          state_ == State::kRebootRequired ||
          (state_ == State::kIdle &&
@@ -375,7 +383,7 @@
   DCHECK(reporter_invocation.BehaviourIsSupported(
       SwReporterInvocation::BEHAVIOUR_TRIGGER_PROMPT));
 
-  if (state() != State::kIdle)
+  if (state() != State::kIdle && state() != State::kReporterRunning)
     return;
 
   DCHECK(!reporter_invocation_);
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.cc
index 0fe563b..ddc55dc 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.cc
@@ -53,6 +53,10 @@
   OnCleanupStateChange();
 }
 
+void ChromeCleanerStateChangeObserver::OnReporterRunning() {
+  OnCleanupStateChange();
+}
+
 void ChromeCleanerStateChangeObserver::OnInfected(
     const ChromeCleanerScannerResults& reported_results) {
   OnCleanupStateChange();
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.h
index be30708..8f06de8 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.h
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_state_change_observer_win.h
@@ -30,6 +30,7 @@
   // ChromeCleanerController::Observer implementation.
   void OnIdle(ChromeCleanerController::IdleReason idle_reason) override;
   void OnScanning() override;
+  void OnReporterRunning() override;
   void OnInfected(const ChromeCleanerScannerResults& scanner_results) override;
   void OnCleaning(const ChromeCleanerScannerResults& scanner_results) override;
   void OnRebootRequired() override;
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index f68963c..efea49d7 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -45,8 +45,6 @@
 #include "components/search_provider_logos/logo_tracker.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/browser_thread.h"
-#include "crypto/secure_hash.h"
-#include "net/base/hash_value.h"
 #include "net/base/url_util.h"
 #include "net/url_request/url_request.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -184,28 +182,12 @@
   return config_data_js;
 }
 
-std::string GetIntegritySha256Value(const std::string& data) {
-  // Compute the sha256 hash.
-  net::SHA256HashValue hash_value;
-  std::unique_ptr<crypto::SecureHash> hash(
-      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
-  hash->Update(data.data(), data.size());
-  hash->Finish(&hash_value, sizeof(hash_value));
-
-  // Base64-encode it.
-  base::StringPiece hash_value_str(
-      reinterpret_cast<const char*>(hash_value.data), sizeof(hash_value));
-  std::string result;
-  base::Base64Encode(hash_value_str, &result);
-  return result;
-}
-
 std::string GetThemeCSS(Profile* profile) {
   SkColor background_color =
       ThemeService::GetThemeProviderForProfile(profile)
           .GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
 
-  return base::StringPrintf("body { background-color: #%02X%02X%02X; }",
+  return base::StringPrintf("html { background-color: #%02X%02X%02X; }",
                             SkColorGetR(background_color),
                             SkColorGetG(background_color),
                             SkColorGetB(background_color));
@@ -272,25 +254,60 @@
   return result;
 }
 
+// Note: Code that runs on the IO thread is implemented as non-member functions,
+// to avoid accidentally accessing member data that's owned by the UI thread.
+
+bool ShouldServiceRequestIOThread(const GURL& url,
+                                  content::ResourceContext* resource_context,
+                                  int render_process_id) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+  DCHECK(url.host_piece() == chrome::kChromeSearchLocalNtpHost);
+  if (!InstantIOContext::ShouldServiceRequest(url, resource_context,
+                                              render_process_id)) {
+    return false;
+  }
+
+  if (url.SchemeIs(chrome::kChromeSearchScheme)) {
+    std::string filename;
+    webui::ParsePathAndScale(url, &filename, nullptr);
+    for (size_t i = 0; i < arraysize(kResources); ++i) {
+      if (filename == kResources[i].filename)
+        return true;
+    }
+  }
+  return false;
+}
+
+std::string GetContentSecurityPolicyScriptSrcIOThread() {
+#if !defined(GOOGLE_CHROME_BUILD)
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kLocalNtpReload)) {
+    // While live-editing the local NTP files, turn off CSP.
+    return "script-src * 'unsafe-inline';";
+  }
+#endif  // !defined(GOOGLE_CHROME_BUILD)
+
+  return base::StringPrintf(
+      "script-src 'strict-dynamic' 'sha256-%s' 'sha256-%s';",
+      LOCAL_NTP_JS_INTEGRITY, VOICE_JS_INTEGRITY);
+}
+
+std::string GetContentSecurityPolicyChildSrcIOThread() {
+  // Allow embedding of the most visited iframe, as well as the account
+  // switcher and the notifications dropdown from the One Google Bar, and/or
+  // the iframe for interactive Doodles.
+  return base::StringPrintf("child-src %s https://*.google.com/;",
+                            chrome::kChromeSearchMostVisitedUrl);
+}
+
 }  // namespace
 
 class LocalNtpSource::GoogleSearchProviderTracker
     : public TemplateURLServiceObserver {
  public:
-  using SearchProviderIsGoogleChangedCallback =
-      base::Callback<void(bool is_google)>;
-
-  using GoogleBaseUrlChangedCallback =
-      base::Callback<void(const GURL& google_base_url)>;
-
-  GoogleSearchProviderTracker(
-      TemplateURLService* service,
-      const SearchProviderIsGoogleChangedCallback& is_google_callback,
-      const GoogleBaseUrlChangedCallback& google_base_url_callback)
-      : service_(service),
-        is_google_callback_(is_google_callback),
-        google_base_url_callback_(google_base_url_callback),
-        is_google_(false) {
+  explicit GoogleSearchProviderTracker(TemplateURLService* service)
+      : service_(service), is_google_(false) {
     DCHECK(service_);
     service_->AddObserver(this);
     is_google_ = search::DefaultSearchProviderIsGoogle(service_);
@@ -308,15 +325,8 @@
 
  private:
   void OnTemplateURLServiceChanged() override {
-    bool old_is_google = is_google_;
     is_google_ = search::DefaultSearchProviderIsGoogle(service_);
-    if (is_google_ != old_is_google)
-      is_google_callback_.Run(is_google_);
-
-    const GURL old_google_base_url = google_base_url_;
     google_base_url_ = GURL(service_->search_terms_data().GoogleBaseURLValue());
-    if (google_base_url_ != old_google_base_url)
-      google_base_url_callback_.Run(google_base_url_);
   }
 
   void OnTemplateURLServiceShuttingDown() override {
@@ -325,8 +335,6 @@
   }
 
   TemplateURLService* service_;
-  SearchProviderIsGoogleChangedCallback is_google_callback_;
-  GoogleBaseUrlChangedCallback google_base_url_callback_;
 
   bool is_google_;
   GURL google_base_url_;
@@ -447,8 +455,6 @@
           OneGoogleBarServiceFactory::GetForProfile(profile_)),
       one_google_bar_service_observer_(this),
       logo_service_(nullptr),
-      default_search_provider_is_google_(false),
-      default_search_provider_is_google_io_thread_(false),
       weak_ptr_factory_(this) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
@@ -465,15 +471,8 @@
   TemplateURLService* template_url_service =
       TemplateURLServiceFactory::GetForProfile(profile_);
   if (template_url_service) {
-    google_tracker_ = base::MakeUnique<GoogleSearchProviderTracker>(
-        template_url_service,
-        base::Bind(&LocalNtpSource::DefaultSearchProviderIsGoogleChanged,
-                   base::Unretained(this)),
-        base::Bind(&LocalNtpSource::GoogleBaseUrlChanged,
-                   base::Unretained(this)));
-    DefaultSearchProviderIsGoogleChanged(
-        google_tracker_->DefaultSearchProviderIsGoogle());
-    GoogleBaseUrlChanged(google_tracker_->GetGoogleBaseUrl());
+    google_tracker_ =
+        base::MakeUnique<GoogleSearchProviderTracker>(template_url_service);
   }
 }
 
@@ -492,7 +491,8 @@
   std::string stripped_path = StripParameters(path);
   if (stripped_path == kConfigDataFilename) {
     std::string config_data_js =
-        GetConfigData(default_search_provider_is_google_, google_base_url_);
+        GetConfigData(google_tracker_->DefaultSearchProviderIsGoogle(),
+                      google_tracker_->GetGoogleBaseUrl());
     callback.Run(base::RefCountedString::TakeString(&config_data_js));
     return;
   }
@@ -551,13 +551,6 @@
     std::string html = ui::ResourceBundle::GetSharedInstance()
                            .GetRawDataResource(IDR_LOCAL_NTP_HTML)
                            .as_string();
-    std::string config_integrity = base::StringPrintf(
-        kIntegrityFormat,
-        GetIntegritySha256Value(
-            GetConfigData(default_search_provider_is_google_, google_base_url_))
-            .c_str());
-    base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{CONFIG_INTEGRITY}}",
-                                           config_integrity);
     std::string local_ntp_integrity =
         base::StringPrintf(kIntegrityFormat, LOCAL_NTP_JS_INTEGRITY);
     base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{LOCAL_NTP_INTEGRITY}}",
@@ -613,63 +606,30 @@
     int render_process_id) const {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
-  DCHECK(url.host_piece() == chrome::kChromeSearchLocalNtpHost);
-  if (!InstantIOContext::ShouldServiceRequest(url, resource_context,
-                                              render_process_id)) {
-    return false;
-  }
-
-  if (url.SchemeIs(chrome::kChromeSearchScheme)) {
-    std::string filename;
-    webui::ParsePathAndScale(url, &filename, nullptr);
-    for (size_t i = 0; i < arraysize(kResources); ++i) {
-      if (filename == kResources[i].filename)
-        return true;
-    }
-  }
-  return false;
+  return ShouldServiceRequestIOThread(url, resource_context, render_process_id);
 }
 
 std::string LocalNtpSource::GetContentSecurityPolicyScriptSrc() const {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
-#if !defined(GOOGLE_CHROME_BUILD)
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kLocalNtpReload)) {
-    // While live-editing the local NTP files, turn off CSP.
-    return "script-src * 'unsafe-inline';";
-  }
-#endif  // !defined(GOOGLE_CHROME_BUILD)
-
-  return base::StringPrintf(
-      "script-src 'strict-dynamic' 'sha256-%s' 'sha256-%s' 'sha256-%s';",
-      GetIntegritySha256Value(
-          GetConfigData(default_search_provider_is_google_io_thread_,
-                        google_base_url_io_thread_))
-          .c_str(),
-      LOCAL_NTP_JS_INTEGRITY, VOICE_JS_INTEGRITY);
+  return GetContentSecurityPolicyScriptSrcIOThread();
 }
 
 std::string LocalNtpSource::GetContentSecurityPolicyChildSrc() const {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
-  if (one_google_bar_service_ || logo_service_) {
-    // Allow embedding of the most visited iframe, as well as the account
-    // switcher and the notifications dropdown from the One Google Bar, and/or
-    // the iframe for interactive Doodles.
-    return base::StringPrintf("child-src %s https://*.google.com/;",
-                              chrome::kChromeSearchMostVisitedUrl);
-  }
-  // Allow embedding of the most visited iframe.
-  return base::StringPrintf("child-src %s;",
-                            chrome::kChromeSearchMostVisitedUrl);
+  return GetContentSecurityPolicyChildSrcIOThread();
 }
 
 void LocalNtpSource::OnOneGoogleBarDataUpdated() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
   ServeOneGoogleBar(one_google_bar_service_->one_google_bar_data());
 }
 
 void LocalNtpSource::OnOneGoogleBarServiceShuttingDown() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
   one_google_bar_service_observer_.RemoveAll();
   one_google_bar_service_ = nullptr;
 }
@@ -705,40 +665,6 @@
   one_google_bar_requests_.clear();
 }
 
-void LocalNtpSource::DefaultSearchProviderIsGoogleChanged(bool is_google) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  default_search_provider_is_google_ = is_google;
-  content::BrowserThread::PostTask(
-      content::BrowserThread::IO, FROM_HERE,
-      base::BindOnce(
-          &LocalNtpSource::SetDefaultSearchProviderIsGoogleOnIOThread,
-          weak_ptr_factory_.GetWeakPtr(), is_google));
-}
-
-void LocalNtpSource::SetDefaultSearchProviderIsGoogleOnIOThread(
-    bool is_google) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
-  default_search_provider_is_google_io_thread_ = is_google;
-}
-
-void LocalNtpSource::GoogleBaseUrlChanged(const GURL& google_base_url) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  google_base_url_ = google_base_url;
-  content::BrowserThread::PostTask(
-      content::BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&LocalNtpSource::SetGoogleBaseUrlOnIOThread,
-                     weak_ptr_factory_.GetWeakPtr(), google_base_url));
-}
-
-void LocalNtpSource::SetGoogleBaseUrlOnIOThread(const GURL& google_base_url) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
-  google_base_url_io_thread_ = google_base_url;
-}
-
 LocalNtpSource::OneGoogleBarRequest::OneGoogleBarRequest(
     base::TimeTicks start_time,
     const content::URLDataSource::GotDataCallback& callback)
diff --git a/chrome/browser/search/local_ntp_source.h b/chrome/browser/search/local_ntp_source.h
index 3d2566a..a2854f98 100644
--- a/chrome/browser/search/local_ntp_source.h
+++ b/chrome/browser/search/local_ntp_source.h
@@ -74,14 +74,6 @@
 
   void ServeOneGoogleBar(const base::Optional<OneGoogleBarData>& data);
 
-  void DefaultSearchProviderIsGoogleChanged(bool is_google);
-
-  void SetDefaultSearchProviderIsGoogleOnIOThread(bool is_google);
-
-  void GoogleBaseUrlChanged(const GURL& google_base_url);
-
-  void SetGoogleBaseUrlOnIOThread(const GURL& google_base_url);
-
   Profile* const profile_;
 
   OneGoogleBarService* one_google_bar_service_;
@@ -95,13 +87,6 @@
   std::vector<OneGoogleBarRequest> one_google_bar_requests_;
 
   std::unique_ptr<GoogleSearchProviderTracker> google_tracker_;
-  bool default_search_provider_is_google_;
-  // A copy of |default_search_provider_is_google_| for use on the IO thread.
-  bool default_search_provider_is_google_io_thread_;
-
-  GURL google_base_url_;
-  // A copy of |google_base_url_| for use on the IO thread.
-  GURL google_base_url_io_thread_;
 
   base::WeakPtrFactory<LocalNtpSource> weak_ptr_factory_;
 
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index 14386af..cea27c1 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -48,20 +48,15 @@
 const char kServiceWorkerFileName[] = "newtab-serviceworker.js";
 
 bool MatchesOrigin(const GURL& my_url, const GURL& other_url) {
-  return my_url.host_piece() == other_url.host_piece() &&
-         my_url.port() == other_url.port() &&
-         (my_url.scheme_piece() == other_url.scheme_piece() ||
-          (my_url.SchemeIs(url::kHttpsScheme) &&
-           other_url.SchemeIs(url::kHttpScheme)));
+  return my_url.scheme_piece() == other_url.scheme_piece() &&
+         my_url.host_piece() == other_url.host_piece() &&
+         my_url.port() == other_url.port();
 }
 
 }  // namespace
 
 // Returns true if |my_url| matches |other_url| in terms of origin (i.e. host,
-// port, and scheme) and path. As a special case, this also matches if |my_url|
-// is "https://" and |other_url| is "http://" (and host, port, and path match).
-// This is so that "https://" URLs will be considered "Instant URLs" even if the
-// default search provider URL is "http://".
+// port, and scheme) and path.
 // Defined outside of the anonymous namespace so that it's accessible to unit
 // tests.
 bool MatchesOriginAndPath(const GURL& my_url, const GURL& other_url) {
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index 89aea28..d1a9543 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -53,8 +53,8 @@
                                     GURL("http://example.com/path")));
   EXPECT_FALSE(MatchesOriginAndPath(GURL("http://example.com/path"),
                                     GURL("https://example.com/path")));
-  EXPECT_TRUE(MatchesOriginAndPath(GURL("https://example.com/path"),
-                                   GURL("http://example.com/path")));
+  EXPECT_FALSE(MatchesOriginAndPath(GURL("https://example.com/path"),
+                                    GURL("http://example.com/path")));
   EXPECT_FALSE(MatchesOriginAndPath(GURL("http://example.com/path"),
                                     GURL("http://example.com/another-path")));
 }
diff --git a/chrome/browser/service_process/service_process_control_browsertest.cc b/chrome/browser/service_process/service_process_control_browsertest.cc
index 8d72fe2..00436d9 100644
--- a/chrome/browser/service_process/service_process_control_browsertest.cc
+++ b/chrome/browser/service_process/service_process_control_browsertest.cc
@@ -168,13 +168,7 @@
   EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
 }
 
-// Flaky on Windows. crbug.com/791791
-#if defined(OS_WIN)
-#define MAYBE_LaunchAndIPC DISABLED_LaunchAndIPC
-#else
-#define MAYBE_LaunchAndIPC LaunchAndIPC
-#endif
-IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_LaunchAndIPC) {
+IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchAndIPC) {
   LaunchServiceProcessControl(true);
 
   // Make sure we are connected to the service process.
@@ -190,14 +184,7 @@
   EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
 }
 
-// Flaky on Windows. crbug.com/791791
-#if defined(OS_WIN)
-#define MAYBE_LaunchAndReconnect DISABLED_LaunchAndReconnect
-#else
-#define MAYBE_LaunchAndReconnect LaunchAndReconnect
-#endif
-IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
-                       MAYBE_LaunchAndReconnect) {
+IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchAndReconnect) {
   LaunchServiceProcessControl(true);
 
   // Make sure we are connected to the service process.
diff --git a/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc b/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc
index edb608b..245ff06 100644
--- a/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc
+++ b/chrome/browser/sessions/persistent_tab_restore_service_unittest.cc
@@ -607,7 +607,7 @@
 
   // We should get back kMaxEntries entries. We added more, but
   // TabRestoreService only allows up to kMaxEntries.
-  ASSERT_EQ(kMaxEntries, service_->entries().size());
+  ASSERT_EQ(static_cast<size_t>(kMaxEntries), service_->entries().size());
 
   // The first entry should come from the session service.
   sessions::TabRestoreService::Entry* entry = service_->entries().front().get();
diff --git a/chrome/browser/signin/dice_response_handler.cc b/chrome/browser/signin/dice_response_handler.cc
index 42fad68..5cb3d61 100644
--- a/chrome/browser/signin/dice_response_handler.cc
+++ b/chrome/browser/signin/dice_response_handler.cc
@@ -13,6 +13,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/about_signin_internals_factory.h"
 #include "chrome/browser/signin/account_reconcilor_factory.h"
 #include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
@@ -20,6 +21,7 @@
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/signin/core/browser/about_signin_internals.h"
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_management_switches.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
@@ -85,6 +87,7 @@
       : BrowserContextKeyedServiceFactory(
             "DiceResponseHandler",
             BrowserContextDependencyManager::GetInstance()) {
+    DependsOn(AboutSigninInternalsFactory::GetInstance());
     DependsOn(AccountReconcilorFactory::GetInstance());
     DependsOn(AccountTrackerServiceFactory::GetInstance());
     DependsOn(ChromeSigninClientFactory::GetInstance());
@@ -106,7 +109,8 @@
         SigninManagerFactory::GetForProfile(profile),
         ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
         AccountTrackerServiceFactory::GetForProfile(profile),
-        AccountReconcilorFactory::GetForProfile(profile));
+        AccountReconcilorFactory::GetForProfile(profile),
+        AboutSigninInternalsFactory::GetForProfile(profile));
   }
 };
 
@@ -181,8 +185,7 @@
   RecordDiceFetchTokenResult(kFetchSuccess);
   gaia_auth_fetcher_.reset();
   timeout_closure_.Cancel();
-  dice_response_handler_->OnTokenExchangeSuccess(
-      this, gaia_id_, email_, result.refresh_token, std::move(delegate_));
+  dice_response_handler_->OnTokenExchangeSuccess(this, result.refresh_token);
   // |this| may be deleted at this point.
 }
 
@@ -209,17 +212,20 @@
     SigninManager* signin_manager,
     ProfileOAuth2TokenService* profile_oauth2_token_service,
     AccountTrackerService* account_tracker_service,
-    AccountReconcilor* account_reconcilor)
+    AccountReconcilor* account_reconcilor,
+    AboutSigninInternals* about_signin_internals)
     : signin_manager_(signin_manager),
       signin_client_(signin_client),
       token_service_(profile_oauth2_token_service),
       account_tracker_service_(account_tracker_service),
-      account_reconcilor_(account_reconcilor) {
+      account_reconcilor_(account_reconcilor),
+      about_signin_internals_(about_signin_internals) {
   DCHECK(signin_client_);
   DCHECK(signin_manager_);
   DCHECK(token_service_);
   DCHECK(account_tracker_service_);
   DCHECK(account_reconcilor_);
+  DCHECK(about_signin_internals_);
 }
 
 DiceResponseHandler::~DiceResponseHandler() {}
@@ -392,26 +398,34 @@
 
 void DiceResponseHandler::OnTokenExchangeSuccess(
     DiceTokenFetcher* token_fetcher,
-    std::string gaia_id,
-    std::string email,
-    std::string refresh_token,
-    std::unique_ptr<ProcessDiceHeaderDelegate> delegate) {
+    const std::string& refresh_token) {
+  const std::string& email = token_fetcher->email();
+  const std::string& gaia_id = token_fetcher->gaia_id();
   if (!CanGetTokenForAccount(gaia_id, email))
     return;
   VLOG(1) << "[Dice] OAuth success for email " << email;
   bool should_enable_sync = token_fetcher->should_enable_sync();
-  DeleteTokenFetcher(token_fetcher);
   std::string account_id =
       account_tracker_service_->SeedAccountInfo(gaia_id, email);
   token_service_->UpdateCredentials(account_id, refresh_token);
+  about_signin_internals_->OnRefreshTokenReceived(
+      base::StringPrintf("Successful (%s)", account_id.c_str()));
   if (should_enable_sync)
-    delegate->EnableSync(account_id);
+    token_fetcher->delegate()->EnableSync(account_id);
+
+  DeleteTokenFetcher(token_fetcher);
 }
 
 void DiceResponseHandler::OnTokenExchangeFailure(
     DiceTokenFetcher* token_fetcher,
     const GoogleServiceAuthError& error) {
-  // TODO(droger): Handle authentication errors.
-  VLOG(1) << "[Dice] OAuth failed with error: " << error.ToString();
+  const std::string& email = token_fetcher->email();
+  const std::string& gaia_id = token_fetcher->gaia_id();
+  std::string account_id =
+      account_tracker_service_->PickAccountIdForAccount(gaia_id, email);
+  about_signin_internals_->OnRefreshTokenReceived(
+      base::StringPrintf("Failure (%s)", account_id.c_str()));
+  token_fetcher->delegate()->HandleTokenExchangeFailure(email, error);
+
   DeleteTokenFetcher(token_fetcher);
 }
diff --git a/chrome/browser/signin/dice_response_handler.h b/chrome/browser/signin/dice_response_handler.h
index f783927f..f414f489 100644
--- a/chrome/browser/signin/dice_response_handler.h
+++ b/chrome/browser/signin/dice_response_handler.h
@@ -16,6 +16,7 @@
 #include "components/signin/core/browser/signin_header_helper.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
 
+class AboutSigninInternals;
 class AccountTrackerService;
 class GaiaAuthFetcher;
 class GoogleServiceAuthError;
@@ -36,6 +37,11 @@
   // Called after the account was seeded in the account tracker service and
   // after the refresh token was fetched and updated in the token service.
   virtual void EnableSync(const std::string& account_id) = 0;
+
+  // Handles a failure in the token exchange (i.e. shows the error to the user).
+  virtual void HandleTokenExchangeFailure(
+      const std::string& email,
+      const GoogleServiceAuthError& error) = 0;
 };
 
 // Processes the Dice responses from Gaia.
@@ -49,7 +55,8 @@
                       SigninManager* signin_manager,
                       ProfileOAuth2TokenService* profile_oauth2_token_service,
                       AccountTrackerService* account_tracker_service,
-                      AccountReconcilor* account_reconcilor);
+                      AccountReconcilor* account_reconcilor,
+                      AboutSigninInternals* about_signin_internals);
   ~DiceResponseHandler() override;
 
   // Must be called when receiving a Dice response header.
@@ -81,6 +88,7 @@
     void set_should_enable_sync(bool should_enable_sync) {
       should_enable_sync_ = should_enable_sync;
     }
+    ProcessDiceHeaderDelegate* delegate() { return delegate_.get(); }
 
    private:
     // Called by |timeout_closure_| when the request times out.
@@ -134,12 +142,8 @@
 
   // Called after exchanging an OAuth 2.0 authorization code for a refresh token
   // after DiceAction::SIGNIN.
-  void OnTokenExchangeSuccess(
-      DiceTokenFetcher* token_fetcher,
-      std::string gaia_id,
-      std::string email,
-      std::string refresh_token,
-      std::unique_ptr<ProcessDiceHeaderDelegate> delegate);
+  void OnTokenExchangeSuccess(DiceTokenFetcher* token_fetcher,
+                              const std::string& refresh_token);
   void OnTokenExchangeFailure(DiceTokenFetcher* token_fetcher,
                               const GoogleServiceAuthError& error);
 
@@ -148,6 +152,7 @@
   ProfileOAuth2TokenService* token_service_;
   AccountTrackerService* account_tracker_service_;
   AccountReconcilor* account_reconcilor_;
+  AboutSigninInternals* about_signin_internals_;
   std::vector<std::unique_ptr<DiceTokenFetcher>> token_fetchers_;
 
   DISALLOW_COPY_AND_ASSIGN(DiceResponseHandler);
diff --git a/chrome/browser/signin/dice_response_handler_unittest.cc b/chrome/browser/signin/dice_response_handler_unittest.cc
index e6a5a79..0a0701f 100644
--- a/chrome/browser/signin/dice_response_handler_unittest.cc
+++ b/chrome/browser/signin/dice_response_handler_unittest.cc
@@ -17,18 +17,22 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/signin/core/browser/about_signin_internals.h"
 #include "components/signin/core/browser/account_reconcilor.h"
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/dice_account_reconcilor_delegate.h"
+#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h"
 #include "components/signin/core/browser/fake_signin_manager.h"
 #include "components/signin/core/browser/profile_management_switches.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/scoped_account_consistency.h"
+#include "components/signin/core/browser/signin_error_controller.h"
 #include "components/signin/core/browser/signin_header_helper.h"
 #include "components/signin/core/browser/test_signin_client.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "google_apis/gaia/fake_oauth2_token_service_delegate.h"
+#include "google_apis/gaia/gaia_constants.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -101,6 +105,12 @@
     enable_sync_account_id_ = account_id;
   }
 
+  void HandleTokenExchangeFailure(const std::string& email,
+                                  const GoogleServiceAuthError& error) {
+    auth_error_email_ = email;
+    auth_error_ = error;
+  }
+
  protected:
   DiceResponseHandlerTest()
       : loop_(base::MessageLoop::TYPE_IO),  // URLRequestContext requires IO.
@@ -114,11 +124,20 @@
                         &token_service_,
                         &account_tracker_service_,
                         nullptr),
+        cookie_service_(&token_service_,
+                        GaiaConstants::kChromeSource,
+                        &signin_client_),
+        about_signin_internals_(&token_service_,
+                                &account_tracker_service_,
+                                &signin_manager_,
+                                &signin_error_controller_,
+                                &cookie_service_),
         reconcilor_blocked_count_(0),
         reconcilor_unblocked_count_(0) {
     loop_.SetTaskRunner(task_runner_);
     DCHECK_EQ(task_runner_, base::ThreadTaskRunnerHandle::Get());
     signin_client_.SetURLRequestContext(request_context_getter_.get());
+    AboutSigninInternals::RegisterPrefs(pref_service_.registry());
     AccountTrackerService::RegisterPrefs(pref_service_.registry());
     SigninManager::RegisterProfilePrefs(pref_service_.registry());
     signin::RegisterAccountConsistencyProfilePrefs(pref_service_.registry());
@@ -129,9 +148,11 @@
     account_reconcilor_ = std::make_unique<AccountReconcilor>(
         &token_service_, &signin_manager_, &signin_client_, nullptr,
         std::move(account_reconcilor_delegate));
+    about_signin_internals_.Initialize(&signin_client_);
     dice_response_handler_ = std::make_unique<DiceResponseHandler>(
         &signin_client_, &signin_manager_, &token_service_,
-        &account_tracker_service_, account_reconcilor_.get());
+        &account_tracker_service_, account_reconcilor_.get(),
+        &about_signin_internals_);
 
     account_tracker_service_.Initialize(&signin_client_);
     account_reconcilor_->AddObserver(this);
@@ -139,6 +160,14 @@
 
   ~DiceResponseHandlerTest() override {
     account_reconcilor_->RemoveObserver(this);
+    account_reconcilor_->Shutdown();
+    about_signin_internals_.Shutdown();
+    cookie_service_.Shutdown();
+    signin_error_controller_.Shutdown();
+    signin_manager_.Shutdown();
+    account_tracker_service_.Shutdown();
+    token_service_.Shutdown();
+    signin_client_.Shutdown();
     task_runner_->ClearPendingTasks();
   }
 
@@ -185,11 +214,16 @@
   ProfileOAuth2TokenService token_service_;
   AccountTrackerService account_tracker_service_;
   FakeSigninManager signin_manager_;
+  SigninErrorController signin_error_controller_;
+  FakeGaiaCookieManagerService cookie_service_;
+  AboutSigninInternals about_signin_internals_;
   std::unique_ptr<AccountReconcilor> account_reconcilor_;
   std::unique_ptr<DiceResponseHandler> dice_response_handler_;
   int reconcilor_blocked_count_;
   int reconcilor_unblocked_count_;
   std::string enable_sync_account_id_;
+  GoogleServiceAuthError auth_error_;
+  std::string auth_error_email_;
 };
 
 class TestProcessDiceHeaderDelegate : public ProcessDiceHeaderDelegate {
@@ -204,6 +238,12 @@
     owner_->EnableSync(account_id);
   }
 
+  void HandleTokenExchangeFailure(
+      const std::string& email,
+      const GoogleServiceAuthError& error) override {
+    owner_->HandleTokenExchangeFailure(email, error);
+  }
+
  private:
   DiceResponseHandlerTest* owner_;
 };
@@ -228,6 +268,8 @@
                                           false /* is_child_account */));
   // Check that the token has been inserted in the token service.
   EXPECT_TRUE(token_service_.RefreshTokenIsAvailable(account_id));
+  EXPECT_TRUE(auth_error_email_.empty());
+  EXPECT_EQ(GoogleServiceAuthError::NONE, auth_error_.state());
   // Check that the reconcilor was blocked and unblocked exactly once.
   EXPECT_EQ(1, reconcilor_blocked_count_);
   EXPECT_EQ(1, reconcilor_unblocked_count_);
@@ -248,12 +290,16 @@
   EXPECT_EQ(
       1u, dice_response_handler_->GetPendingDiceTokenFetchersCountForTesting());
   // Simulate GaiaAuthFetcher failure.
+  GoogleServiceAuthError::State error_state =
+      GoogleServiceAuthError::SERVICE_UNAVAILABLE;
   signin_client_.consumer_->OnClientOAuthFailure(
-      GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
+      GoogleServiceAuthError(error_state));
   EXPECT_EQ(
       0u, dice_response_handler_->GetPendingDiceTokenFetchersCountForTesting());
   // Check that the token has not been inserted in the token service.
   EXPECT_FALSE(token_service_.RefreshTokenIsAvailable(account_id));
+  EXPECT_EQ(account_info.email, auth_error_email_);
+  EXPECT_EQ(error_state, auth_error_.state());
 }
 
 // Checks that a second token for the same account is not requested when a
diff --git a/chrome/browser/signin/dice_tab_helper.cc b/chrome/browser/signin/dice_tab_helper.cc
index bab2d8df..b9e98a5 100644
--- a/chrome/browser/signin/dice_tab_helper.cc
+++ b/chrome/browser/signin/dice_tab_helper.cc
@@ -23,16 +23,12 @@
 
 DiceTabHelper::~DiceTabHelper() {}
 
-void DiceTabHelper::SetSigninAccessPoint(
-    signin_metrics::AccessPoint access_point) {
-  DCHECK_EQ(signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
-            signin_access_point_);
+void DiceTabHelper::InitializeSigninFlow(
+    signin_metrics::AccessPoint access_point,
+    signin_metrics::Reason reason) {
   signin_access_point_ = access_point;
-}
-
-void DiceTabHelper::SetSigninReason(signin_metrics::Reason reason) {
-  DCHECK_EQ(signin_metrics::Reason::REASON_UNKNOWN_REASON, signin_reason_);
   signin_reason_ = reason;
+  should_start_sync_after_web_signin_ = true;
 }
 
 void DiceTabHelper::DidStartNavigation(
diff --git a/chrome/browser/signin/dice_tab_helper.h b/chrome/browser/signin/dice_tab_helper.h
index 987ad22..8e9aecf 100644
--- a/chrome/browser/signin/dice_tab_helper.h
+++ b/chrome/browser/signin/dice_tab_helper.h
@@ -28,11 +28,10 @@
     return should_start_sync_after_web_signin_;
   }
 
-  // Sets the sign-in access point. Should be called only once.
-  void SetSigninAccessPoint(signin_metrics::AccessPoint access_point);
-
-  // Sets the sign-in reason. Should be called only once.
-  void SetSigninReason(signin_metrics::Reason reason);
+  // Initializes the DiceTabHelper for a new signin flow. Must be called once
+  // per signin flow happening in the tab.
+  void InitializeSigninFlow(signin_metrics::AccessPoint access_point,
+                            signin_metrics::Reason reason);
 
   // content::WebContentsObserver:
   void DidStartNavigation(
diff --git a/chrome/browser/signin/dice_tab_helper_unittest.cc b/chrome/browser/signin/dice_tab_helper_unittest.cc
new file mode 100644
index 0000000..0c66541
--- /dev/null
+++ b/chrome/browser/signin/dice_tab_helper_unittest.cc
@@ -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.
+
+#include "chrome/browser/signin/dice_tab_helper.h"
+
+#include "chrome/test/base/testing_profile.h"
+#include "components/signin/core/browser/signin_metrics.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_web_contents_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Tests DiceTabHelper intialization.
+TEST(DiceTabHelperTest, Initialization) {
+  content::TestBrowserThreadBundle thread_bundle;
+  TestingProfile profile;
+  content::TestWebContentsFactory factory;
+  content::WebContents* web_contents = factory.CreateWebContents(&profile);
+  DiceTabHelper::CreateForWebContents(web_contents);
+  DiceTabHelper* dice_tab_helper = DiceTabHelper::FromWebContents(web_contents);
+
+  // Check default state.
+  EXPECT_EQ(signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
+            dice_tab_helper->signin_access_point());
+  EXPECT_EQ(signin_metrics::Reason::REASON_UNKNOWN_REASON,
+            dice_tab_helper->signin_reason());
+  EXPECT_TRUE(dice_tab_helper->should_start_sync_after_web_signin());
+
+  // Initialize the signin flow.
+  signin_metrics::AccessPoint access_point =
+      signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE;
+  signin_metrics::Reason reason =
+      signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT;
+  dice_tab_helper->InitializeSigninFlow(access_point, reason);
+  EXPECT_EQ(access_point, dice_tab_helper->signin_access_point());
+  EXPECT_EQ(reason, dice_tab_helper->signin_reason());
+}
diff --git a/chrome/browser/signin/process_dice_header_delegate_impl.cc b/chrome/browser/signin/process_dice_header_delegate_impl.cc
index 32568a8..ae68a90 100644
--- a/chrome/browser/signin/process_dice_header_delegate_impl.cc
+++ b/chrome/browser/signin/process_dice_header_delegate_impl.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/signin/process_dice_header_delegate_impl.h"
 
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/dice_tab_helper.h"
@@ -12,6 +14,8 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h"
+#include "chrome/browser/ui/webui/signin/login_ui_service.h"
+#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "chrome/common/webui_url_constants.h"
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_management_switches.h"
@@ -91,7 +95,6 @@
   Browser* browser = nullptr;
   if (web_contents) {
     browser = chrome::FindBrowserWithWebContents(web_contents);
-
     // After signing in to Chrome, the user should be redirected to the NTP.
     RedirectToNtp(web_contents);
   }
@@ -102,3 +105,25 @@
   new DiceTurnSyncOnHelper(profile_, browser, signin_access_point_,
                            signin_reason_, account_id);
 }
+
+void ProcessDiceHeaderDelegateImpl::HandleTokenExchangeFailure(
+    const std::string& email,
+    const GoogleServiceAuthError& error) {
+  DCHECK_NE(GoogleServiceAuthError::NONE, error.state());
+  bool should_enable_sync = ShouldEnableSync();
+  if (!should_enable_sync &&
+      !signin::IsDiceEnabledForProfile(profile_->GetPrefs())) {
+    return;
+  }
+
+  // Show pop up-dialog.
+  content::WebContents* web_contents = this->web_contents();
+  Browser* browser = web_contents
+                         ? chrome::FindBrowserWithWebContents(web_contents)
+                         : chrome::FindBrowserWithProfile(profile_);
+  LoginUIServiceFactory::GetForProfile(profile_)->DisplayLoginResult(
+      browser, base::UTF8ToUTF16(error.ToString()), base::UTF8ToUTF16(email));
+
+  if (should_enable_sync && web_contents)
+    RedirectToNtp(web_contents);
+}
diff --git a/chrome/browser/signin/process_dice_header_delegate_impl.h b/chrome/browser/signin/process_dice_header_delegate_impl.h
index ca6ca619..4eaed91 100644
--- a/chrome/browser/signin/process_dice_header_delegate_impl.h
+++ b/chrome/browser/signin/process_dice_header_delegate_impl.h
@@ -21,6 +21,8 @@
 
   // ProcessDiceHeaderDelegate:
   void EnableSync(const std::string& account_id) override;
+  void HandleTokenExchangeFailure(const std::string& email,
+                                  const GoogleServiceAuthError& error) override;
 
  private:
   // Returns true if sync should be enabled after the user signs in.
diff --git a/chrome/browser/site_details_browsertest.cc b/chrome/browser/site_details_browsertest.cc
index a319208..fe2eee9 100644
--- a/chrome/browser/site_details_browsertest.cc
+++ b/chrome/browser/site_details_browsertest.cc
@@ -543,7 +543,15 @@
   EXPECT_THAT(details->uma()->GetAllSamples(
                   "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
               HasOneSample(3));
-  EXPECT_THAT(GetRenderProcessCount(), DependingOnPolicy(3, 3, 15));
+
+  // For --site-per-process, the total process count will be 12 instead of 15,
+  // because the third tab's subframes (b, c, d) will reuse matching subframe
+  // processes from the second tab (across BrowsingInstances).  This subframe
+  // process consolidation was added as part of https://crbug.com/512560.  Note
+  // that the a.com main frame in tab 3 won't reuse tab 2's main frame process,
+  // so this is still one process higher than the lower bound.
+  EXPECT_THAT(GetRenderProcessCount(), DependingOnPolicy(3, 3, 12));
+
   EXPECT_THAT(details->GetOutOfProcessIframeCount(),
               DependingOnPolicy(0, 0, 17));
   EXPECT_THAT(details->uma()->GetAllSamples("SiteIsolation.ProxyCount"),
@@ -610,7 +618,7 @@
   EXPECT_THAT(details->uma()->GetAllSamples(
                   "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
               HasOneSample(3));
-  EXPECT_THAT(GetRenderProcessCount(), DependingOnPolicy(3, 3, 16));
+  EXPECT_THAT(GetRenderProcessCount(), DependingOnPolicy(3, 3, 13));
   EXPECT_THAT(details->GetOutOfProcessIframeCount(),
               DependingOnPolicy(0, 0, 21));
   EXPECT_THAT(details->uma()->GetAllSamples("SiteIsolation.ProxyCount"),
@@ -899,7 +907,18 @@
   EXPECT_THAT(details->uma()->GetAllSamples(
                   "SiteIsolation.IsolateExtensionsProcessCountNoLimit"),
               HasOneSample(4));
-  EXPECT_THAT(GetRenderProcessCount(), DependingOnPolicy(2, 4, 4));
+
+  // As part of https://crbug.com/512560, subframes that require a dedicated
+  // process started reusing existing processes when possible, so under
+  // --site-per-process, tab1's web iframe will share the process with tab2's
+  // web iframe, since they have the same site. This won't affect
+  // --isolate-extensions, because the web iframe's site won't require a
+  // dedicated process in that mode. Hence, with site-per-process, there should
+  // be three total renderer processes: one for the two web iframes, one for
+  // extension3, and one for extension 1's background page. With only
+  // --isolate-extensions, there should be four total renderer processes, as
+  // each web iframe will go into its own process.
+  EXPECT_THAT(GetRenderProcessCount(), DependingOnPolicy(2, 4, 3));
   EXPECT_THAT(details->GetOutOfProcessIframeCount(),
               DependingOnPolicy(0, 2, 2));
 }
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index f63326a..e7b03b79 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -5096,6 +5096,84 @@
   CheckAuthenticatedState(tab, AuthState::NONE);
 }
 
+namespace {
+
+// A handler which changes the response. The first time it's called for
+// |relative_url| it'll give an empty response. The second time it'll
+// redirect to |redirect_url|.
+std::unique_ptr<net::test_server::HttpResponse> ChangingHandler(
+    int* count,
+    const std::string& relative_url,
+    const GURL& redirect_url,
+    const net::test_server::HttpRequest& request) {
+  if (request.relative_url != relative_url)
+    return nullptr;
+
+  std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
+      new net::test_server::BasicHttpResponse);
+  if ((*count)++) {
+    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
+    http_response->AddCustomHeader("Location", redirect_url.spec());
+  }
+  return std::move(http_response);
+}
+
+}  // namespace
+
+// Check that SSL state isn't stale when navigating to an existing page that
+// gives a different response. This covers the case of going from http to
+// https. http://crbug.com/792221
+IN_PROC_BROWSER_TEST_F(SSLUITest, ExistingPageHTTPToHTTPSSSLState) {
+  ASSERT_TRUE(https_server_.Start());
+  int count = 0;
+  std::string relative_url = "/foo";
+  GURL redirect_url = https_server_.GetURL("/simple.html");
+  embedded_test_server()->RegisterRequestHandler(
+      base::BindRepeating(ChangingHandler, &count, relative_url, redirect_url));
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL url = embedded_test_server()->GetURL(relative_url);
+
+  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+  ui_test_utils::NavigateToURL(browser(), url);
+  CheckUnauthenticatedState(tab, AuthState::NONE);
+
+  content::TestNavigationObserver observer(tab, 1);
+  chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
+  observer.Wait();
+
+  CheckAuthenticatedState(tab, AuthState::NONE);
+}
+
+// Check that SSL state isn't stale when navigating to an existing page that
+// gives a different response. This covers the case of going from https to
+// http URL. http://crbug.com/792221
+IN_PROC_BROWSER_TEST_F(SSLUITest, ExistingPageHTTPSToHTTPSSLState) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  int count = 0;
+  std::string relative_url = "/foo";
+  GURL redirect_url = embedded_test_server()->GetURL("/simple.html");
+  https_server_.RegisterRequestHandler(
+      base::BindRepeating(ChangingHandler, &count, relative_url, redirect_url));
+  ASSERT_TRUE(https_server_.Start());
+  const GURL url = https_server_.GetURL(relative_url);
+
+  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+  ui_test_utils::NavigateToURL(browser(), url);
+  CheckAuthenticatedState(tab, AuthState::NONE);
+
+  content::TestNavigationObserver observer(tab, 1);
+  chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
+  observer.Wait();
+
+  CheckUnauthenticatedState(tab, AuthState::NONE);
+
+  // We also manually check the cert on the NavigationEntry, since in the case
+  // of http URLs GetSecurityLevelForRequest will return SecurityLevel::NONE for
+  // http URLs.
+  NavigationEntry* entry = tab->GetController().GetVisibleEntry();
+  ASSERT_FALSE(!!entry->GetSSL().certificate);
+}
+
 // Checks that a restore followed immediately by a history navigation doesn't
 // lose SSL state.
 // Disabled since this is a test for bug 738177.
diff --git a/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc b/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc
index 2f241f9..717712f 100644
--- a/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc
+++ b/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc
@@ -133,8 +133,7 @@
                << "Asynchronous MockHandleSSLError: " << async_);
 
   content::NavigationThrottle::ThrottleCheckResult result =
-      handle_->CallWillFailRequestForTesting(
-          base::nullopt, false /* should_ssl_errors_be_fatal */);
+      handle_->CallWillFailRequestForTesting(base::nullopt);
 
   EXPECT_FALSE(handle_->GetSSLInfo().is_valid());
   EXPECT_EQ(content::NavigationThrottle::PROCEED, result);
@@ -151,8 +150,7 @@
   net::SSLInfo ssl_info;
   ssl_info.cert_status = net::CERT_STATUS_IS_EV;
   content::NavigationThrottle::ThrottleCheckResult result =
-      handle_->CallWillFailRequestForTesting(
-          ssl_info, false /* should_ssl_errors_be_fatal */);
+      handle_->CallWillFailRequestForTesting(ssl_info);
 
   EXPECT_EQ(net::CERT_STATUS_IS_EV, handle_->GetSSLInfo().cert_status);
   EXPECT_EQ(content::NavigationThrottle::PROCEED, result);
@@ -171,8 +169,7 @@
       net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
   ssl_info.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
   content::NavigationThrottle::ThrottleCheckResult synchronous_result =
-      handle_->CallWillFailRequestForTesting(
-          ssl_info, false /* should_ssl_errors_be_fatal */);
+      handle_->CallWillFailRequestForTesting(ssl_info);
 
   EXPECT_EQ(content::NavigationThrottle::DEFER, synchronous_result.action());
   base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/sync/test/integration/sync_arc_package_helper.cc b/chrome/browser/sync/test/integration/sync_arc_package_helper.cc
index 4bce447..667cb1e 100644
--- a/chrome/browser/sync/test/integration/sync_arc_package_helper.cc
+++ b/chrome/browser/sync/test/integration/sync_arc_package_helper.cc
@@ -128,7 +128,6 @@
   instance_map_[profile] =
       std::make_unique<FakeAppInstance>(arc_app_list_prefs);
   DCHECK(instance_map_[profile].get());
-  arc_app_list_prefs->app_connection_holder()->SetInstance(nullptr);
   arc_app_list_prefs->app_connection_holder()->SetInstance(
       instance_map_[profile].get());
   WaitForInstanceReady(arc_app_list_prefs->app_connection_holder());
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc
index b0e1087..ca9270cd 100644
--- a/chrome/browser/task_manager/task_manager_browsertest.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -1324,29 +1324,38 @@
   // random e.g. zygote or gpu activity).
   index = FindResourceIndex(MatchTab("Cross-site iframe factory"));
 
-  // Tab 2's rows should immediately follow tab 1.
-  int tab2_start = index + static_cast<int>(subframe_offsets.size()) + 1;
-  int tab2_count = ShouldExpectSubframes() ? 4 : 1;
-  ASSERT_LE(tab2_start + tab2_count, model()->GetRowCount());
-
+  // All of Tab 2's subframes will reuse Tab 1's existing processes for
+  // corresponding sites.  Tab 2's d.com main frame row should then appear
+  // after all the subframe processes.
+  int tab2_subframe_count = ShouldExpectSubframes() ? 3 : 0;
+  int tab2_main_frame_index = index +
+                              static_cast<int>(subframe_offsets.size()) +
+                              tab2_subframe_count + 1;
   EXPECT_EQ("Tab: Cross-site iframe factory",
-            base::UTF16ToUTF8(model()->GetRowTitle(tab2_start)));
-  if (ShouldExpectSubframes()) {
-    // The relative ordering of tab1's subframe rows shall be the same as what
-    // was observed previously.
-    ASSERT_EQ(subframe_offsets[0],
-              FindResourceIndex(MatchSubframe("http://b.com/")) - index);
-    ASSERT_EQ(subframe_offsets[1],
-              FindResourceIndex(MatchSubframe("http://c.com/")) - index);
-    ASSERT_EQ(subframe_offsets[2],
-              FindResourceIndex(MatchSubframe("http://d.com/")) - index);
+            base::UTF16ToUTF8(model()->GetRowTitle(tab2_main_frame_index)));
 
-    // Because the subframes for tab 2 are nested, their order is deterministic.
-    EXPECT_EQ("Subframe: http://a.com/",
-              base::UTF16ToUTF8(model()->GetRowTitle(tab2_start + 1)));
-    EXPECT_EQ("Subframe: http://c.com/",
-              base::UTF16ToUTF8(model()->GetRowTitle(tab2_start + 2)));
+  if (ShouldExpectSubframes()) {
+    // Tab 2's a.com subframe should share Tab 1's main frame process and go
+    // directly below it.
+    EXPECT_EQ(index + 1, FindResourceIndex(MatchSubframe("http://a.com/")));
+
+    // The other tab 2 subframes (b.com and c.com) should join existing
+    // subframe processes from tab 1.  Check that the b.com and c.com subframe
+    // processes now have two rows each.
+    int subframe_b_index = FindResourceIndex(MatchSubframe("http://b.com/"));
+    int subframe_c_index = FindResourceIndex(MatchSubframe("http://c.com/"));
+    int subframe_d_index = FindResourceIndex(MatchSubframe("http://d.com/"));
     EXPECT_EQ("Subframe: http://b.com/",
-              base::UTF16ToUTF8(model()->GetRowTitle(tab2_start + 3)));
+              base::UTF16ToUTF8(model()->GetRowTitle(subframe_b_index + 1)));
+    EXPECT_EQ("Subframe: http://c.com/",
+              base::UTF16ToUTF8(model()->GetRowTitle(subframe_c_index + 1)));
+
+    // The subframe processes should preserve their relative ordering.
+    EXPECT_EQ(subframe_offsets[0] < subframe_offsets[1],
+              subframe_b_index < subframe_c_index);
+    EXPECT_EQ(subframe_offsets[1] < subframe_offsets[2],
+              subframe_c_index < subframe_d_index);
+    EXPECT_EQ(subframe_offsets[0] < subframe_offsets[2],
+              subframe_b_index < subframe_d_index);
   }
 }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 3d5dcc9..509d392a 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3653,7 +3653,7 @@
   }
 
   if (use_gio) {
-    deps += [ "//build/linux/libgio" ]
+    configs += [ "//build/linux:gio_config" ]
   }
 
   if (use_nss_certs) {
diff --git a/chrome/browser/ui/OWNERS b/chrome/browser/ui/OWNERS
index e193841..381f4ea 100644
--- a/chrome/browser/ui/OWNERS
+++ b/chrome/browser/ui/OWNERS
@@ -16,4 +16,8 @@
 # Instant/Search files.
 per-file browser_instant_controller*=file://chrome/browser/search/OWNERS
 
+# Signin and avatars.
+per-file avatar_*=file://components/signin/OWNERS
+per-file signin_*=file://components/signin/OWNERS
+
 # COMPONENT: UI>Browser
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc
index 2917de0a..40fc64ba 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_test.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -200,12 +200,13 @@
 }
 
 void ArcAppTest::StopArcInstance() {
-  arc_service_manager_->arc_bridge_service()->app()->SetInstance(nullptr);
+  arc_service_manager_->arc_bridge_service()->app()->CloseInstance(
+      app_instance_.get());
 }
 
 void ArcAppTest::RestartArcInstance() {
   auto* bridge_service = arc_service_manager_->arc_bridge_service();
-  bridge_service->app()->SetInstance(nullptr);
+  bridge_service->app()->CloseInstance(app_instance_.get());
   app_instance_ = base::MakeUnique<arc::FakeAppInstance>(arc_app_list_pref_);
   bridge_service->app()->SetInstance(app_instance_.get());
   WaitForInstanceReady(bridge_service->app());
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.cc
index 58d53904..1ef9e995 100644
--- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.cc
+++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.cc
@@ -9,6 +9,10 @@
 #include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/pref_names.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
 #include "components/safe_browsing/db/util.h"
 #include "components/safe_browsing/db/v4_protocol_manager_util.h"
 #include "content/public/browser/navigation_handle.h"
@@ -45,10 +49,17 @@
 }
 
 // static
+void SafeBrowsingTriggeredPopupBlocker::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterBooleanPref(prefs::kAbusiveExperienceInterventionEnforce,
+                                true /* default_value */);
+}
+
+// static
 std::unique_ptr<SafeBrowsingTriggeredPopupBlocker>
 SafeBrowsingTriggeredPopupBlocker::MaybeCreate(
     content::WebContents* web_contents) {
-  if (!base::FeatureList::IsEnabled(kAbusiveExperienceEnforce))
+  if (!IsEnabled(web_contents))
     return nullptr;
 
   auto* observer_manager =
@@ -74,7 +85,7 @@
     should_block = open_url_params->triggering_event_info ==
                    blink::WebTriggeringEventInfo::kFromUntrustedEvent;
   }
-  if (!base::FeatureList::IsEnabled(kAbusiveExperienceEnforce))
+  if (!IsEnabled(web_contents()))
     return false;
 
   if (should_block) {
@@ -157,3 +168,18 @@
 void SafeBrowsingTriggeredPopupBlocker::OnSubresourceFilterGoingAway() {
   scoped_observer_.RemoveAll();
 }
+
+bool SafeBrowsingTriggeredPopupBlocker::IsEnabled(
+    const content::WebContents* web_contents) {
+  // If feature is disabled, return false. This is done so that if the feature
+  // is broken it can be disabled irrespective of the policy.
+  if (!base::FeatureList::IsEnabled(kAbusiveExperienceEnforce))
+    return false;
+
+  // If enterprise policy is not set, this will return true which is the default
+  // preference value.
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+  return profile->GetPrefs()->GetBoolean(
+      prefs::kAbusiveExperienceInterventionEnforce);
+}
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h
index cd4d4c5..8d4b65a 100644
--- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h
+++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h
@@ -21,6 +21,9 @@
 class WebContents;
 }  // namespace content
 
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
 
 extern const base::Feature kAbusiveExperienceEnforce;
 
@@ -66,6 +69,8 @@
     kCount
   };
 
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
   static std::unique_ptr<SafeBrowsingTriggeredPopupBlocker> MaybeCreate(
       content::WebContents* web_contents);
   ~SafeBrowsingTriggeredPopupBlocker() override;
@@ -91,6 +96,10 @@
       const safe_browsing::ThreatMetadata& threat_metadata) override;
   void OnSubresourceFilterGoingAway() override;
 
+  // Enabled state is governed by both a feature flag and a pref (which can be
+  // controlled by enterprise policy).
+  static bool IsEnabled(const content::WebContents* web_contents);
+
   // Data scoped to a single page. Will be reset at navigation commit.
   class PageData {
    public:
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
index 2a52506..78803aa 100644
--- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
@@ -17,16 +17,24 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_database_helper.h"
 #include "chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings_types.h"
+#include "components/policy/core/browser/browser_policy_connector.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/core/common/policy_types.h"
+#include "components/policy/policy_constants.h"
+#include "components/prefs/pref_service.h"
 #include "components/safe_browsing/db/safebrowsing.pb.h"
 #include "components/safe_browsing/db/v4_embedded_test_server_util.h"
 #include "components/safe_browsing/db/v4_test_util.h"
@@ -123,8 +131,12 @@
 
   void SetUp() override {
     database_helper_ = CreateTestDatabase();
+    EXPECT_CALL(provider_, IsInitializationComplete(testing::_))
+        .WillRepeatedly(testing::Return(true));
+    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
     InProcessBrowserTest::SetUp();
   }
+
   void SetUpOnMainThread() override {
     base::FilePath test_data_dir;
     PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
@@ -170,10 +182,16 @@
     return database_helper_.get();
   }
 
+  void UpdatePolicy(const policy::PolicyMap& policy) {
+    provider_.UpdateChromePolicy(policy);
+    base::RunLoop().RunUntilIdle();
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<TestSafeBrowsingDatabaseHelper> database_helper_;
   std::unique_ptr<SafeBrowsingTriggeredPopupBlocker> popup_blocker_;
+  policy::MockConfigurationPolicyProvider provider_;
 
   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTriggeredPopupBlockerBrowserTest);
 };
@@ -263,6 +281,57 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
+                       DrivenByEnterprisePolicy) {
+  // Disable Abusive experience intervention policy.
+  policy::PolicyMap policy;
+  policy.Set(policy::key::kAbusiveExperienceInterventionEnforce,
+             policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+             policy::POLICY_SOURCE_ENTERPRISE_DEFAULT,
+             std::make_unique<base::Value>(false), nullptr);
+  UpdatePolicy(policy);
+
+  const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
+  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));
+  ConfigureAsAbusive(a_url);
+
+  // Navigate to a_url, should not trigger the popup blocker.
+  ui_test_utils::NavigateToURL(browser(), a_url);
+  bool opened_window = false;
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
+                                                   &opened_window));
+  EXPECT_TRUE(opened_window);
+  EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents)
+                   ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));
+
+  // Since the policy change can take effect without browser restart, verify
+  // that enabling the policy here should disallow opening new tabs or windows
+  // from any new tab opened after the policy is set.
+  policy.Set(policy::key::kAbusiveExperienceInterventionEnforce,
+             policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+             policy::POLICY_SOURCE_ENTERPRISE_DEFAULT,
+             std::make_unique<base::Value>(true), nullptr);
+  UpdatePolicy(policy);
+
+  // Open a new tab to make sure the SafeBrowsingTriggeredPopupBlocker gets
+  // created for the new tab.
+  chrome::NewTab(browser());
+
+  // Navigate to a_url, should trigger the popup blocker.
+  ui_test_utils::NavigateToURL(browser(), a_url);
+  opened_window = false;
+  content::WebContents* web_contents1 =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+      web_contents1, "openWindow()", &opened_window));
+  EXPECT_FALSE(opened_window);
+  // Make sure the popup UI was shown.
+  EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents1)
+                  ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingTriggeredPopupBlockerBrowserTest,
                        NoFeature_NoMessages) {
   // Disable Abusive enforcement, but keep the notifications coming from the
   // SubresourceFilter.
diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm
index 916d33d..3e6f0d5e 100644
--- a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm
+++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration_browsertest.mm
@@ -17,8 +17,8 @@
 
   void SetUpOnMainThread() override {
     std::unique_ptr<ContentSettingImageModel> content_setting_image_model(
-        ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
-            CONTENT_SETTINGS_TYPE_GEOLOCATION));
+        ContentSettingImageModel::CreateForContentType(
+            ContentSettingImageModel::ImageType::GEOLOCATION));
     BrowserWindowController* controller = [BrowserWindowController
         browserWindowControllerForWindow:browser()
                                              ->window()
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
index 22922b0e..d4813fc 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -30,6 +30,7 @@
 #include "components/omnibox/browser/omnibox_edit_controller.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/browser/omnibox_popup_model.h"
+#include "components/omnibox/browser/suggestion_answer.h"
 #include "components/toolbar/toolbar_model.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/common/constants.h"
@@ -612,9 +613,13 @@
     model()->OnChanged();
   [field_ clearUndoChain];
 
+  // Get friendly accessibility label.
+  base::string16 description =
+      match.answer ? match.answer->second_line().AccessibleText()
+                   : match.description;
   AnnounceAutocompleteForScreenReader(
       AutocompleteMatchType::ToAccessibilityLabel(match.type, display_text,
-                                                  match.description));
+                                                  description));
 }
 
 bool OmniboxViewMac::OnInlineAutocompleteTextMaybeChanged(
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc
index 263442db5..dcc6be34 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -10,6 +10,7 @@
 #include "base/feature_list.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
 #include "build/build_config.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/browser_process.h"
@@ -49,7 +50,8 @@
 
 class ContentSettingBlockedImageModel : public ContentSettingSimpleImageModel {
  public:
-  explicit ContentSettingBlockedImageModel(ContentSettingsType content_type);
+  ContentSettingBlockedImageModel(ImageType image_type,
+                                  ContentSettingsType content_type);
 
   void UpdateFromWebContents(WebContents* web_contents) override;
 
@@ -106,7 +108,7 @@
 
   void UpdateFromWebContents(WebContents* web_contents) override;
 
-  ContentSettingBubbleModel* CreateBubbleModel(
+  ContentSettingBubbleModel* CreateBubbleModelImpl(
       ContentSettingBubbleModel::Delegate* delegate,
       WebContents* web_contents,
       Profile* profile) override;
@@ -121,7 +123,7 @@
 namespace {
 
 struct ContentSettingsImageDetails {
-  ContentSettingsType type;
+  ContentSettingsType content_type;
   const gfx::VectorIcon& icon;
   int blocked_tooltip_id;
   int blocked_explanatory_text_id;
@@ -146,28 +148,9 @@
     {CONTENT_SETTINGS_TYPE_SOUND, kTabAudioIcon, IDS_BLOCKED_SOUND_TITLE, 0, 0},
 };
 
-// The ordering of the models here influences the order in which icons are
-// shown in the omnibox.
-constexpr ContentSettingsType kContentTypeIconOrder[] = {
-    CONTENT_SETTINGS_TYPE_COOKIES,
-    CONTENT_SETTINGS_TYPE_IMAGES,
-    CONTENT_SETTINGS_TYPE_JAVASCRIPT,
-    CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
-    CONTENT_SETTINGS_TYPE_PLUGINS,
-    CONTENT_SETTINGS_TYPE_POPUPS,
-    CONTENT_SETTINGS_TYPE_GEOLOCATION,
-    CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
-    CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS,
-    CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,  // Note: also handles mic.
-    CONTENT_SETTINGS_TYPE_ADS,
-    CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
-    CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
-    CONTENT_SETTINGS_TYPE_SOUND,
-};
-
 const ContentSettingsImageDetails* GetImageDetails(ContentSettingsType type) {
   for (const ContentSettingsImageDetails& image_details : kImageDetails) {
-    if (image_details.type == type)
+    if (image_details.content_type == type)
       return &image_details;
   }
   return nullptr;
@@ -178,12 +161,12 @@
 // Single content setting ------------------------------------------------------
 
 ContentSettingSimpleImageModel::ContentSettingSimpleImageModel(
+    ImageType image_type,
     ContentSettingsType content_type)
-    : ContentSettingImageModel(),
-      content_type_(content_type) {
-}
+    : ContentSettingImageModel(image_type), content_type_(content_type) {}
 
-ContentSettingBubbleModel* ContentSettingSimpleImageModel::CreateBubbleModel(
+ContentSettingBubbleModel*
+ContentSettingSimpleImageModel::CreateBubbleModelImpl(
     ContentSettingBubbleModel::Delegate* delegate,
     WebContents* web_contents,
     Profile* profile) {
@@ -219,30 +202,59 @@
 
 // static
 std::unique_ptr<ContentSettingImageModel>
-ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
-    ContentSettingsType content_settings_type) {
-  if (content_settings_type == CONTENT_SETTINGS_TYPE_GEOLOCATION)
-    return base::MakeUnique<ContentSettingGeolocationImageModel>();
-
-  if (content_settings_type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS)
-    return base::MakeUnique<ContentSettingRPHImageModel>();
-
-  if (content_settings_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX)
-    return base::MakeUnique<ContentSettingMIDISysExImageModel>();
-
-  if (content_settings_type == CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS)
-    return base::MakeUnique<ContentSettingDownloadsImageModel>();
-
-  return base::MakeUnique<ContentSettingBlockedImageModel>(
-      content_settings_type);
+ContentSettingImageModel::CreateForContentType(ImageType image_type) {
+  switch (image_type) {
+    case ImageType::COOKIES:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::COOKIES, CONTENT_SETTINGS_TYPE_COOKIES);
+    case ImageType::IMAGES:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::IMAGES, CONTENT_SETTINGS_TYPE_IMAGES);
+    case ImageType::JAVASCRIPT:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::JAVASCRIPT, CONTENT_SETTINGS_TYPE_JAVASCRIPT);
+    case ImageType::PPAPI_BROKER:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::PPAPI_BROKER, CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
+    case ImageType::PLUGINS:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::PLUGINS, CONTENT_SETTINGS_TYPE_PLUGINS);
+    case ImageType::POPUPS:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::POPUPS, CONTENT_SETTINGS_TYPE_POPUPS);
+    case ImageType::GEOLOCATION:
+      return std::make_unique<ContentSettingGeolocationImageModel>();
+    case ImageType::MIXEDSCRIPT:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::MIXEDSCRIPT, CONTENT_SETTINGS_TYPE_MIXEDSCRIPT);
+    case ImageType::PROTOCOL_HANDLERS:
+      return std::make_unique<ContentSettingRPHImageModel>();
+    case ImageType::MEDIASTREAM:
+      return std::make_unique<ContentSettingMediaImageModel>();
+    case ImageType::ADS:
+      return std::make_unique<ContentSettingSubresourceFilterImageModel>();
+    case ImageType::AUTOMATIC_DOWNLOADS:
+      return std::make_unique<ContentSettingDownloadsImageModel>();
+    case ImageType::MIDI_SYSEX:
+      return std::make_unique<ContentSettingMIDISysExImageModel>();
+    case ImageType::SOUND:
+      return std::make_unique<ContentSettingBlockedImageModel>(
+          ImageType::SOUND, CONTENT_SETTINGS_TYPE_SOUND);
+    case ImageType::FRAMEBUST:
+      return std::make_unique<ContentSettingFramebustBlockImageModel>();
+    case ImageType::NUM_IMAGE_TYPES:
+      break;
+  }
+  NOTREACHED();
+  return nullptr;
 }
 
 // Generic blocked content settings --------------------------------------------
 
 ContentSettingBlockedImageModel::ContentSettingBlockedImageModel(
+    ImageType image_type,
     ContentSettingsType content_type)
-    : ContentSettingSimpleImageModel(content_type) {
-}
+    : ContentSettingSimpleImageModel(image_type, content_type) {}
 
 void ContentSettingBlockedImageModel::UpdateFromWebContents(
     WebContents* web_contents) {
@@ -311,8 +323,8 @@
 // Geolocation -----------------------------------------------------------------
 
 ContentSettingGeolocationImageModel::ContentSettingGeolocationImageModel()
-    : ContentSettingSimpleImageModel(CONTENT_SETTINGS_TYPE_GEOLOCATION) {
-}
+    : ContentSettingSimpleImageModel(ImageType::GEOLOCATION,
+                                     CONTENT_SETTINGS_TYPE_GEOLOCATION) {}
 
 void ContentSettingGeolocationImageModel::UpdateFromWebContents(
     WebContents* web_contents) {
@@ -344,7 +356,8 @@
 // Protocol handlers -----------------------------------------------------------
 
 ContentSettingRPHImageModel::ContentSettingRPHImageModel()
-    : ContentSettingSimpleImageModel(CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
+    : ContentSettingSimpleImageModel(ImageType::PROTOCOL_HANDLERS,
+                                     CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
   set_icon(vector_icons::kProtocolHandlerIcon, gfx::kNoneIcon);
   set_tooltip(l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP));
 }
@@ -368,7 +381,8 @@
 // MIDI SysEx ------------------------------------------------------------------
 
 ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel()
-    : ContentSettingSimpleImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {}
+    : ContentSettingSimpleImageModel(ImageType::MIDI_SYSEX,
+                                     CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {}
 
 void ContentSettingMIDISysExImageModel::UpdateFromWebContents(
     WebContents* web_contents) {
@@ -402,6 +416,7 @@
 
 ContentSettingDownloadsImageModel::ContentSettingDownloadsImageModel()
     : ContentSettingSimpleImageModel(
+          ImageType::AUTOMATIC_DOWNLOADS,
           CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS) {}
 
 void ContentSettingDownloadsImageModel::UpdateFromWebContents(
@@ -439,8 +454,7 @@
 // Media -----------------------------------------------------------------------
 
 ContentSettingMediaImageModel::ContentSettingMediaImageModel()
-    : ContentSettingImageModel() {
-}
+    : ContentSettingImageModel(ImageType::MEDIASTREAM) {}
 
 void ContentSettingMediaImageModel::UpdateFromWebContents(
     WebContents* web_contents) {
@@ -481,7 +495,7 @@
   set_visible(true);
 }
 
-ContentSettingBubbleModel* ContentSettingMediaImageModel::CreateBubbleModel(
+ContentSettingBubbleModel* ContentSettingMediaImageModel::CreateBubbleModelImpl(
     ContentSettingBubbleModel::Delegate* delegate,
     WebContents* web_contents,
     Profile* profile) {
@@ -522,7 +536,7 @@
 
 ContentSettingSubresourceFilterImageModel::
     ContentSettingSubresourceFilterImageModel()
-    : ContentSettingImageModel() {}
+    : ContentSettingImageModel(ImageType::ADS) {}
 
 void ContentSettingSubresourceFilterImageModel::UpdateFromWebContents(
     WebContents* web_contents) {
@@ -545,7 +559,7 @@
 }
 
 ContentSettingBubbleModel*
-ContentSettingSubresourceFilterImageModel::CreateBubbleModel(
+ContentSettingSubresourceFilterImageModel::CreateBubbleModelImpl(
     ContentSettingBubbleModel::Delegate* delegate,
     WebContents* web_contents,
     Profile* profile) {
@@ -576,7 +590,7 @@
 
 // Blocked Framebust -----------------------------------------------------------
 ContentSettingFramebustBlockImageModel::ContentSettingFramebustBlockImageModel()
-    : ContentSettingImageModel() {}
+    : ContentSettingImageModel(ImageType::FRAMEBUST) {}
 
 void ContentSettingFramebustBlockImageModel::UpdateFromWebContents(
     WebContents* web_contents) {
@@ -596,7 +610,7 @@
 }
 
 ContentSettingBubbleModel*
-ContentSettingFramebustBlockImageModel::CreateBubbleModel(
+ContentSettingFramebustBlockImageModel::CreateBubbleModelImpl(
     ContentSettingBubbleModel::Delegate* delegate,
     WebContents* web_contents,
     Profile* profile) {
@@ -625,65 +639,64 @@
       gfx::CreateVectorIconWithBadge(*icon_, 16, icon_color, *icon_badge_));
 }
 
-ContentSettingImageModel::ContentSettingImageModel()
+ContentSettingImageModel::ContentSettingImageModel(ImageType image_type)
     : is_visible_(false),
       icon_(&gfx::kNoneIcon),
       icon_badge_(&gfx::kNoneIcon),
-      explanatory_string_id_(0) {}
+      explanatory_string_id_(0),
+      image_type_(image_type) {}
+
+ContentSettingBubbleModel* ContentSettingImageModel::CreateBubbleModel(
+    ContentSettingBubbleModel::Delegate* delegate,
+    content::WebContents* web_contents,
+    Profile* profile) {
+  UMA_HISTOGRAM_ENUMERATION(
+      "ContentSettings.ImagePressed", image_type(),
+      ContentSettingImageModel::ImageType::NUM_IMAGE_TYPES);
+  return CreateBubbleModelImpl(delegate, web_contents, profile);
+}
 
 // static
 std::vector<std::unique_ptr<ContentSettingImageModel>>
 ContentSettingImageModel::GenerateContentSettingImageModels() {
+  // The ordering of the models here influences the order in which icons are
+  // shown in the omnibox.
+  constexpr ImageType kContentSettingImageOrder[] = {
+      ImageType::COOKIES,
+      ImageType::IMAGES,
+      ImageType::JAVASCRIPT,
+      ImageType::PPAPI_BROKER,
+      ImageType::PLUGINS,
+      ImageType::POPUPS,
+      ImageType::GEOLOCATION,
+      ImageType::MIXEDSCRIPT,
+      ImageType::PROTOCOL_HANDLERS,
+      ImageType::MEDIASTREAM,
+      ImageType::ADS,
+      ImageType::AUTOMATIC_DOWNLOADS,
+      ImageType::MIDI_SYSEX,
+      ImageType::SOUND,
+      ImageType::FRAMEBUST,
+  };
+
   std::vector<std::unique_ptr<ContentSettingImageModel>> result;
-  std::unique_ptr<ContentSettingImageModel> model;
-
-  for (auto icon : kContentTypeIconOrder) {
-    switch (icon) {
-      case CONTENT_SETTINGS_TYPE_GEOLOCATION:
-        model = base::MakeUnique<ContentSettingGeolocationImageModel>();
-        break;
-      case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
-        model = base::MakeUnique<ContentSettingRPHImageModel>();
-        break;
-      case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
-        model = base::MakeUnique<ContentSettingMediaImageModel>();
-        break;
-      case CONTENT_SETTINGS_TYPE_ADS:
-        model = base::MakeUnique<ContentSettingSubresourceFilterImageModel>();
-        break;
-      case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
-        model = base::MakeUnique<ContentSettingMIDISysExImageModel>();
-        break;
-      case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
-        model = base::MakeUnique<ContentSettingDownloadsImageModel>();
-        break;
-      default:
-        // All other content settings types use ContentSettingBlockedImageModel.
-        model = base::MakeUnique<ContentSettingBlockedImageModel>(icon);
-        break;
-    }
-    result.push_back(std::move(model));
-  }
-
-  // The framebust blocking UI reuses the code for displaying an icon with
-  // ContentSettingImageModel and ContentSettingBubbleModel, even though
-  // framebust blocking is not a content setting.
-  result.push_back(base::MakeUnique<ContentSettingFramebustBlockImageModel>());
+  for (auto type : kContentSettingImageOrder)
+    result.push_back(CreateForContentType(type));
 
   return result;
 }
 
 // static
 size_t ContentSettingImageModel::GetContentSettingImageModelIndexForTesting(
-    ContentSettingsType content_type) {
-  if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)
-    content_type = CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA;
-  for (size_t i = 0; i < arraysize(kContentTypeIconOrder); ++i) {
-    if (content_type == kContentTypeIconOrder[i])
+    ImageType image_type) {
+  std::vector<std::unique_ptr<ContentSettingImageModel>> models =
+      GenerateContentSettingImageModels();
+  for (size_t i = 0; i < models.size(); ++i) {
+    if (image_type == models[i]->image_type())
       return i;
   }
   NOTREACHED();
-  return arraysize(kContentTypeIconOrder);
+  return models.size();
 }
 
 #if defined(OS_MACOSX)
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.h b/chrome/browser/ui/content_settings/content_setting_image_model.h
index 93371c7e0..8379987f 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model.h
+++ b/chrome/browser/ui/content_settings/content_setting_image_model.h
@@ -28,6 +28,28 @@
 // that are displayed in the location bar.
 class ContentSettingImageModel {
  public:
+  // The type of the content setting image model. This enum is used in
+  // histograms and thus is append-only.
+  enum class ImageType {
+    COOKIES = 0,
+    IMAGES = 1,
+    JAVASCRIPT = 2,
+    PPAPI_BROKER = 3,
+    PLUGINS = 4,
+    POPUPS = 5,
+    GEOLOCATION = 6,
+    MIXEDSCRIPT = 7,
+    PROTOCOL_HANDLERS = 8,
+    MEDIASTREAM = 9,
+    ADS = 10,
+    AUTOMATIC_DOWNLOADS = 11,
+    MIDI_SYSEX = 12,
+    SOUND = 13,
+    FRAMEBUST = 14,
+
+    NUM_IMAGE_TYPES
+  };
+
   virtual ~ContentSettingImageModel() {}
 
   // Generates a vector of all image models to be used within one window.
@@ -37,7 +59,11 @@
   // Returns the corresponding index into the above vector for the given
   // ContentSettingsType. For testing.
   static size_t GetContentSettingImageModelIndexForTesting(
-      ContentSettingsType content_type);
+      ImageType image_type);
+
+  // Factory method.
+  static std::unique_ptr<ContentSettingImageModel> CreateForContentType(
+      ImageType image_type);
 
   // Notifies this model that its setting might have changed and it may need to
   // update its visibility, icon and tooltip.
@@ -45,10 +71,10 @@
 
   // Creates the model for the bubble that will be attached to this image.
   // The bubble model is owned by the caller.
-  virtual ContentSettingBubbleModel* CreateBubbleModel(
+  ContentSettingBubbleModel* CreateBubbleModel(
       ContentSettingBubbleModel::Delegate* delegate,
       content::WebContents* web_contents,
-      Profile* profile) = 0;
+      Profile* profile);
 
   // Whether the animation should be run for the given |web_contents|.
   virtual bool ShouldRunAnimation(content::WebContents* web_contents) = 0;
@@ -72,8 +98,16 @@
   int explanatory_string_id() const { return explanatory_string_id_; }
   const base::string16& get_tooltip() const { return tooltip_; }
 
+  ImageType image_type() const { return image_type_; }
+
  protected:
-  ContentSettingImageModel();
+  explicit ContentSettingImageModel(ImageType type);
+
+  // Internal implementation by subclasses of bubble model creation.
+  virtual ContentSettingBubbleModel* CreateBubbleModelImpl(
+      ContentSettingBubbleModel::Delegate* delegate,
+      content::WebContents* web_contents,
+      Profile* profile) = 0;
 
   void set_icon(const gfx::VectorIcon& icon, const gfx::VectorIcon& badge) {
     icon_ = &icon;
@@ -93,6 +127,7 @@
   const gfx::VectorIcon* icon_badge_;
   int explanatory_string_id_;
   base::string16 tooltip_;
+  const ImageType image_type_;
 
   DISALLOW_COPY_AND_ASSIGN(ContentSettingImageModel);
 };
@@ -100,21 +135,17 @@
 // A subclass for an image model tied to a single content type.
 class ContentSettingSimpleImageModel : public ContentSettingImageModel {
  public:
-  explicit ContentSettingSimpleImageModel(ContentSettingsType content_type);
+  ContentSettingSimpleImageModel(ImageType type,
+                                 ContentSettingsType content_type);
 
   // ContentSettingImageModel implementation.
-  ContentSettingBubbleModel* CreateBubbleModel(
+  ContentSettingBubbleModel* CreateBubbleModelImpl(
       ContentSettingBubbleModel::Delegate* delegate,
       content::WebContents* web_contents,
       Profile* profile) override;
   bool ShouldRunAnimation(content::WebContents* web_contents) override;
   void SetAnimationHasRun(content::WebContents* web_contents) override;
 
-  // Factory method. Used only for testing.
-  static std::unique_ptr<ContentSettingImageModel>
-  CreateForContentTypeForTesting(ContentSettingsType content_type);
-
- protected:
   ContentSettingsType content_type() { return content_type_; }
 
  private:
@@ -131,7 +162,7 @@
 
   void UpdateFromWebContents(content::WebContents* web_contents) override;
 
-  ContentSettingBubbleModel* CreateBubbleModel(
+  ContentSettingBubbleModel* CreateBubbleModelImpl(
       ContentSettingBubbleModel::Delegate* delegate,
       content::WebContents* web_contents,
       Profile* profile) override;
@@ -149,7 +180,7 @@
 
   void UpdateFromWebContents(content::WebContents* web_contents) override;
 
-  ContentSettingBubbleModel* CreateBubbleModel(
+  ContentSettingBubbleModel* CreateBubbleModelImpl(
       ContentSettingBubbleModel::Delegate* delegate,
       content::WebContents* web_contents,
       Profile* profile) override;
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc
index 7c00807..4d8e4a23 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc
@@ -13,6 +13,7 @@
 #include "chrome/test/base/in_process_browser_test.h"
 
 using content::WebContents;
+using ImageType = ContentSettingImageModel::ImageType;
 
 typedef InProcessBrowserTest ContentSettingImageModelBrowserTest;
 
@@ -34,24 +35,25 @@
 
   // Test that image models tied to a single content setting create bubbles tied
   // to the same setting.
-  static const ContentSettingsType content_settings_to_test[] = {
-      CONTENT_SETTINGS_TYPE_COOKIES,
-      CONTENT_SETTINGS_TYPE_IMAGES,
-      CONTENT_SETTINGS_TYPE_JAVASCRIPT,
-      CONTENT_SETTINGS_TYPE_PLUGINS,
-      CONTENT_SETTINGS_TYPE_POPUPS,
-      CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
-      CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
-      CONTENT_SETTINGS_TYPE_GEOLOCATION,
-      CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS,
-      CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
-  };
+  static constexpr ContentSettingImageModel::ImageType
+      content_settings_to_test[] = {
+          ImageType::COOKIES,
+          ImageType::IMAGES,
+          ImageType::JAVASCRIPT,
+          ImageType::PLUGINS,
+          ImageType::POPUPS,
+          ImageType::MIXEDSCRIPT,
+          ImageType::PPAPI_BROKER,
+          ImageType::GEOLOCATION,
+          ImageType::PROTOCOL_HANDLERS,
+          ImageType::MIDI_SYSEX,
+      };
 
   Profile* profile = browser()->profile();
-  for (ContentSettingsType type : content_settings_to_test) {
+  for (auto type : content_settings_to_test) {
+    auto model = ContentSettingImageModel::CreateForContentType(type);
     std::unique_ptr<ContentSettingBubbleModel> bubble(
-        ContentSettingSimpleImageModel::CreateForContentTypeForTesting(type)
-            ->CreateBubbleModel(nullptr, web_contents, profile));
+        model->CreateBubbleModel(nullptr, web_contents, profile));
 
     // All of the above content settings should create a
     // ContentSettingSimpleBubbleModel that is tied to a particular setting,
@@ -59,16 +61,22 @@
     ContentSettingSimpleBubbleModel* simple_bubble =
         bubble->AsSimpleBubbleModel();
     ASSERT_TRUE(simple_bubble);
-    EXPECT_EQ(type, simple_bubble->content_type());
+    EXPECT_EQ(static_cast<ContentSettingSimpleImageModel*>(model.get())
+                  ->content_type(),
+              simple_bubble->content_type());
+    EXPECT_EQ(type, model->image_type());
   }
 
-  // For other models, we can only test that they create a valid bubble.
+  // For other models, we can only test that they create a valid bubble, and
+  // that all the image types are unique.
+  std::set<ImageType> image_types;
   std::vector<std::unique_ptr<ContentSettingImageModel>> models =
       ContentSettingImageModel::GenerateContentSettingImageModels();
   for (auto& model : models) {
     EXPECT_TRUE(base::WrapUnique(
                     model->CreateBubbleModel(nullptr, web_contents, profile))
                     .get());
+    EXPECT_TRUE(image_types.insert(model->image_type()).second);
   }
 }
 
@@ -79,9 +87,8 @@
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
-  std::unique_ptr<ContentSettingImageModel> model =
-      ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
-          CONTENT_SETTINGS_TYPE_IMAGES);
+  auto model =
+      ContentSettingImageModel::CreateForContentType(ImageType::IMAGES);
 
   EXPECT_TRUE(model->ShouldRunAnimation(web_contents));
   model->SetAnimationHasRun(web_contents);
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
index 01579af..e02ae73c 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
@@ -66,9 +66,9 @@
   TabSpecificContentSettings::CreateForWebContents(web_contents());
   TabSpecificContentSettings* content_settings =
       TabSpecificContentSettings::FromWebContents(web_contents());
-  std::unique_ptr<ContentSettingImageModel> content_setting_image_model =
-      ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
-          CONTENT_SETTINGS_TYPE_IMAGES);
+  auto content_setting_image_model =
+      ContentSettingImageModel::CreateForContentType(
+          ContentSettingImageModel::ImageType::IMAGES);
   EXPECT_FALSE(content_setting_image_model->is_visible());
   EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
 
@@ -82,9 +82,9 @@
 
 TEST_F(ContentSettingImageModelTest, RPHUpdateFromWebContents) {
   TabSpecificContentSettings::CreateForWebContents(web_contents());
-  std::unique_ptr<ContentSettingImageModel> content_setting_image_model =
-      ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
-          CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS);
+  auto content_setting_image_model =
+      ContentSettingImageModel::CreateForContentType(
+          ContentSettingImageModel::ImageType::PROTOCOL_HANDLERS);
   content_setting_image_model->UpdateFromWebContents(web_contents());
   EXPECT_FALSE(content_setting_image_model->is_visible());
 
@@ -104,9 +104,9 @@
   HostContentSettingsMapFactory::GetForProfile(profile())
       ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                  CONTENT_SETTING_BLOCK);
-  std::unique_ptr<ContentSettingImageModel> content_setting_image_model(
-      ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
-          CONTENT_SETTINGS_TYPE_COOKIES));
+  auto content_setting_image_model =
+      ContentSettingImageModel::CreateForContentType(
+          ContentSettingImageModel::ImageType::COOKIES);
   EXPECT_FALSE(content_setting_image_model->is_visible());
   EXPECT_TRUE(content_setting_image_model->get_tooltip().empty());
 
@@ -124,9 +124,9 @@
 
 // Regression test for http://crbug.com/161854.
 TEST_F(ContentSettingImageModelTest, NULLTabSpecificContentSettings) {
-  std::unique_ptr<ContentSettingImageModel> content_setting_image_model =
-      ContentSettingSimpleImageModel::CreateForContentTypeForTesting(
-          CONTENT_SETTINGS_TYPE_IMAGES);
+  auto content_setting_image_model =
+      ContentSettingImageModel::CreateForContentType(
+          ContentSettingImageModel::ImageType::IMAGES);
   NotificationForwarder forwarder(content_setting_image_model.get());
   // Should not crash.
   TabSpecificContentSettings::CreateForWebContents(web_contents());
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc
index dc93e19..997225c 100644
--- a/chrome/browser/ui/hung_plugin_tab_helper.cc
+++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/common/channel_info.h"
-#include "chrome/common/crash_keys.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/infobars/core/confirm_infobar_delegate.h"
 #include "components/infobars/core/infobar.h"
@@ -50,8 +49,7 @@
     const content::ChildProcessData& data = iter.GetData();
     if (data.id == child_id) {
 #if defined(OS_WIN)
-      base::StringPairs crash_keys = {
-          {crash_keys::kHungRendererReason, "plugin"}};
+      base::StringPairs crash_keys = {{"hung-reason", "plugin"}};
       CrashDumpAndTerminateHungChildProcess(data.handle, crash_keys);
 #else
       base::Process process =
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index 15da7df..930e24e 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -1208,13 +1208,7 @@
   ASSERT_TRUE(omnibox_view->GetText().empty());
 }
 
-#if defined(OS_WIN)
-#define MAYBE_NonSubstitutingKeywordTest NonSubstitutingKeywordTest
-#else
-// https://crbug.com/751031.
-#define MAYBE_NonSubstitutingKeywordTest DISABLED_NonSubstitutingKeywordTest
-#endif
-IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_NonSubstitutingKeywordTest) {
+IN_PROC_BROWSER_TEST_F(OmniboxViewTest, DISABLED_NonSubstitutingKeywordTest) {
   OmniboxView* omnibox_view = NULL;
   ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
   OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
index 72cd17a..49a8f55 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -46,6 +46,8 @@
 
 namespace {
 
+constexpr ukm::SourceId kTestSourceId = 0x1234;
+
 constexpr char kSignInPromoCountTilNoThanksMetric[] =
     "PasswordManager.SignInPromoCountTilNoThanks";
 constexpr char kSignInPromoCountTilSignInMetric[] =
@@ -535,9 +537,7 @@
           // Setup metrics recorder
           auto recorder = base::MakeRefCounted<
               password_manager::PasswordFormMetricsRecorder>(
-              true /*is_main_frame_secure*/, &test_ukm_recorder,
-              test_ukm_recorder.GetNewSourceID(),
-              GURL("https://www.example.com/"));
+              true /*is_main_frame_secure*/, kTestSourceId);
 
           // Exercise bubble.
           ON_CALL(*controller(), GetPasswordFormMetricsRecorder())
@@ -601,8 +601,7 @@
             test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
         EXPECT_EQ(1u, entries.size());
         for (const auto* entry : entries) {
-          test_ukm_recorder.ExpectEntrySourceHasUrl(
-              entry, GURL("https://www.example.com/"));
+          EXPECT_EQ(kTestSourceId, entry->source_id);
           test_ukm_recorder.ExpectEntryMetric(
               entry,
               update ? UkmEntry::kUpdating_Prompt_ShownName
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 72a7fe5..a9d24fe 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -457,8 +457,7 @@
     ukm::SourceId source_id = test_ukm_recorder.GetNewSourceID();
     auto recorder =
         base::MakeRefCounted<password_manager::PasswordFormMetricsRecorder>(
-            true /*is_main_frame_secure*/, &test_ukm_recorder, source_id,
-            GURL("http://www.example.com/"));
+            true /*is_main_frame_secure*/, source_id);
 
     // Exercise controller.
     std::unique_ptr<password_manager::PasswordFormManager> test_form_manager(
@@ -496,8 +495,7 @@
         test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
     EXPECT_EQ(1u, entries.size());
     for (const auto* entry : entries) {
-      test_ukm_recorder.ExpectEntrySourceHasUrl(
-          entry, GURL("http://www.example.com/"));
+      EXPECT_EQ(source_id, entry->source_id);
 
       if (test.edit_username) {
         test_ukm_recorder.ExpectEntryMetric(
@@ -938,8 +936,7 @@
     ukm::SourceId source_id = test_ukm_recorder.GetNewSourceID();
     auto recorder =
         base::MakeRefCounted<password_manager::PasswordFormMetricsRecorder>(
-            true /*is_main_frame_secure*/, &test_ukm_recorder, source_id,
-            GURL("http://www.example.com/"));
+            true /*is_main_frame_secure*/, source_id);
     std::unique_ptr<password_manager::PasswordFormManager> test_form_manager(
         CreateFormManagerWithMetricsRecorder(recorder));
 
@@ -981,8 +978,7 @@
         test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
     ASSERT_EQ(1u, entries.size());
     auto* entry = entries[0];
-    test_ukm_recorder.ExpectEntrySourceHasUrl(entry,
-                                              GURL("http://www.example.com/"));
+    EXPECT_EQ(source_id, entry->source_id);
 
     if (is_update) {
       histogram_tester.ExpectUniqueSample(
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc
index 5126b926..a3d5927 100644
--- a/chrome/browser/ui/search/local_ntp_browsertest.cc
+++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -7,6 +7,7 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/files/scoped_temp_dir.h"
 #include "base/i18n/base_i18n_switches.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/statistics_recorder.h"
@@ -14,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/instant_service.h"
@@ -25,11 +27,13 @@
 #include "chrome/browser/ui/search/instant_test_utils.h"
 #include "chrome/browser/ui/search/local_ntp_test_utils.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/common/search/instant_types.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/interstitial_page.h"
 #include "content/public/browser/interstitial_page_delegate.h"
@@ -251,6 +255,14 @@
 
 // Regression test for crbug.com/592273.
 IN_PROC_BROWSER_TEST_F(LocalNTPTest, EmbeddedSearchAPIAfterDownload) {
+  // Set up a temporary directory for downloads, so that we don't leak the
+  // downloaded file.
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  base::ScopedTempDir downloads_dir;
+  ASSERT_TRUE(downloads_dir.CreateUniqueTempDir());
+  browser()->profile()->GetPrefs()->SetFilePath(
+      prefs::kDownloadDefaultDirectory, downloads_dir.GetPath());
+
   // Set up a test server, so we have some URL to download.
   net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
   test_server.ServeFilesFromSourceDirectory("chrome/test/data");
diff --git a/chrome/browser/ui/search/local_ntp_test_utils.cc b/chrome/browser/ui/search/local_ntp_test_utils.cc
index a0b5503..7288628 100644
--- a/chrome/browser/ui/search/local_ntp_test_utils.cc
+++ b/chrome/browser/ui/search/local_ntp_test_utils.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
+#include "chrome/test/base/search_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/prefs/pref_service.h"
 #include "components/search_engines/template_url.h"
@@ -119,6 +120,7 @@
 
   TemplateURLService* template_url_service =
       TemplateURLServiceFactory::GetForProfile(profile);
+  search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
   TemplateURL* template_url =
       template_url_service->Add(std::make_unique<TemplateURL>(data));
   template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
diff --git a/chrome/browser/ui/signin_view_controller.cc b/chrome/browser/ui/signin_view_controller.cc
index 0e1f4e77..83a94507 100644
--- a/chrome/browser/ui/signin_view_controller.cc
+++ b/chrome/browser/ui/signin_view_controller.cc
@@ -154,8 +154,7 @@
   DCHECK_EQ(signin_url, active_contents->GetVisibleURL());
   DiceTabHelper::CreateForWebContents(active_contents);
   DiceTabHelper* tab_helper = DiceTabHelper::FromWebContents(active_contents);
-  tab_helper->SetSigninAccessPoint(access_point);
-  tab_helper->SetSigninReason(signin_reason);
+  tab_helper->InitializeSigninFlow(access_point, signin_reason);
 
   if (signin_reason == signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT) {
     signin_metrics::LogSigninAccessPointStarted(access_point);
diff --git a/chrome/browser/ui/tabs/tab_activity_watcher_unittest.cc b/chrome/browser/ui/tabs/tab_activity_watcher_unittest.cc
index a85017e..4d2132a5 100644
--- a/chrome/browser/ui/tabs/tab_activity_watcher_unittest.cc
+++ b/chrome/browser/ui/tabs/tab_activity_watcher_unittest.cc
@@ -7,7 +7,9 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_activity_watcher.h"
 #include "chrome/browser/ui/tabs/tab_metrics_event.pb.h"
@@ -50,7 +52,10 @@
 const UkmMetricMap kBasicMetricValues({
     {TabManager_TabMetrics::kContentTypeName,
      TabMetricsEvent::CONTENT_TYPE_TEXT_HTML},
+    // TODO(michaelpg): Test HasBeforeUnloadHandler in a browser_test.
+    {TabManager_TabMetrics::kHasBeforeUnloadHandlerName, 0},
     {TabManager_TabMetrics::kHasFormEntryName, 0},
+    {TabManager_TabMetrics::kIsExtensionProtectedName, 0},
     {TabManager_TabMetrics::kIsPinnedName, 0},
     {TabManager_TabMetrics::kKeyEventCountName, 0},
     {TabManager_TabMetrics::kMouseEventCountName, 0},
@@ -298,6 +303,11 @@
     ExpectNewEntry(kTestUrls[1], expected_metrics);
   }
 
+  // Simulate an extension protecting the tab.
+  g_browser_process->GetTabManager()->SetTabAutoDiscardableState(
+      test_contents_2, false);
+  expected_metrics[TabManager_TabMetrics::kIsExtensionProtectedName] = 1;
+
   // Site engagement score should round down to the nearest 10.
   SiteEngagementService::Get(profile())->ResetBaseScoreForURL(kTestUrls[1], 45);
   expected_metrics[TabManager_TabMetrics::kSiteEngagementScoreName] = 40;
diff --git a/chrome/browser/ui/tabs/tab_metrics_logger_impl.cc b/chrome/browser/ui/tabs/tab_metrics_logger_impl.cc
index d395ea7..20f6587 100644
--- a/chrome/browser/ui/tabs/tab_metrics_logger_impl.cc
+++ b/chrome/browser/ui/tabs/tab_metrics_logger_impl.cc
@@ -8,15 +8,18 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/engagement/site_engagement_service.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_metrics_event.pb.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/page_importance_signals.h"
 #include "net/base/mime_util.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
+#include "third_party/WebKit/public/platform/WebSuddenTerminationDisablerType.h"
 
 using metrics::TabMetricsEvent;
 
@@ -104,8 +107,19 @@
   // audio indicator in the tab strip.
   entry.SetWasRecentlyAudible(web_contents->WasRecentlyAudible());
 
-  entry.SetIsPinned(tab_strip_model->IsTabPinned(index))
+  resource_coordinator::TabManager* tab_manager =
+      g_browser_process->GetTabManager();
+  DCHECK(tab_manager);
+
+  entry
+      .SetHasBeforeUnloadHandler(
+          web_contents->GetMainFrame()->GetSuddenTerminationDisablerState(
+              blink::kBeforeUnloadHandler))
       .SetHasFormEntry(
           web_contents->GetPageImportanceSignals().had_form_interaction)
+      // TODO(michaelpg): This dependency should be reversed during the
+      // resource_coordinator refactor: crbug.com/775644.
+      .SetIsExtensionProtected(!tab_manager->IsTabAutoDiscardable(web_contents))
+      .SetIsPinned(tab_strip_model->IsTabPinned(index))
       .Record(ukm_recorder);
 }
diff --git a/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.cc b/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.cc
index a0c1eab6..8526a74 100644
--- a/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.cc
+++ b/chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.cc
@@ -69,23 +69,25 @@
   //   of view-source:chrome://newtab, which should display its URL despite what
   //   chrome://newtab says.
   content::NavigationEntry* entry = GetNavigationEntry();
-  if (entry) {
-    if (entry->IsViewSourceMode() ||
-        entry->GetPageType() == content::PAGE_TYPE_INTERSTITIAL) {
-      return true;
-    }
+  if (!entry)
+    return true;
 
-    GURL url = entry->GetURL();
-    GURL virtual_url = entry->GetVirtualURL();
-    if (url.SchemeIs(content::kChromeUIScheme) ||
-        virtual_url.SchemeIs(content::kChromeUIScheme)) {
-      if (!url.SchemeIs(content::kChromeUIScheme))
-        url = virtual_url;
-      return url.host() != chrome::kChromeUINewTabHost;
-    }
+  if (entry->IsViewSourceMode() ||
+      entry->GetPageType() == content::PAGE_TYPE_INTERSTITIAL) {
+    return true;
   }
 
-  return !search::IsInstantNTP(GetActiveWebContents());
+  GURL url = entry->GetURL();
+  GURL virtual_url = entry->GetVirtualURL();
+  if (url.SchemeIs(content::kChromeUIScheme) ||
+      virtual_url.SchemeIs(content::kChromeUIScheme)) {
+    if (!url.SchemeIs(content::kChromeUIScheme))
+      url = virtual_url;
+    return url.host() != chrome::kChromeUINewTabHost;
+  }
+
+  Profile* profile = GetProfile();
+  return !profile || !search::IsInstantNTPURL(url, profile);
 }
 
 security_state::SecurityLevel ChromeToolbarModelDelegate::GetSecurityLevel()
diff --git a/chrome/browser/ui/toolbar/toolbar_model_unittest.cc b/chrome/browser/ui/toolbar/toolbar_model_unittest.cc
index 24d2dbe..b60efaa 100644
--- a/chrome/browser/ui/toolbar/toolbar_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/toolbar_model_unittest.cc
@@ -40,10 +40,21 @@
         base::ASCIIToUTF16("view-source:www.google.com"),
     },
     {
+        GURL("chrome://newtab/"), base::string16(),
+    },
+    {
         GURL("view-source:chrome://newtab/"),
         base::ASCIIToUTF16("view-source:chrome://newtab"),
     },
     {
+        GURL("chrome-search://local-ntp/local-ntp.html"), base::string16(),
+    },
+    {
+        GURL("view-source:chrome-search://local-ntp/local-ntp.html"),
+        base::ASCIIToUTF16(
+            "view-source:chrome-search://local-ntp/local-ntp.html"),
+    },
+    {
         GURL("chrome-extension://fooooooooooooooooooooooooooooooo/bar.html"),
         base::ASCIIToUTF16(
             "chrome-extension://fooooooooooooooooooooooooooooooo/bar.html"),
@@ -120,23 +131,23 @@
     const base::string16& expected_text) {
   // Check while loading.
   content::NavigationController* controller =
-      &browser()->tab_strip_model()->GetWebContentsAt(0)->GetController();
+      &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
   controller->LoadURL(url, content::Referrer(), ui::PAGE_TRANSITION_LINK,
                       std::string());
   ToolbarModel* toolbar_model = browser()->toolbar_model();
   EXPECT_EQ(expected_text, toolbar_model->GetFormattedURL(nullptr));
-  EXPECT_TRUE(toolbar_model->ShouldDisplayURL());
+  EXPECT_NE(expected_text.empty(), toolbar_model->ShouldDisplayURL());
 
   // Check after commit.
   CommitPendingLoad(controller);
   EXPECT_EQ(expected_text, toolbar_model->GetFormattedURL(nullptr));
-  EXPECT_TRUE(toolbar_model->ShouldDisplayURL());
+  EXPECT_NE(expected_text.empty(), toolbar_model->ShouldDisplayURL());
 }
 
 void ToolbarModelTest::NavigateAndCheckElided(const GURL& url) {
   // Check while loading.
   content::NavigationController* controller =
-      &browser()->tab_strip_model()->GetWebContentsAt(0)->GetController();
+      &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
   controller->LoadURL(url, content::Referrer(), ui::PAGE_TRANSITION_LINK,
                       std::string());
   ToolbarModel* toolbar_model = browser()->toolbar_model();
@@ -174,3 +185,31 @@
       GURL(std::string("https://www.foo.com/?") + long_text));
   NavigateAndCheckElided(GURL(std::string("data:abc") + long_text));
 }
+
+// Regression test for crbug.com/792401.
+TEST_F(ToolbarModelTest, ShouldDisplayURLWhileNavigatingAwayFromNTP) {
+  ToolbarModel* toolbar_model = browser()->toolbar_model();
+
+  // Open an NTP. Its URL should not be displayed.
+  AddTab(browser(), GURL("chrome://newtab"));
+  ASSERT_FALSE(toolbar_model->ShouldDisplayURL());
+  ASSERT_TRUE(toolbar_model->GetFormattedURL(nullptr).empty());
+
+  const std::string other_url = "https://www.foo.com";
+
+  // Start loading another page. Its URL should be displayed, even though the
+  // current page is still the NTP.
+  content::NavigationController* controller =
+      &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
+  controller->LoadURL(GURL(other_url), content::Referrer(),
+                      ui::PAGE_TRANSITION_LINK, std::string());
+  EXPECT_TRUE(toolbar_model->ShouldDisplayURL());
+  EXPECT_EQ(base::ASCIIToUTF16(other_url),
+            toolbar_model->GetFormattedURL(nullptr));
+
+  // Of course the same should still hold after committing.
+  CommitPendingLoad(controller);
+  EXPECT_TRUE(toolbar_model->ShouldDisplayURL());
+  EXPECT_EQ(base::ASCIIToUTF16(other_url),
+            toolbar_model->GetFormattedURL(nullptr));
+}
diff --git a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
index bf1da98..959ff4f6 100644
--- a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
@@ -90,7 +90,8 @@
   }
 
   void TearDownOnMainThread() override {
-    arc_app_list_pref_->app_connection_holder()->SetInstance(nullptr);
+    arc_app_list_pref_->app_connection_holder()->CloseInstance(
+        app_instance_.get());
     app_instance_.reset();
     ArcSessionManager::Get()->Shutdown();
   }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
index 01099a3..d150b25 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "base/scoped_observer.h"
+#include "base/test/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
@@ -508,7 +509,7 @@
   EXPECT_TRUE(menu_button->menu()->IsShowing());
 
   // Show a content setting icon.
-  const auto& content_setting_views =
+  auto& content_setting_views =
       frame_view->hosted_app_button_container_->content_setting_views_;
 
   for (auto* v : content_setting_views)
@@ -522,10 +523,32 @@
 
   content_settings->OnGeolocationPermissionSet(kAppStartURL.GetOrigin(), true);
 
-  int visible = std::count_if(
-      content_setting_views.begin(), content_setting_views.end(),
-      [](const ContentSettingImageView* v) { return v->visible(); });
-  EXPECT_EQ(1, visible);
+  auto is_visible = [](const ContentSettingImageView* v) {
+    return v->visible();
+  };
+
+  EXPECT_EQ(1, std::count_if(content_setting_views.begin(),
+                             content_setting_views.end(), is_visible));
+
+  // Press the content setting button.
+  auto content_setting_view = std::find_if(
+      content_setting_views.begin(), content_setting_views.end(), is_visible);
+
+  base::HistogramTester histograms;
+
+  (*content_setting_view)
+      ->OnKeyPressed(
+          ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE));
+  (*content_setting_view)
+      ->OnKeyReleased(
+          ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SPACE, ui::EF_NONE));
+
+  histograms.ExpectBucketCount(
+      "HostedAppFrame.ContentSettings.ImagePressed",
+      static_cast<int>(ContentSettingImageModel::ImageType::GEOLOCATION), 1);
+  histograms.ExpectBucketCount(
+      "ContentSettings.ImagePressed",
+      static_cast<int>(ContentSettingImageModel::ImageType::GEOLOCATION), 1);
 
   // The app and domain should render next to the window title.
   frame_header->LayoutRenderTexts(gfx::Rect(300, 30), 100, 100);
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.cc b/chrome/browser/ui/views/frame/hosted_app_button_container.cc
index ea274d3..c7a7986b 100644
--- a/chrome/browser/ui/views/frame/hosted_app_button_container.cc
+++ b/chrome/browser/ui/views/frame/hosted_app_button_container.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/frame/hosted_app_button_container.h"
 
+#include "base/metrics/histogram_macros.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h"
 #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
@@ -97,6 +98,13 @@
   return browser_view_->browser()->content_setting_bubble_model_delegate();
 }
 
+void HostedAppButtonContainer::OnContentSettingImageBubbleShown(
+    ContentSettingImageModel::ImageType type) const {
+  UMA_HISTOGRAM_ENUMERATION(
+      "HostedAppFrame.ContentSettings.ImagePressed", type,
+      ContentSettingImageModel::ImageType::NUM_IMAGE_TYPES);
+}
+
 void HostedAppButtonContainer::RefreshContentSettingViews() {
   for (auto* v : content_setting_views_)
     v->Update();
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.h b/chrome/browser/ui/views/frame/hosted_app_button_container.h
index 99fac99..3af6c0d2 100644
--- a/chrome/browser/ui/views/frame/hosted_app_button_container.h
+++ b/chrome/browser/ui/views/frame/hosted_app_button_container.h
@@ -71,6 +71,8 @@
   content::WebContents* GetContentSettingWebContents() override;
   ContentSettingBubbleModelDelegate* GetContentSettingBubbleModelDelegate()
       override;
+  void OnContentSettingImageBubbleShown(
+      ContentSettingImageModel::ImageType type) const override;
 
   // views::View:
   void ChildVisibilityChanged(views::View* child) override;
diff --git a/chrome/browser/ui/views/frame/hosted_app_frame_header_ash.cc b/chrome/browser/ui/views/frame/hosted_app_frame_header_ash.cc
index 6ed241b..8ee1968 100644
--- a/chrome/browser/ui/views/frame/hosted_app_frame_header_ash.cc
+++ b/chrome/browser/ui/views/frame/hosted_app_frame_header_ash.cc
@@ -41,8 +41,7 @@
 HostedAppFrameHeaderAsh::~HostedAppFrameHeaderAsh() {}
 
 std::unique_ptr<gfx::RenderText> HostedAppFrameHeaderAsh::CreateRenderText() {
-  std::unique_ptr<gfx::RenderText> render_text(
-      gfx::RenderText::CreateInstance());
+  auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
   render_text->SetFontList(views::NativeWidgetAura::GetWindowTitleFontList());
   render_text->SetCursorEnabled(false);
   render_text->SetColor(GetTitleColor());
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc
index 3795471..49b6f64 100644
--- a/chrome/browser/ui/views/hung_renderer_view.cc
+++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/harmony/chrome_typography.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/crash_keys.h"
 #include "chrome/common/logging_chrome.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
@@ -374,13 +373,13 @@
     base::StringPairs crash_keys;
 
     crash_keys.push_back(std::make_pair(
-        crash_keys::kHungRendererOutstandingAckCount,
+        "hung-outstanding-acks",
         base::IntToString(unresponsive_state_.outstanding_ack_count)));
     crash_keys.push_back(std::make_pair(
-        crash_keys::kHungRendererOutstandingEventType,
+        "hung-outstanding-event-type",
         base::IntToString(unresponsive_state_.outstanding_event_type)));
     crash_keys.push_back(
-        std::make_pair(crash_keys::kHungRendererLastEventType,
+        std::make_pair("hung-last-event-type",
                        base::IntToString(unresponsive_state_.last_event_type)));
 
     // Try to generate a crash report for the hung process.
diff --git a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
index 46342c8..1b4996a 100644
--- a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
@@ -17,6 +18,8 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/views/content_setting_bubble_contents.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/common/content_settings_types.h"
@@ -27,11 +30,14 @@
 #include "ui/views/widget/widget.h"
 #include "url/gurl.h"
 
+using ImageType = ContentSettingImageModel::ImageType;
+
 class ContentSettingBubbleDialogTest : public DialogBrowserTest {
  public:
   ContentSettingBubbleDialogTest() {}
 
-  void ShowDialogBubble(ContentSettingsType content_type);
+  void ShowDialogBubble(ContentSettingsType content_type,
+                        ContentSettingImageModel::ImageType image_type);
 
   void ShowDialog(const std::string& name) override;
 
@@ -40,7 +46,8 @@
 };
 
 void ContentSettingBubbleDialogTest::ShowDialogBubble(
-    ContentSettingsType content_type) {
+    ContentSettingsType content_type,
+    ContentSettingImageModel::ImageType image_type) {
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   TabSpecificContentSettings* content_settings =
@@ -92,33 +99,49 @@
   browser()->window()->UpdateToolbar(web_contents);
   LocationBarTesting* location_bar_testing =
       browser()->window()->GetLocationBar()->GetLocationBarForTesting();
+
+  base::HistogramTester histograms;
+
   EXPECT_TRUE(location_bar_testing->TestContentSettingImagePressed(
       ContentSettingImageModel::GetContentSettingImageModelIndexForTesting(
-          content_type)));
+          image_type)));
+
+  histograms.ExpectBucketCount("ContentSettings.ImagePressed",
+                               static_cast<int>(image_type), 1);
 }
 
 void ContentSettingBubbleDialogTest::ShowDialog(const std::string& name) {
   constexpr struct {
     const char* name;
     ContentSettingsType content_type;
+    ContentSettingImageModel::ImageType image_type;
   } content_settings_values[] = {
-      {"cookies", CONTENT_SETTINGS_TYPE_COOKIES},
-      {"images", CONTENT_SETTINGS_TYPE_IMAGES},
-      {"javascript", CONTENT_SETTINGS_TYPE_JAVASCRIPT},
-      {"plugins", CONTENT_SETTINGS_TYPE_PLUGINS},
-      {"popups", CONTENT_SETTINGS_TYPE_POPUPS},
-      {"geolocation", CONTENT_SETTINGS_TYPE_GEOLOCATION},
-      {"ppapi_broker", CONTENT_SETTINGS_TYPE_PPAPI_BROKER},
-      {"mixed_script", CONTENT_SETTINGS_TYPE_MIXEDSCRIPT},
-      {"mediastream_mic", CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC},
-      {"mediastream_camera", CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA},
-      {"protocol_handlers", CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS},
-      {"automatic_downloads", CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS},
-      {"midi_sysex", CONTENT_SETTINGS_TYPE_MIDI_SYSEX},
-      {"ads", CONTENT_SETTINGS_TYPE_ADS}};
+      {"cookies", CONTENT_SETTINGS_TYPE_COOKIES, ImageType::COOKIES},
+      {"images", CONTENT_SETTINGS_TYPE_IMAGES, ImageType::IMAGES},
+      {"javascript", CONTENT_SETTINGS_TYPE_JAVASCRIPT, ImageType::JAVASCRIPT},
+      {"plugins", CONTENT_SETTINGS_TYPE_PLUGINS, ImageType::PLUGINS},
+      {"popups", CONTENT_SETTINGS_TYPE_POPUPS, ImageType::POPUPS},
+      {"geolocation", CONTENT_SETTINGS_TYPE_GEOLOCATION,
+       ImageType::GEOLOCATION},
+      {"ppapi_broker", CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
+       ImageType::PPAPI_BROKER},
+      {"mixed_script", CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
+       ImageType::MIXEDSCRIPT},
+      {"mediastream_mic", CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+       ImageType::MEDIASTREAM},
+      {"mediastream_camera", CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
+       ImageType::MEDIASTREAM},
+      {"protocol_handlers", CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS,
+       ImageType::PROTOCOL_HANDLERS},
+      {"automatic_downloads", CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
+       ImageType::AUTOMATIC_DOWNLOADS},
+      {"midi_sysex", CONTENT_SETTINGS_TYPE_MIDI_SYSEX, ImageType::MIDI_SYSEX},
+      {"ads", CONTENT_SETTINGS_TYPE_ADS, ImageType::ADS},
+  };
   for (auto content_settings : content_settings_values) {
     if (name == content_settings.name) {
-      ShowDialogBubble(content_settings.content_type);
+      ShowDialogBubble(content_settings.content_type,
+                       content_settings.image_type);
       return;
     }
   }
diff --git a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
index a259b58..a6f71286 100644
--- a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
+++ b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
@@ -199,6 +199,8 @@
       bubble_view_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT);
     }
     bubble_widget->Show();
+    delegate_->OnContentSettingImageBubbleShown(
+        content_setting_image_model_->image_type());
   }
 
   return true;
diff --git a/chrome/browser/ui/views/location_bar/content_setting_image_view.h b/chrome/browser/ui/views/location_bar/content_setting_image_view.h
index bf5547a..7d7fff25 100644
--- a/chrome/browser/ui/views/location_bar/content_setting_image_view.h
+++ b/chrome/browser/ui/views/location_bar/content_setting_image_view.h
@@ -45,6 +45,10 @@
     virtual ContentSettingBubbleModelDelegate*
     GetContentSettingBubbleModelDelegate() = 0;
 
+    // Invoked when a bubble is shown.
+    virtual void OnContentSettingImageBubbleShown(
+        ContentSettingImageModel::ImageType type) const {}
+
    protected:
     virtual ~Delegate() {}
   };
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 1bdcac7..a1314ec 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -503,8 +503,7 @@
 
 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateRenderText(
     const base::string16& text) const {
-  std::unique_ptr<gfx::RenderText> render_text(
-      gfx::RenderText::CreateInstance());
+  auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
   render_text->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0)));
   render_text->SetCursorEnabled(false);
   render_text->SetElideBehavior(gfx::ELIDE_TAIL);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 3606782..742fec2 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -31,6 +31,7 @@
 #include "components/omnibox/browser/omnibox_edit_model.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/browser/omnibox_popup_model.h"
+#include "components/omnibox/browser/suggestion_answer.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/toolbar/toolbar_model.h"
 #include "content/public/browser/web_contents.h"
@@ -482,8 +483,12 @@
   if (save_original_selection)
     saved_temporary_selection_ = GetSelectedRange();
 
+  // Get friendly accessibility label.
+  base::string16 description =
+      match.answer ? match.answer->second_line().AccessibleText()
+                   : match.description;
   friendly_suggestion_text_ = AutocompleteMatchType::ToAccessibilityLabel(
-      match.type, display_text, match.description,
+      match.type, display_text, description,
       &friendly_suggestion_text_prefix_length_);
 
   SetWindowTextAndCaretPos(display_text, display_text.length(), false,
diff --git a/chrome/browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc b/chrome/browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc
index da671c7..28b7e596 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc
@@ -114,7 +114,8 @@
   // Run the interesting code.
   tray_watcher_->EnsureTrayIconVisible();
 
-  EXPECT_EQ(PREFERENCE_SHOW_ALWAYS, GetNotifyItem()->preference);
+  EXPECT_EQ(static_cast<DWORD>(PREFERENCE_SHOW_ALWAYS),
+            GetNotifyItem()->preference);
   SendNotifyItemUpdate(std::move(notify_item));
   notify_item = GetNotifyItem();
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index 1d6d10d..813b9cb 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -346,11 +346,6 @@
   return true;
 }
 
-void ToolbarView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
-  node_data->role = ui::AX_ROLE_TOOLBAR;
-  node_data->SetName(l10n_util::GetStringUTF8(IDS_ACCNAME_TOOLBAR));
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // ToolbarView, Menu::Delegate overrides:
 
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.h b/chrome/browser/ui/views/toolbar/toolbar_view.h
index aa7305d..e474fd7 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.h
@@ -113,7 +113,6 @@
 
   // AccessiblePaneView:
   bool SetPaneFocus(View* initial_focus) override;
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
 
   // views::MenuButtonListener:
   void OnMenuButtonClicked(views::MenuButton* source,
diff --git a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
index 5ee538c..1f6cb23a 100644
--- a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include "ash/public/cpp/ash_switches.h"
 #include "ash/shell.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -339,6 +340,8 @@
                      TopRowKeysAreFunctionKeys(profile));
   source->AddBoolean("voiceInteractionEnabled",
                      chromeos::switches::IsVoiceInteractionEnabled());
+  source->AddBoolean("displayMoveWindowAccelsEnabled",
+                     ash::switches::IsDisplayMoveWindowAccelsEnabled());
   source->AddBoolean("keyboardOverlayUsesLayout2",
                      ui::DeviceUsesKeyboardLayout2());
   ash::Shell* shell = ash::Shell::Get();
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
index 796d4d9..9ad60c25 100644
--- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
+++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
@@ -47,7 +47,7 @@
 const char kNoScriptFlagLink[] = "chrome://flags/#enable-noscript-previews";
 const char kOfflinePageFlagLink[] = "chrome://flags/#enable-offline-previews";
 
-const char kDefaultFlagValue[] = "Not Forced";
+const char kDefaultFlagValue[] = "Default";
 
 // Check if the flag status of the flag is a forced value or not.
 std::string GetFeatureFlagStatus(const std::string& feature_name) {
@@ -55,13 +55,13 @@
       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
           switches::kEnableFeatures);
   if (enabled_features.find(feature_name) != std::string::npos) {
-    return "Forced Enabled";
+    return "Enabled";
   }
   std::string disabled_features =
       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
           switches::kDisableFeatures);
   if (disabled_features.find(feature_name) != std::string::npos) {
-    return "Forced Disabled";
+    return "Disabled";
   }
   return kDefaultFlagValue;
 }
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
index c56005d9..5bf9620 100644
--- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
@@ -67,7 +67,9 @@
 constexpr char kNoScriptFeatureName[] = "NoScriptPreviews";
 constexpr char kOfflinePageFeatureName[] = "OfflinePreviews";
 
-constexpr char kDefaultFlagValue[] = "Not Forced";
+constexpr char kDefaultFlagValue[] = "Default";
+constexpr char kEnabledFlagValue[] = "Enabled";
+constexpr char kDisabledFlagValue[] = "Disabled";
 
 // The map that would be passed to the callback in GetPreviewsEnabledCallback.
 std::unordered_map<std::string, mojom::PreviewsStatusPtr> passed_in_modes;
@@ -477,7 +479,7 @@
   ASSERT_NE(passed_in_flags.end(), noscript_flag);
   EXPECT_EQ(flag_descriptions::kEnableNoScriptPreviewsName,
             noscript_flag->second->description);
-  EXPECT_EQ("Forced Enabled", noscript_flag->second->value);
+  EXPECT_EQ(kEnabledFlagValue, noscript_flag->second->value);
   EXPECT_EQ(kNoScriptFlagLink, noscript_flag->second->link);
 }
 
@@ -494,7 +496,7 @@
   ASSERT_NE(passed_in_flags.end(), noscript_flag);
   EXPECT_EQ(flag_descriptions::kEnableNoScriptPreviewsName,
             noscript_flag->second->description);
-  EXPECT_EQ("Forced Disabled", noscript_flag->second->value);
+  EXPECT_EQ(kDisabledFlagValue, noscript_flag->second->value);
   EXPECT_EQ(kNoScriptFlagLink, noscript_flag->second->link);
 }
 
@@ -534,7 +536,7 @@
   EXPECT_EQ(flag_descriptions::kEnableOfflinePreviewsName,
             offline_page_flag->second->description);
 #endif  // OS_ANDROID
-  EXPECT_EQ("Forced Enabled", offline_page_flag->second->value);
+  EXPECT_EQ(kEnabledFlagValue, offline_page_flag->second->value);
   EXPECT_EQ(kOfflinePageFlagLink, offline_page_flag->second->link);
 }
 
@@ -554,7 +556,7 @@
   EXPECT_EQ(flag_descriptions::kEnableOfflinePreviewsName,
             offline_page_flag->second->description);
 #endif  // OS_ANDROID
-  EXPECT_EQ("Forced Disabled", offline_page_flag->second->value);
+  EXPECT_EQ(kDisabledFlagValue, offline_page_flag->second->value);
   EXPECT_EQ(kOfflinePageFlagLink, offline_page_flag->second->link);
 }
 
diff --git a/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc b/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
index 477aa793..3c264c5 100644
--- a/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
+++ b/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/tpm_firmware_update.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/user_manager/user_manager.h"
@@ -58,6 +59,24 @@
 
 void BrowserLifetimeHandler::HandleFactoryReset(
     const base::ListValue* args) {
+  bool tpm_firmware_update_requested;
+  args->GetBoolean(0, &tpm_firmware_update_requested);
+  if (tpm_firmware_update_requested) {
+    chromeos::tpm_firmware_update::ShouldOfferUpdateViaPowerwash(
+        base::BindOnce([](bool offer_update) {
+          if (!offer_update)
+            return;
+
+          PrefService* prefs = g_browser_process->local_state();
+          prefs->SetBoolean(prefs::kFactoryResetRequested, true);
+          prefs->SetBoolean(prefs::kFactoryResetTPMFirmwareUpdateRequested,
+                            true);
+          prefs->CommitPendingWrite();
+          chrome::AttemptRelaunch();
+        }));
+    return;
+  }
+
   policy::BrowserPolicyConnectorChromeOS* connector =
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   bool allow_powerwash = !connector->IsEnterpriseManaged() &&
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc
index 87984fc4..1bb0d8f 100644
--- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc
+++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc
@@ -13,9 +13,13 @@
 #include "base/metrics/user_metrics_action.h"
 #include "base/synchronization/lock.h"
 #include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/component_updater/sw_reporter_installer_win.h"
+#include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_message_handler.h"
 
 using safe_browsing::ChromeCleanerController;
 
@@ -79,29 +83,36 @@
 void ChromeCleanupHandler::RegisterMessages() {
   web_ui()->RegisterMessageCallback(
       "dismissCleanupPage",
-      base::Bind(&ChromeCleanupHandler::HandleDismiss, base::Unretained(this)));
+      base::BindRepeating(&ChromeCleanupHandler::HandleDismiss,
+                          base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
       "registerChromeCleanerObserver",
-      base::Bind(&ChromeCleanupHandler::HandleRegisterChromeCleanerObserver,
-                 base::Unretained(this)));
+      base::BindRepeating(
+          &ChromeCleanupHandler::HandleRegisterChromeCleanerObserver,
+          base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
+      "startScanning",
+      base::BindRepeating(&ChromeCleanupHandler::HandleStartScanning,
+                          base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
       "restartComputer",
-      base::Bind(&ChromeCleanupHandler::HandleRestartComputer,
-                 base::Unretained(this)));
+      base::BindRepeating(&ChromeCleanupHandler::HandleRestartComputer,
+                          base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
       "setLogsUploadPermission",
-      base::Bind(&ChromeCleanupHandler::HandleSetLogsUploadPermission,
-                 base::Unretained(this)));
+      base::BindRepeating(&ChromeCleanupHandler::HandleSetLogsUploadPermission,
+                          base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
-      "startCleanup", base::Bind(&ChromeCleanupHandler::HandleStartCleanup,
-                                 base::Unretained(this)));
+      "startCleanup",
+      base::BindRepeating(&ChromeCleanupHandler::HandleStartCleanup,
+                          base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
       "notifyShowDetails",
-      base::Bind(&ChromeCleanupHandler::HandleNotifyShowDetails,
-                 base::Unretained(this)));
+      base::BindRepeating(&ChromeCleanupHandler::HandleNotifyShowDetails,
+                          base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
       "notifyChromeCleanupLearnMoreClicked",
-      base::Bind(
+      base::BindRepeating(
           &ChromeCleanupHandler::HandleNotifyChromeCleanupLearnMoreClicked,
           base::Unretained(this)));
 }
@@ -116,39 +127,37 @@
 
 void ChromeCleanupHandler::OnIdle(
     ChromeCleanerController::IdleReason idle_reason) {
-  CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::Value("chrome-cleanup-on-idle"),
-                         base::Value(IdleReasonToString(idle_reason)));
+  FireWebUIListener("chrome-cleanup-on-idle",
+                    base::Value(IdleReasonToString(idle_reason)));
 }
 
 void ChromeCleanupHandler::OnScanning() {
-  CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::Value("chrome-cleanup-on-scanning"));
+  FireWebUIListener("chrome-cleanup-on-scanning");
+}
+
+void ChromeCleanupHandler::OnReporterRunning() {
+  FireWebUIListener("chrome-cleanup-on-reporter-running");
 }
 
 void ChromeCleanupHandler::OnInfected(
     const safe_browsing::ChromeCleanerScannerResults& scanner_results) {
-  CallJavascriptFunction(
-      "cr.webUIListenerCallback", base::Value("chrome-cleanup-on-infected"),
-      GetFilesAsListStorage(scanner_results.files_to_delete()));
+  FireWebUIListener("chrome-cleanup-on-infected",
+                    GetFilesAsListStorage(scanner_results.files_to_delete()));
 }
 
 void ChromeCleanupHandler::OnCleaning(
     const safe_browsing::ChromeCleanerScannerResults& scanner_results) {
-  CallJavascriptFunction(
-      "cr.webUIListenerCallback", base::Value("chrome-cleanup-on-cleaning"),
-      GetFilesAsListStorage(scanner_results.files_to_delete()));
+  FireWebUIListener("chrome-cleanup-on-cleaning",
+                    GetFilesAsListStorage(scanner_results.files_to_delete()));
 }
 
 void ChromeCleanupHandler::OnRebootRequired() {
-  CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::Value("chrome-cleanup-on-reboot-required"));
+  FireWebUIListener("chrome-cleanup-on-reboot-required");
 }
 
 void ChromeCleanupHandler::OnLogsEnabledChanged(bool logs_enabled) {
-  CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::Value("chrome-cleanup-upload-permission-change"),
-                         base::Value(logs_enabled));
+  FireWebUIListener("chrome-cleanup-upload-permission-change",
+                    base::Value(logs_enabled));
 }
 
 void ChromeCleanupHandler::HandleDismiss(const base::ListValue* args) {
@@ -177,8 +186,7 @@
   controller_->RemoveObserver(this);
   controller_->ResetIdleState();
 
-  CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::Value("chrome-cleanup-on-dismiss"));
+  FireWebUIListener("chrome-cleanup-on-dismiss");
 }
 
 void ChromeCleanupHandler::HandleRegisterChromeCleanerObserver(
@@ -194,14 +202,33 @@
   OnLogsEnabledChanged(controller_->logs_enabled());
 }
 
+void ChromeCleanupHandler::HandleStartScanning(const base::ListValue* args) {
+  CHECK_EQ(1U, args->GetSize());
+  bool allow_logs_upload = false;
+  args->GetBoolean(0, &allow_logs_upload);
+
+  // The state is propagated to all open tabs and should be consistent.
+  DCHECK_EQ(controller_->logs_enabled(), allow_logs_upload);
+
+  // TODO(crbug.com/776538): Force an on-demand update of the component.
+  component_updater::RegisterSwReporterComponentWithParams(
+      allow_logs_upload ? safe_browsing::SwReporterInvocationType::
+                              kUserInitiatedWithLogsAllowed
+                        : safe_browsing::SwReporterInvocationType::
+                              kUserInitiatedWithLogsDisallowed,
+      g_browser_process->component_updater());
+
+  base::RecordAction(
+      base::UserMetricsAction("SoftwareReporter.CleanupWebui_StartScanning"));
+}
+
 void ChromeCleanupHandler::HandleRestartComputer(const base::ListValue* args) {
   DCHECK_EQ(0U, args->GetSize());
 
   base::RecordAction(
       base::UserMetricsAction("SoftwareReporter.CleanupWebui_RestartComputer"));
 
-  CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::Value("chrome-cleanup-on-dismiss"));
+  FireWebUIListener("chrome-cleanup-on-dismiss");
 
   controller_->Reboot();
 }
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h
index 1e3cf17..c0d61a2 100644
--- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h
+++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.h
@@ -33,6 +33,7 @@
   // ChromeCleanerController::Observer implementation.
   void OnIdle(
       safe_browsing::ChromeCleanerController::IdleReason idle_reason) override;
+  void OnReporterRunning() override;
   void OnScanning() override;
   void OnInfected(const safe_browsing::ChromeCleanerScannerResults&
                       reported_results) override;
@@ -51,6 +52,10 @@
   // and retrieves the current cleanup state.
   void HandleRegisterChromeCleanerObserver(const base::ListValue* args);
 
+  // Callback for the "startScanning" message to start scanning the user's
+  // system to detect unwanted software.
+  void HandleStartScanning(const base::ListValue* args);
+
   // Callback for the "restartComputer" message to finalize the cleanup with a
   // system restart.
   void HandleRestartComputer(const base::ListValue* args);
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 5356c893..ab0e5a0 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
@@ -814,8 +814,16 @@
 
 void AddResetStrings(content::WebUIDataSource* html_source) {
   LocalizedString localized_strings[] = {
+#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
+    {"resetPageTitle", safe_browsing::UserInitiatedCleanupsEnabled()
+                           ? IDS_SETTINGS_RESET_AND_CLEANUP
+                           : IDS_SETTINGS_RESET},
+#else
     {"resetPageTitle", IDS_SETTINGS_RESET},
-    {"resetPageDescription", IDS_SETTINGS_RESET_PROFILE_SETTINGS_DESCRIPTION},
+#endif
+    {"resetTrigger", IDS_SETTINGS_RESET},
+    {"resetTriggerDescription",
+     IDS_SETTINGS_RESET_PROFILE_SETTINGS_DESCRIPTION},
     {"resetPageExplanation", IDS_RESET_PROFILE_SETTINGS_EXPLANATION},
     {"triggeredResetPageExplanation",
      IDS_TRIGGERED_RESET_PROFILE_SETTINGS_EXPLANATION},
@@ -834,8 +842,6 @@
     {"resetProfileBannerButton", IDS_SETTINGS_RESET_BANNER_RESET_BUTTON_TEXT},
     {"resetProfileBannerDescription", IDS_SETTINGS_RESET_BANNER_TEXT},
 #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
-    // The page title to be used if user initiated cleanups are enabled.
-    {"resetAndCleanupPageTitle", IDS_SETTINGS_RESET_AND_CLEANUP},
     {"resetCleanupComputerTrigger",
      IDS_SETTINGS_RESET_CLEAN_UP_COMPUTER_TRIGGER},
     {"resetCleanupComputerTriggerDescription",
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
index 29e64c60..0aac146 100644
--- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
+++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
@@ -218,8 +218,17 @@
       web_ui->GetWebContents()->GetBrowserContext());
 }
 
+void RecordAuthenticatedLaunchUserEvent(
+    const AuthenticatedLaunchUserEvent& event) {
+  UMA_HISTOGRAM_ENUMERATION(kAuthenticatedLaunchUserEventMetricsName, event,
+                            AuthenticatedLaunchUserEvent::EVENT_COUNT);
+}
+
 }  // namespace
 
+const char kAuthenticatedLaunchUserEventMetricsName[] =
+    "Signin.AuthenticatedLaunchUserEvent";
+
 // ProfileUpdateObserver ------------------------------------------------------
 
 class UserManagerScreenHandler::ProfileUpdateObserver
@@ -430,6 +439,8 @@
   // Only try to validate locally or check the password change detection
   // if we actually have a local credential saved.
   if (!entry->GetLocalAuthCredentials().empty()) {
+    RecordAuthenticatedLaunchUserEvent(
+        AuthenticatedLaunchUserEvent::LOCAL_REAUTH_DIALOG);
     if (LocalAuth::ValidateLocalAuthCredentials(entry, password)) {
       ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL);
       return;
@@ -458,12 +469,16 @@
   if (!email_address_.empty()) {
     // In order to support the upgrade case where we have a local hash but no
     // password token, the user must perform a full online reauth.
+    RecordAuthenticatedLaunchUserEvent(
+        AuthenticatedLaunchUserEvent::GAIA_REAUTH_DIALOG);
     UserManagerProfileDialog::ShowReauthDialog(
         browser_context, email_address_, signin_metrics::Reason::REASON_UNLOCK);
   } else if (entry->IsSigninRequired() && entry->IsSupervised()) {
     // Supervised profile will only be locked when force-sign-in is enabled
     // and it shouldn't be unlocked. Display the error message directly via
     // the system profile to avoid profile creation.
+    RecordAuthenticatedLaunchUserEvent(
+        AuthenticatedLaunchUserEvent::SUPERVISED_PROFILE_BLOCKED_WARNING);
     DisplayErrorMessage(
         l10n_util::GetStringUTF16(IDS_SUPERVISED_USER_NOT_ALLOWED_BY_POLICY),
         web_ui());
@@ -474,10 +489,14 @@
     // merge. We consider a profile as pre-existing if it has been actived
     // previously. A pre-existed profile can still be used if it has been signed
     // in with an email address matched RestrictSigninToPattern policy already.
+    RecordAuthenticatedLaunchUserEvent(
+        AuthenticatedLaunchUserEvent::USED_PROFILE_BLOCKED_WARNING);
     DisplayErrorMessage(
         l10n_util::GetStringUTF16(IDS_USER_NOT_ALLOWED_BY_POLICY), web_ui());
   } else {
     // Fresh sign in via user manager without existing email address.
+    RecordAuthenticatedLaunchUserEvent(
+        AuthenticatedLaunchUserEvent::FORCED_PRIMARY_SIGNIN_DIALOG);
     UserManagerProfileDialog::ShowSigninDialog(
         browser_context, profile_path,
         signin_util::IsForceSigninEnabled()
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.h b/chrome/browser/ui/webui/signin/user_manager_screen_handler.h
index 7c4ad86..05d91b1 100644
--- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.h
+++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.h
@@ -32,6 +32,19 @@
 class ListValue;
 }
 
+extern const char kAuthenticatedLaunchUserEventMetricsName[];
+
+// UI event when user click a locked profile. It must matches the
+// AuthenticatedLaunchUserEvent in enums.xml
+enum AuthenticatedLaunchUserEvent {
+  LOCAL_REAUTH_DIALOG,
+  GAIA_REAUTH_DIALOG,
+  SUPERVISED_PROFILE_BLOCKED_WARNING,
+  USED_PROFILE_BLOCKED_WARNING,
+  FORCED_PRIMARY_SIGNIN_DIALOG,
+  EVENT_COUNT,
+};
+
 class UserManagerScreenHandler
     : public content::WebUIMessageHandler,
       public proximity_auth::ScreenlockBridge::LockHandler,
diff --git a/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc b/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc
index dca96b9..a37de58 100644
--- a/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/histogram_tester.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profile_window.h"
 #include "chrome/browser/profiles/profiles_state.h"
@@ -14,6 +15,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
+#include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/chromium_strings.h"
@@ -106,35 +108,97 @@
   EXPECT_EQ(GURL(chrome::kChromeUIHelpURL), current_URL);
 }
 
-IN_PROC_BROWSER_TEST_F(UserManagerUIBrowserTest, LaunchBlockedUser) {
-  ui_test_utils::NavigateToURL(browser(),
-                               GURL(chrome::kChromeUIMdUserManagerUrl));
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
+class UserManagerUIAuthenticatedUserBrowserTest
+    : public UserManagerUIBrowserTest {
+ public:
+  void Init() {
+    ui_test_utils::NavigateToURL(browser(),
+                                 GURL(chrome::kChromeUIMdUserManagerUrl));
+    web_contents_ = browser()->tab_strip_model()->GetActiveWebContents();
+    profile_ = browser()->profile();
+    EXPECT_TRUE(
+        g_browser_process->profile_manager()
+            ->GetProfileAttributesStorage()
+            .GetProfileAttributesWithPath(profile_->GetPath(), &entry_));
+  }
 
-  signin_util::SetForceSigninForTesting(true);
+  void LaunchAuthenticatedUser(const std::string& email) {
+    std::string profile_path;
+    base::ReplaceChars(profile_->GetPath().MaybeAsASCII(), "\\", "\\\\",
+                       &profile_path);
+    std::string launch_js = base::StringPrintf(
+        "chrome.send('authenticatedLaunchUser', ['%s', '%s', ''])",
+        profile_path.c_str(), email.c_str());
+    EXPECT_TRUE(content::ExecuteScript(web_contents_, launch_js));
+  }
 
-  Profile* profile = browser()->profile();
-  ProfileAttributesEntry* entry;
-  EXPECT_TRUE(g_browser_process->profile_manager()
-                  ->GetProfileAttributesStorage()
-                  .GetProfileAttributesWithPath(profile->GetPath(), &entry));
-  entry->SetIsSigninRequired(true);
-  entry->SetActiveTimeToNow();
+  content::WebContents* web_contents_;
+  Profile* profile_;
+  ProfileAttributesEntry* entry_;
+  base::HistogramTester histogram_tester_;
+};
+
+IN_PROC_BROWSER_TEST_F(UserManagerUIAuthenticatedUserBrowserTest, Reauth) {
+  Init();
+  entry_->SetLocalAuthCredentials("1mock_credentials");
+
+  LaunchAuthenticatedUser("email@mock.com");
+
+  histogram_tester_.ExpectBucketCount(
+      kAuthenticatedLaunchUserEventMetricsName,
+      AuthenticatedLaunchUserEvent::LOCAL_REAUTH_DIALOG, 1);
+  histogram_tester_.ExpectBucketCount(
+      kAuthenticatedLaunchUserEventMetricsName,
+      AuthenticatedLaunchUserEvent::GAIA_REAUTH_DIALOG, 1);
+  histogram_tester_.ExpectTotalCount(kAuthenticatedLaunchUserEventMetricsName,
+                                     2);
+}
+
+IN_PROC_BROWSER_TEST_F(UserManagerUIAuthenticatedUserBrowserTest,
+                       SupervisedUserBlocked) {
+  Init();
+  entry_->SetIsSigninRequired(true);
+  entry_->SetSupervisedUserId("supervised_user_id");
   MockLoginUIService* service = static_cast<MockLoginUIService*>(
       LoginUIServiceFactory::GetInstance()->SetTestingFactoryAndUse(
-          profile, CreateLoginUIService));
-
-  std::string profile_path;
-  base::ReplaceChars(profile->GetPath().MaybeAsASCII(), "\\", "\\\\",
-                     &profile_path);
-  std::string launch_js = base::StringPrintf(
-      "chrome.send('authenticatedLaunchUser', ['%s', '', ''])",
-      profile_path.c_str());
-
+          profile_, CreateLoginUIService));
   EXPECT_CALL(*service, DisplayLoginResult(_, _, _));
 
-  EXPECT_TRUE(content::ExecuteScript(web_contents, launch_js));
+  LaunchAuthenticatedUser("");
+
+  histogram_tester_.ExpectUniqueSample(
+      kAuthenticatedLaunchUserEventMetricsName,
+      AuthenticatedLaunchUserEvent::SUPERVISED_PROFILE_BLOCKED_WARNING, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(UserManagerUIAuthenticatedUserBrowserTest,
+                       NormalUserBlocked) {
+  Init();
+  signin_util::SetForceSigninForTesting(true);
+  entry_->SetIsSigninRequired(true);
+  entry_->SetActiveTimeToNow();
+  MockLoginUIService* service = static_cast<MockLoginUIService*>(
+      LoginUIServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+          profile_, CreateLoginUIService));
+  EXPECT_CALL(*service, DisplayLoginResult(_, _, _));
+
+  LaunchAuthenticatedUser("");
+
+  histogram_tester_.ExpectUniqueSample(
+      kAuthenticatedLaunchUserEventMetricsName,
+      AuthenticatedLaunchUserEvent::USED_PROFILE_BLOCKED_WARNING, 1);
+  signin_util::ResetForceSigninForTesting();
+}
+
+IN_PROC_BROWSER_TEST_F(UserManagerUIAuthenticatedUserBrowserTest,
+                       ForcedPrimarySignin) {
+  Init();
+
+  LaunchAuthenticatedUser("");
+
+  histogram_tester_.ExpectUniqueSample(
+      kAuthenticatedLaunchUserEventMetricsName,
+      AuthenticatedLaunchUserEvent::FORCED_PRIMARY_SIGNIN_DIALOG, 1);
 }
 
 // TODO(mlerman): Test that unlocking a locked profile causes the extensions
diff --git a/chrome/browser/ui/window_sizer/window_sizer.cc b/chrome/browser/ui/window_sizer/window_sizer.cc
index f7788c5..3adf2a6 100644
--- a/chrome/browser/ui/window_sizer/window_sizer.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer.cc
@@ -289,11 +289,8 @@
                                          gfx::Rect* default_bounds) const {
   DCHECK(default_bounds);
 #if defined(OS_CHROMEOS)
-  // TODO(beng): insufficient but currently necessary. http://crbug.com/133312
-  if (ash_util::ShouldOpenAshOnStartup()) {
-    *default_bounds = ash::WindowPositioner::GetDefaultWindowBounds(display);
-    return;
-  }
+  *default_bounds = GetDefaultWindowBoundsAsh(display);
+  return;
 #endif
   gfx::Rect work_area = display.work_area();
 
diff --git a/chrome/browser/ui/window_sizer/window_sizer.h b/chrome/browser/ui/window_sizer/window_sizer.h
index ea306102..ab64ec02 100644
--- a/chrome/browser/ui/window_sizer/window_sizer.h
+++ b/chrome/browser/ui/window_sizer/window_sizer.h
@@ -119,6 +119,15 @@
   // The maximum default window width. This value may differ between platforms.
   static const int kWindowMaxDefaultWidth;
 
+#if defined(OS_CHROMEOS)
+  // The number of pixels which are kept free top, left and right when a window
+  // gets positioned to its default location.
+  static const int kDesktopBorderSize = 16;
+
+  // Maximum width of a window even if there is more room on the desktop.
+  static const int kMaximumWindowWidth = 1100;
+#endif
+
  private:
   // The edge of the screen to check for out-of-bounds.
   enum Edge { TOP, LEFT, BOTTOM, RIGHT };
@@ -178,6 +187,9 @@
   // if it was set to SHOW_STATE_DEFAULT.
   void GetTabbedBrowserBoundsAsh(gfx::Rect* bounds,
                                  ui::WindowShowState* show_state) const;
+
+  // Returns the default bounds for a browser window on |display|.
+  static gfx::Rect GetDefaultWindowBoundsAsh(const display::Display& display);
 #endif
 
   // Determine the default show state for the window - not looking at other
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash.cc b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
index 4b27cdb..05e2f64 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
@@ -30,7 +30,7 @@
       // For trusted popups (v1 apps and system windows), do not use the last
       // active window bounds, only use saved or default bounds.
       if (!GetSavedWindowBounds(bounds, show_state))
-        GetDefaultWindowBounds(GetTargetDisplay(gfx::Rect()), bounds);
+        *bounds = GetDefaultWindowBoundsAsh(GetTargetDisplay(gfx::Rect()));
       determined = true;
     } else {
       // In Ash, prioritize the last saved |show_state|. If you have questions
@@ -61,7 +61,7 @@
       // gets maximized after this method returns. Return a sensible default
       // in order to make restored state visibly different from maximized.
       *show_state = ui::SHOW_STATE_MAXIMIZED;
-      *bounds = ash::WindowPositioner::GetDefaultWindowBounds(display);
+      *bounds = GetDefaultWindowBoundsAsh(display);
       determined = true;
     }
   }
@@ -87,7 +87,7 @@
     // target display.
     display = target_display_provider_->GetTargetDisplay(screen_,
                                                          *bounds_in_screen);
-    *bounds_in_screen = ash::WindowPositioner::GetDefaultWindowBounds(display);
+    *bounds_in_screen = GetDefaultWindowBoundsAsh(display);
   }
 
   if (browser_->is_session_restore()) {
@@ -114,3 +114,22 @@
       browser_window, is_saved_bounds, passed_show_state, bounds_in_screen,
       show_state);
 }
+
+gfx::Rect WindowSizer::GetDefaultWindowBoundsAsh(
+    const display::Display& display) {
+  const gfx::Rect work_area = display.work_area();
+  // There should be a 'desktop' border around the window at the left and right
+  // side.
+  int default_width = work_area.width() - 2 * kDesktopBorderSize;
+  // There should also be a 'desktop' border around the window at the top.
+  // Since the workspace excludes the tray area we only need one border size.
+  int default_height = work_area.height() - kDesktopBorderSize;
+  int offset_x = kDesktopBorderSize;
+  if (default_width > kMaximumWindowWidth) {
+    // The window should get centered on the screen and not follow the grid.
+    offset_x = (work_area.width() - kMaximumWindowWidth) / 2;
+    default_width = kMaximumWindowWidth;
+  }
+  return gfx::Rect(work_area.x() + offset_x, work_area.y() + kDesktopBorderSize,
+                   default_width, default_height);
+}
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
index 07dc88d3..3102492b 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
@@ -30,6 +30,10 @@
 
 namespace {
 
+// Shorten identifiers to improve line wrapping.
+const int kDesktopBorderSize = WindowSizer::kDesktopBorderSize;
+const int kMaximumWindowWidth = WindowSizer::kMaximumWindowWidth;
+
 std::unique_ptr<Browser> CreateTestBrowser(aura::Window* window,
                                            const gfx::Rect& bounds,
                                            Browser::CreateParams* params) {
@@ -54,11 +58,10 @@
     gfx::Rect window_bounds;
     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(),
                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
-    EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
-                        768 - ash::WindowPositioner::kDesktopBorderSize),
-              window_bounds);
+    EXPECT_EQ(
+        gfx::Rect(kDesktopBorderSize, kDesktopBorderSize,
+                  1024 - kDesktopBorderSize * 2, 768 - kDesktopBorderSize),
+        window_bounds);
   }
 
   { // 4:3 monitor case, 1024x768, taskbar on bottom
@@ -66,11 +69,9 @@
     GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(),
                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
                     &window_bounds);
-    EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
-                        taskbar_bottom_work_area.height() -
-                          ash::WindowPositioner::kDesktopBorderSize),
+    EXPECT_EQ(gfx::Rect(kDesktopBorderSize, kDesktopBorderSize,
+                        1024 - kDesktopBorderSize * 2,
+                        taskbar_bottom_work_area.height() - kDesktopBorderSize),
               window_bounds);
   }
 
@@ -79,12 +80,11 @@
     GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(),
                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
                     &window_bounds);
-    EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        taskbar_right_work_area.width() -
-                          ash::WindowPositioner::kDesktopBorderSize * 2,
-                        768 - ash::WindowPositioner::kDesktopBorderSize),
-              window_bounds);
+    EXPECT_EQ(
+        gfx::Rect(kDesktopBorderSize, kDesktopBorderSize,
+                  taskbar_right_work_area.width() - kDesktopBorderSize * 2,
+                  768 - kDesktopBorderSize),
+        window_bounds);
   }
 
   { // 4:3 monitor case, 1024x768, taskbar on left
@@ -92,13 +92,10 @@
     GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(),
                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
                     &window_bounds);
-    EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() +
-                          ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        taskbar_left_work_area.width() -
-                          ash::WindowPositioner::kDesktopBorderSize * 2,
-                        taskbar_left_work_area.height() -
-                          ash::WindowPositioner::kDesktopBorderSize),
+    EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + kDesktopBorderSize,
+                        kDesktopBorderSize,
+                        taskbar_left_work_area.width() - kDesktopBorderSize * 2,
+                        taskbar_left_work_area.height() - kDesktopBorderSize),
               window_bounds);
   }
 
@@ -107,12 +104,10 @@
     GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(),
                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
                     &window_bounds);
-    EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                        taskbar_top_work_area.y() +
-                          ash::WindowPositioner::kDesktopBorderSize,
-                        1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
-                        taskbar_top_work_area.height() -
-                            ash::WindowPositioner::kDesktopBorderSize),
+    EXPECT_EQ(gfx::Rect(kDesktopBorderSize,
+                        taskbar_top_work_area.y() + kDesktopBorderSize,
+                        1024 - kDesktopBorderSize * 2,
+                        taskbar_top_work_area.height() - kDesktopBorderSize),
               window_bounds);
   }
 
@@ -120,10 +115,8 @@
     gfx::Rect window_bounds;
     GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(),
                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
-    EXPECT_EQ(gfx::Rect((1280 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kMaximumWindowWidth,
-                        1024 - ash::WindowPositioner::kDesktopBorderSize),
+    EXPECT_EQ(gfx::Rect((1280 - kMaximumWindowWidth) / 2, kDesktopBorderSize,
+                        kMaximumWindowWidth, 1024 - kDesktopBorderSize),
               window_bounds);
   }
 
@@ -131,10 +124,8 @@
     gfx::Rect window_bounds;
     GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(),
                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
-    EXPECT_EQ(gfx::Rect((1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kMaximumWindowWidth,
-                        1200 - ash::WindowPositioner::kDesktopBorderSize),
+    EXPECT_EQ(gfx::Rect((1600 - kMaximumWindowWidth) / 2, kDesktopBorderSize,
+                        kMaximumWindowWidth, 1200 - kDesktopBorderSize),
               window_bounds);
   }
 
@@ -142,10 +133,8 @@
     gfx::Rect window_bounds;
     GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(),
                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
-    EXPECT_EQ(gfx::Rect((1680 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kMaximumWindowWidth,
-                        1050 - ash::WindowPositioner::kDesktopBorderSize),
+    EXPECT_EQ(gfx::Rect((1680 - kMaximumWindowWidth) / 2, kDesktopBorderSize,
+                        kMaximumWindowWidth, 1050 - kDesktopBorderSize),
               window_bounds);
   }
 
@@ -153,10 +142,8 @@
     gfx::Rect window_bounds;
     GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(),
                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
-    EXPECT_EQ(gfx::Rect((1920 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kMaximumWindowWidth,
-                        1200 - ash::WindowPositioner::kDesktopBorderSize),
+    EXPECT_EQ(gfx::Rect((1920 - kMaximumWindowWidth) / 2, kDesktopBorderSize,
+                        kMaximumWindowWidth, 1200 - kDesktopBorderSize),
               window_bounds);
   }
 }
@@ -166,75 +153,61 @@
 TEST_F(WindowSizerAshTest, LastWindowBoundsCase) {
   { // normal, in the middle of the screen somewhere.
     gfx::Rect window_bounds;
-    GetWindowBounds(
-        p1024x768, p1024x768, gfx::Rect(),
-        gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                  ash::WindowPositioner::kDesktopBorderSize, 500, 400),
-        gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
-        &window_bounds);
-    EXPECT_EQ(
-        gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  500, 400).ToString(),
-        window_bounds.ToString());
+    GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
+                    gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400),
+                    gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
+                    &window_bounds);
+    EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize,
+                        kWindowTilePixels + kDesktopBorderSize, 500, 400)
+                  .ToString(),
+              window_bounds.ToString());
   }
 
   { // taskbar on top.
     gfx::Rect window_bounds;
-    GetWindowBounds(
-        p1024x768, taskbar_top_work_area, gfx::Rect(),
-        gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                  ash::WindowPositioner::kDesktopBorderSize, 500, 400),
-        gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
-        &window_bounds);
-    EXPECT_EQ(
-        gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  std::max(kWindowTilePixels +
-                           ash::WindowPositioner::kDesktopBorderSize,
-                           34 /* toolbar height */),
-                  500, 400).ToString(),
-        window_bounds.ToString());
+    GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(),
+                    gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400),
+                    gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
+                    &window_bounds);
+    EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize,
+                        std::max(kWindowTilePixels + kDesktopBorderSize,
+                                 34 /* toolbar height */),
+                        500, 400)
+                  .ToString(),
+              window_bounds.ToString());
   }
 
   { // Too small to satisify the minimum visibility condition.
     gfx::Rect window_bounds;
-    GetWindowBounds(
-        p1024x768, p1024x768, gfx::Rect(),
-        gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                  ash::WindowPositioner::kDesktopBorderSize, 29, 29),
-        gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
-        &window_bounds);
-    EXPECT_EQ(
-        gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  30 /* not 29 */,
-                  30 /* not 29 */).ToString(),
-        window_bounds.ToString());
+    GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
+                    gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 29, 29),
+                    gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
+                    &window_bounds);
+    EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize,
+                        kWindowTilePixels + kDesktopBorderSize, 30 /* not 29 */,
+                        30 /* not 29 */)
+                  .ToString(),
+              window_bounds.ToString());
   }
 
 
   { // Normal.
     gfx::Rect window_bounds;
-    GetWindowBounds(
-        p1024x768, p1024x768, gfx::Rect(),
-        gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                  ash::WindowPositioner::kDesktopBorderSize, 500, 400),
-        gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
-        &window_bounds);
-    EXPECT_EQ(
-        gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  500, 400).ToString(),
-        window_bounds.ToString());
+    GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
+                    gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400),
+                    gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
+                    &window_bounds);
+    EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize,
+                        kWindowTilePixels + kDesktopBorderSize, 500, 400)
+                  .ToString(),
+              window_bounds.ToString());
   }
 }
 
 // Test that the window opened is sized appropriately given persisted sizes.
 TEST_F(WindowSizerAshTest, PersistedBoundsCase) {
   { // normal, in the middle of the screen somewhere.
-    gfx::Rect initial_bounds(
-        ash::WindowPositioner::kDesktopBorderSize,
-        ash::WindowPositioner::kDesktopBorderSize, 500, 400);
+    gfx::Rect initial_bounds(kDesktopBorderSize, kDesktopBorderSize, 500, 400);
 
     gfx::Rect window_bounds;
     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds,
@@ -309,38 +282,27 @@
 
   { // width and height too small
     gfx::Rect window_bounds;
-    GetWindowBounds(
-        p1024x768, p1024x768, gfx::Rect(),
-        gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                  ash::WindowPositioner::kDesktopBorderSize, 29, 29),
-        gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
-    EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                        ash::WindowPositioner::kDesktopBorderSize,
-                        30 /* not 29 */, 30 /* not 29 */).ToString(),
+    GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
+                    gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 29, 29),
+                    gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
+    EXPECT_EQ(gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 30 /* not 29 */,
+                        30 /* not 29 */)
+                  .ToString(),
               window_bounds.ToString());
   }
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// The following unittests have different results on Mac/non-Mac because we
-// reposition windows aggressively on Mac.  The *WithAggressiveReposition tests
-// are run on Mac, and the *WithNonAggressiveRepositioning tests are run on
-// other platforms.
-
 TEST_F(WindowSizerAshTest, LastWindowOffscreenWithNonAggressiveRepositioning) {
   { // taskbar on left.
     gfx::Rect window_bounds;
-    GetWindowBounds(
-        p1024x768, taskbar_left_work_area, gfx::Rect(),
-        gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
-                  ash::WindowPositioner::kDesktopBorderSize, 500, 400),
-        gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
-        &window_bounds);
-    EXPECT_EQ(
-        gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
-                  500, 400).ToString(),
-        window_bounds.ToString());
+    GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(),
+                    gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400),
+                    gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
+                    &window_bounds);
+    EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize,
+                        kWindowTilePixels + kDesktopBorderSize, 500, 400)
+                  .ToString(),
+              window_bounds.ToString());
   }
 
   { // offset would put the new window offscreen at the bottom but the minimum
@@ -459,12 +421,11 @@
     // since that might get used if the resolution is too big.
     EXPECT_EQ(
         gfx::Rect(
-            std::max(ash::WindowPositioner::kDesktopBorderSize,
-                     (1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2),
-            ash::WindowPositioner::kDesktopBorderSize,
-            std::min(ash::WindowPositioner::kMaximumWindowWidth,
-                     1600 - 2 * ash::WindowPositioner::kDesktopBorderSize),
-            1200 - ash::WindowPositioner::kDesktopBorderSize).ToString(),
+            std::max(kDesktopBorderSize, (1600 - kMaximumWindowWidth) / 2),
+            kDesktopBorderSize,
+            std::min(kMaximumWindowWidth, 1600 - 2 * kDesktopBorderSize),
+            1200 - kDesktopBorderSize)
+            .ToString(),
         window_bounds.ToString());
   }
 }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn
index e3dcb7d..b9b8122 100644
--- a/chrome/browser/vr/BUILD.gn
+++ b/chrome/browser/vr/BUILD.gn
@@ -49,8 +49,6 @@
     "elements/exit_prompt.h",
     "elements/exit_prompt_texture.cc",
     "elements/exit_prompt_texture.h",
-    "elements/exit_warning_texture.cc",
-    "elements/exit_warning_texture.h",
     "elements/full_screen_rect.cc",
     "elements/full_screen_rect.h",
     "elements/grid.cc",
diff --git a/chrome/browser/vr/elements/audio_permission_prompt_texture.cc b/chrome/browser/vr/elements/audio_permission_prompt_texture.cc
index 21e486f..b443ed4 100644
--- a/chrome/browser/vr/elements/audio_permission_prompt_texture.cc
+++ b/chrome/browser/vr/elements/audio_permission_prompt_texture.cc
@@ -37,7 +37,7 @@
 
 constexpr float kButtonWidth = 0.162f;
 
-constexpr char kPreferredFontNameForButtons[] = "sans-serif.medium";
+constexpr char kPreferredFontNameForButtons[] = "sans-serif-medium";
 
 }  // namespace
 
diff --git a/chrome/browser/vr/elements/button.cc b/chrome/browser/vr/elements/button.cc
index 5d6b113..af69d92 100644
--- a/chrome/browser/vr/elements/button.cc
+++ b/chrome/browser/vr/elements/button.cc
@@ -29,7 +29,7 @@
   set_hit_testable(false);
 
   auto background = base::MakeUnique<Rect>();
-  background->set_type(kTypeButtonBackground);
+  background->SetType(kTypeButtonBackground);
   background->set_bubble_events(true);
   background->SetTransitionedProperties({TRANSFORM});
   background->set_hit_testable(false);
@@ -37,7 +37,7 @@
   AddChild(std::move(background));
 
   auto vector_icon = base::MakeUnique<VectorIcon>(512);
-  vector_icon->set_type(kTypeButtonForeground);
+  vector_icon->SetType(kTypeButtonForeground);
   vector_icon->SetIcon(icon);
   vector_icon->set_bubble_events(true);
   vector_icon->SetTransitionedProperties({TRANSFORM});
@@ -46,7 +46,7 @@
   AddChild(std::move(vector_icon));
 
   auto hit_plane = base::MakeUnique<InvisibleHitTarget>();
-  hit_plane->set_type(kTypeButtonHitTarget);
+  hit_plane->SetType(kTypeButtonHitTarget);
   hit_plane->set_bubble_events(true);
   hit_plane_ = hit_plane.get();
   foreground_->AddChild(std::move(hit_plane));
@@ -121,9 +121,9 @@
 }
 
 void Button::OnSetDrawPhase() {
-  background_->set_draw_phase(draw_phase());
-  foreground_->set_draw_phase(draw_phase());
-  hit_plane_->set_draw_phase(draw_phase());
+  background_->SetDrawPhase(draw_phase());
+  foreground_->SetDrawPhase(draw_phase());
+  hit_plane_->SetDrawPhase(draw_phase());
 }
 
 void Button::OnSetName() {
diff --git a/chrome/browser/vr/elements/button_unittest.cc b/chrome/browser/vr/elements/button_unittest.cc
index 7b3448a..c23676d 100644
--- a/chrome/browser/vr/elements/button_unittest.cc
+++ b/chrome/browser/vr/elements/button_unittest.cc
@@ -70,7 +70,7 @@
 
 TEST(Button, DrawPhasePropagatesToSubElements) {
   Button button(base::Callback<void()>(), vector_icons::kMicrophoneIcon);
-  button.set_draw_phase(kPhaseOverlayForeground);
+  button.SetDrawPhase(kPhaseOverlayForeground);
 
   for (auto& child : button.children()) {
     EXPECT_EQ(kPhaseOverlayForeground, child->draw_phase());
@@ -79,7 +79,7 @@
 
 TEST(Button, NamePropagatesToSubElements) {
   Button button(base::Callback<void()>(), vector_icons::kMicrophoneIcon);
-  button.set_name(kCloseButton);
+  button.SetName(kCloseButton);
 
   for (auto& child : button.children()) {
     EXPECT_EQ(child->owner_name_for_test(), kCloseButton);
diff --git a/chrome/browser/vr/elements/controller.cc b/chrome/browser/vr/elements/controller.cc
index 627f40f..ebf8c4da 100644
--- a/chrome/browser/vr/elements/controller.cc
+++ b/chrome/browser/vr/elements/controller.cc
@@ -43,7 +43,7 @@
 }  // namespace
 
 Controller::Controller() {
-  set_name(kController);
+  SetName(kController);
   set_hit_testable(false);
   SetVisible(true);
 }
diff --git a/chrome/browser/vr/elements/exit_warning_texture.cc b/chrome/browser/vr/elements/exit_warning_texture.cc
deleted file mode 100644
index 71c3469..0000000
--- a/chrome/browser/vr/elements/exit_warning_texture.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/vr/elements/exit_warning_texture.h"
-
-#include "cc/paint/skia_paint_canvas.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/vector_icons/vector_icons.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/font_list.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector2d.h"
-#include "ui/gfx/paint_vector_icon.h"
-#include "ui/gfx/render_text.h"
-#include "ui/gfx/vector_icon_types.h"
-
-namespace vr {
-
-namespace {
-
-constexpr float kBorderFactor = 0.045f;
-constexpr float kFontSizeFactor = 0.048f;
-constexpr float kTextWidthFactor = 1.0f - 3 * kBorderFactor;
-
-}  // namespace
-
-ExitWarningTexture::ExitWarningTexture() = default;
-
-ExitWarningTexture::~ExitWarningTexture() = default;
-
-void ExitWarningTexture::Draw(SkCanvas* sk_canvas,
-                              const gfx::Size& texture_size) {
-  cc::SkiaPaintCanvas paint_canvas(sk_canvas);
-  gfx::Canvas gfx_canvas(&paint_canvas, 1.0f);
-  gfx::Canvas* canvas = &gfx_canvas;
-
-  size_.set_width(texture_size.width());
-  SkPaint paint;
-
-  paint.setColor(background_color());
-  auto text = l10n_util::GetStringUTF16(IDS_VR_BROWSER_UNSUPPORTED_PAGE);
-  gfx::FontList fonts;
-  GetDefaultFontList(size_.width() * kFontSizeFactor, text, &fonts);
-  gfx::Rect text_size(size_.width() * kTextWidthFactor, 0);
-
-  std::vector<std::unique_ptr<gfx::RenderText>> lines =
-      PrepareDrawStringRect(text, fonts, foreground_color(), &text_size,
-                            kTextAlignmentCenter, kWrappingBehaviorWrap);
-
-  DCHECK_LE(text_size.height(),
-            static_cast<int>((1.0 - 2 * kBorderFactor) * size_.width()));
-  size_.set_height(size_.width() * 2 * kBorderFactor + text_size.height());
-  float radius = size_.height() * kBorderFactor;
-  sk_canvas->drawRoundRect(SkRect::MakeWH(size_.width(), size_.height()),
-                           radius, radius, paint);
-
-  canvas->Save();
-  canvas->Translate(gfx::Vector2d(size_.width() * kBorderFactor,
-                                  size_.width() * kBorderFactor));
-  for (auto& render_text : lines)
-    render_text->Draw(canvas);
-  canvas->Restore();
-}
-
-gfx::Size ExitWarningTexture::GetPreferredTextureSize(int maximum_width) const {
-  return gfx::Size(maximum_width, maximum_width);
-}
-
-gfx::SizeF ExitWarningTexture::GetDrawnSize() const {
-  return size_;
-}
-
-}  // namespace vr
diff --git a/chrome/browser/vr/elements/exit_warning_texture.h b/chrome/browser/vr/elements/exit_warning_texture.h
deleted file mode 100644
index 9c4d60e..0000000
--- a/chrome/browser/vr/elements/exit_warning_texture.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_VR_ELEMENTS_EXIT_WARNING_TEXTURE_H_
-#define CHROME_BROWSER_VR_ELEMENTS_EXIT_WARNING_TEXTURE_H_
-
-#include "base/macros.h"
-#include "chrome/browser/vr/elements/ui_texture.h"
-
-namespace vr {
-
-class ExitWarningTexture : public UiTexture {
- public:
-  ExitWarningTexture();
-  ~ExitWarningTexture() override;
-  gfx::Size GetPreferredTextureSize(int width) const override;
-  gfx::SizeF GetDrawnSize() const override;
-
- private:
-  void Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) override;
-
-  gfx::SizeF size_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExitWarningTexture);
-};
-
-}  // namespace vr
-
-#endif  // CHROME_BROWSER_VR_ELEMENTS_EXIT_WARNING_TEXTURE_H_
diff --git a/chrome/browser/vr/elements/keyboard.cc b/chrome/browser/vr/elements/keyboard.cc
index 01b6126..b88f3e9 100644
--- a/chrome/browser/vr/elements/keyboard.cc
+++ b/chrome/browser/vr/elements/keyboard.cc
@@ -11,7 +11,8 @@
 namespace vr {
 
 Keyboard::Keyboard() {
-  set_name(kKeyboard);
+  SetName(kKeyboard);
+  set_focusable(false);
   SetVisibleImmediately(false);
 }
 
@@ -66,6 +67,41 @@
   delegate_->SetTransform(LocalTransform());
 }
 
+void Keyboard::OnHoverEnter(const gfx::PointF& position) {
+  if (!delegate_)
+    return;
+
+  delegate_->OnHoverEnter(position);
+}
+
+void Keyboard::OnHoverLeave() {
+  if (!delegate_)
+    return;
+
+  delegate_->OnHoverLeave();
+}
+
+void Keyboard::OnMove(const gfx::PointF& position) {
+  if (!delegate_)
+    return;
+
+  delegate_->OnMove(position);
+}
+
+void Keyboard::OnButtonDown(const gfx::PointF& position) {
+  if (!delegate_)
+    return;
+
+  delegate_->OnButtonDown(position);
+}
+
+void Keyboard::OnButtonUp(const gfx::PointF& position) {
+  if (!delegate_)
+    return;
+
+  delegate_->OnButtonUp(position);
+}
+
 bool Keyboard::OnBeginFrame(const base::TimeTicks& time,
                             const gfx::Vector3dF& head_direction) {
   if (!delegate_)
@@ -86,6 +122,10 @@
   delegate_->Draw(camera_model);
 }
 
+void Keyboard::OnSetFocusable() {
+  DCHECK(!focusable());
+}
+
 void Keyboard::UpdateDelegateVisibility() {
   if (!delegate_)
     return;
diff --git a/chrome/browser/vr/elements/keyboard.h b/chrome/browser/vr/elements/keyboard.h
index a052730..0d50ea25 100644
--- a/chrome/browser/vr/elements/keyboard.h
+++ b/chrome/browser/vr/elements/keyboard.h
@@ -29,11 +29,18 @@
       int target_property_id,
       cc::Animation* animation) override;
 
+  void OnHoverEnter(const gfx::PointF& position) override;
+  void OnHoverLeave() override;
+  void OnMove(const gfx::PointF& position) override;
+  void OnButtonDown(const gfx::PointF& position) override;
+  void OnButtonUp(const gfx::PointF& position) override;
+
  private:
   bool OnBeginFrame(const base::TimeTicks& time,
                     const gfx::Vector3dF& head_direction) override;
   void Render(UiElementRenderer* renderer,
               const CameraModel& camera_model) const final;
+  void OnSetFocusable() override;
 
   void UpdateDelegateVisibility();
 
diff --git a/chrome/browser/vr/elements/laser.cc b/chrome/browser/vr/elements/laser.cc
index b349d0fc..1e427875 100644
--- a/chrome/browser/vr/elements/laser.cc
+++ b/chrome/browser/vr/elements/laser.cc
@@ -64,7 +64,7 @@
 }  // namespace
 
 Laser::Laser(Model* model) : model_(model) {
-  set_name(kLaser);
+  SetName(kLaser);
   set_hit_testable(false);
   SetVisible(true);
 }
diff --git a/chrome/browser/vr/elements/linear_layout_unittest.cc b/chrome/browser/vr/elements/linear_layout_unittest.cc
index 2d3d9ec..56e11f7 100644
--- a/chrome/browser/vr/elements/linear_layout_unittest.cc
+++ b/chrome/browser/vr/elements/linear_layout_unittest.cc
@@ -31,7 +31,6 @@
   auto element = base::MakeUnique<UiElement>();
   UiElement* rect_a = element.get();
   rect_a->SetSize(10, 10);
-  rect_a->SetVisible(true);
   layout.AddChild(std::move(element));
 
   // One element should require no position adjustment at all.
@@ -42,7 +41,6 @@
   element = base::MakeUnique<UiElement>();
   UiElement* rect_b = element.get();
   rect_b->SetSize(20, 20);
-  rect_b->SetVisible(true);
   layout.AddChild(std::move(element));
   layout.LayOutChildren();
 
@@ -74,7 +72,6 @@
     auto element = base::MakeUnique<TestElement>();
     rect = element.get();
     element->SetSize(10, 10);
-    element->SetVisible(true);
     layout.AddChild(std::move(element));
   }
 
@@ -108,23 +105,18 @@
   //     rect_c
   auto parent_layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown);
   UiElement* p_parent_layout = parent_layout.get();
-  parent_layout->SetVisible(true);
   auto child_layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown);
   UiElement* p_child_layout = child_layout.get();
-  child_layout->SetVisible(true);
   auto rect_a = base::MakeUnique<TestElement>();
   TestElement* p_rect_a = rect_a.get();
-  rect_a->SetVisible(true);
   rect_a->SetSize(10, 10);
   child_layout->AddChild(std::move(rect_a));
   auto rect_b = base::MakeUnique<TestElement>();
   TestElement* p_rect_b = rect_b.get();
-  rect_b->SetVisible(true);
   rect_b->SetSize(10, 10);
   child_layout->AddChild(std::move(rect_b));
   auto rect_c = base::MakeUnique<TestElement>();
   TestElement* p_rect_c = rect_c.get();
-  rect_c->SetVisible(true);
   rect_c->SetSize(999, 10);
   parent_layout->AddChild(std::move(child_layout));
   parent_layout->AddChild(std::move(rect_c));
diff --git a/chrome/browser/vr/elements/reticle.cc b/chrome/browser/vr/elements/reticle.cc
index e6ff51a..1f7e0cd 100644
--- a/chrome/browser/vr/elements/reticle.cc
+++ b/chrome/browser/vr/elements/reticle.cc
@@ -75,7 +75,7 @@
 }  // namespace
 
 Reticle::Reticle(UiScene* scene, Model* model) : scene_(scene), model_(model) {
-  set_name(kReticle);
+  SetName(kReticle);
   set_hit_testable(false);
   SetVisible(true);
 }
diff --git a/chrome/browser/vr/elements/scaled_depth_adjuster.cc b/chrome/browser/vr/elements/scaled_depth_adjuster.cc
index 28dc227..e106ae9 100644
--- a/chrome/browser/vr/elements/scaled_depth_adjuster.cc
+++ b/chrome/browser/vr/elements/scaled_depth_adjuster.cc
@@ -7,7 +7,7 @@
 namespace vr {
 
 ScaledDepthAdjuster::ScaledDepthAdjuster(float delta_z) : delta_z_(delta_z) {
-  set_type(kTypeScaledDepthAdjuster);
+  SetType(kTypeScaledDepthAdjuster);
   set_hit_testable(false);
 }
 
diff --git a/chrome/browser/vr/elements/simple_textured_element.h b/chrome/browser/vr/elements/simple_textured_element.h
index 43a9581..6408ec28 100644
--- a/chrome/browser/vr/elements/simple_textured_element.h
+++ b/chrome/browser/vr/elements/simple_textured_element.h
@@ -10,7 +10,6 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/vr/elements/exclusive_screen_toast_texture.h"
-#include "chrome/browser/vr/elements/exit_warning_texture.h"
 #include "chrome/browser/vr/elements/system_indicator_texture.h"
 #include "chrome/browser/vr/elements/textured_element.h"
 #include "chrome/browser/vr/elements/transient_element.h"
@@ -35,9 +34,6 @@
   DISALLOW_COPY_AND_ASSIGN(SimpleTexturedElement);
 };
 
-typedef SimpleTexturedElement<ExitWarningTexture,
-                              TexturedElement::ResizeVertically>
-    ExitWarning;
 typedef SimpleTexturedElement<ExclusiveScreenToastTexture,
                               TexturedElement::ResizeHorizontally>
     ExclusiveScreenToast;
diff --git a/chrome/browser/vr/elements/text.cc b/chrome/browser/vr/elements/text.cc
index c10f408..1a5b930 100644
--- a/chrome/browser/vr/elements/text.cc
+++ b/chrome/browser/vr/elements/text.cc
@@ -145,19 +145,21 @@
   GetDefaultFontList(pixel_font_height, text_, &fonts);
   gfx::Rect text_bounds(texture_size.width(), 0);
 
+  TextRenderParameters parameters;
+  parameters.color = color_;
+  parameters.text_alignment = alignment_;
+  parameters.wrapping_behavior =
+      multiline_ ? kWrappingBehaviorWrap : kWrappingBehaviorNoWrap;
+  parameters.cursor_enabled = cursor_enabled_;
+  parameters.cursor_position = cursor_position_;
+
   std::vector<std::unique_ptr<gfx::RenderText>> lines =
       // TODO(vollick): if this subsumes all text, then we should probably move
       // this function into this class.
-      PrepareDrawStringRect(
-          text_, fonts, color_, &text_bounds, alignment_,
-          multiline_ ? kWrappingBehaviorWrap : kWrappingBehaviorNoWrap);
+      PrepareDrawStringRect(text_, fonts, &text_bounds, parameters);
 
-  if (cursor_enabled_) {
-    DCHECK(!multiline_);
-    lines.front()->SetCursorEnabled(true);
-    lines.front()->SetCursorPosition(cursor_position_);
+  if (cursor_enabled_)
     cursor_bounds_ = lines.front()->GetUpdatedCursorBounds();
-  }
 
   // Note, there is no padding here whatsoever.
   size_ = gfx::SizeF(text_bounds.size());
diff --git a/chrome/browser/vr/elements/text_input.cc b/chrome/browser/vr/elements/text_input.cc
index ff1b685..eb7ef36 100644
--- a/chrome/browser/vr/elements/text_input.cc
+++ b/chrome/browser/vr/elements/text_input.cc
@@ -23,9 +23,10 @@
     : focus_changed_callback_(focus_changed_callback),
       input_edit_callback_(input_edit_callback) {
   auto text = base::MakeUnique<Text>(maximum_width_pixels, font_height_meters);
-  text->set_type(kTypeTextInputHint);
-  text->set_draw_phase(kPhaseForeground);
+  text->SetType(kTypeTextInputHint);
+  text->SetDrawPhase(kPhaseForeground);
   text->set_hit_testable(false);
+  text->set_focusable(false);
   text->set_x_anchoring(LEFT);
   text->set_x_centering(LEFT);
   text->SetSize(1, 1);
@@ -35,9 +36,10 @@
   this->AddChild(std::move(text));
 
   text = base::MakeUnique<Text>(maximum_width_pixels, font_height_meters);
-  text->set_type(kTypeTextInputText);
-  text->set_draw_phase(kPhaseForeground);
+  text->SetType(kTypeTextInputText);
+  text->SetDrawPhase(kPhaseForeground);
   text->set_hit_testable(true);
+  text->set_focusable(false);
   text->set_x_anchoring(LEFT);
   text->set_x_centering(LEFT);
   text->set_bubble_events(true);
@@ -50,9 +52,10 @@
 
   auto cursor = base::MakeUnique<Rect>();
   cursor->SetVisible(false);
-  cursor->set_type(kTypeTextInputCursor);
-  cursor->set_draw_phase(kPhaseForeground);
+  cursor->SetType(kTypeTextInputCursor);
+  cursor->SetDrawPhase(kPhaseForeground);
   cursor->set_hit_testable(false);
+  cursor->set_focusable(false);
   cursor->set_x_anchoring(LEFT);
   cursor->set_y_anchoring(BOTTOM);
   cursor->SetColor(SK_ColorBLUE);
@@ -68,10 +71,6 @@
   delegate_ = text_input_delegate;
 }
 
-bool TextInput::IsEditable() {
-  return true;
-}
-
 void TextInput::OnButtonUp(const gfx::PointF& position) {
   RequestFocus();
 }
@@ -94,6 +93,13 @@
   delegate_->RequestFocus(id());
 }
 
+void TextInput::RequestUnfocus() {
+  if (!delegate_)
+    return;
+
+  delegate_->RequestUnfocus(id());
+}
+
 void TextInput::SetHintText(const base::string16& text) {
   hint_element_->SetText(text);
 }
@@ -102,7 +108,9 @@
   input_edit_callback_.Run(info);
 }
 
-void TextInput::OnInputCommitted(const TextInputInfo& info) {}
+void TextInput::OnInputCommitted(const TextInputInfo& info) {
+  input_commit_callback_.Run(info);
+}
 
 void TextInput::SetTextColor(SkColor color) {
   text_element_->SetColor(color);
diff --git a/chrome/browser/vr/elements/text_input.h b/chrome/browser/vr/elements/text_input.h
index 68d0208..438af9f 100644
--- a/chrome/browser/vr/elements/text_input.h
+++ b/chrome/browser/vr/elements/text_input.h
@@ -25,19 +25,22 @@
   // Called when the user enters text while this element is focused.
   typedef base::RepeatingCallback<void(const TextInputInfo&)>
       OnInputEditedCallback;
+  // Called when the user commits text while this element is focused.
+  typedef base::RepeatingCallback<void(const TextInputInfo&)>
+      OnInputCommittedCallback;
   TextInput(int maximum_width_pixels,
             float font_height_meters,
             OnFocusChangedCallback focus_changed_callback,
             OnInputEditedCallback input_edit_callback);
   ~TextInput() override;
 
-  bool IsEditable() override;
   void OnButtonUp(const gfx::PointF& position) override;
   void OnFocusChanged(bool focused) override;
   void OnInputEdited(const TextInputInfo& info) override;
   void OnInputCommitted(const TextInputInfo& info) override;
 
   void RequestFocus();
+  void RequestUnfocus();
   void UpdateInput(const TextInputInfo& info);
 
   void SetHintText(const base::string16& text);
@@ -46,6 +49,10 @@
   void SetHintColor(SkColor color);
   void SetTextInputDelegate(TextInputDelegate* text_input_delegate);
 
+  void set_input_committed_callback(const OnInputCommittedCallback& callback) {
+    input_commit_callback_ = callback;
+  }
+
   bool OnBeginFrame(const base::TimeTicks& time,
                     const gfx::Vector3dF& look_at) final;
   void OnSetSize(gfx::SizeF size) final;
@@ -61,6 +68,7 @@
 
   OnFocusChangedCallback focus_changed_callback_;
   OnInputEditedCallback input_edit_callback_;
+  OnInputEditedCallback input_commit_callback_;
   TextInputDelegate* delegate_ = nullptr;
   TextInputInfo text_info_;
   bool focused_ = false;
diff --git a/chrome/browser/vr/elements/ui_element.cc b/chrome/browser/vr/elements/ui_element.cc
index 39b56dd..4d49901 100644
--- a/chrome/browser/vr/elements/ui_element.cc
+++ b/chrome/browser/vr/elements/ui_element.cc
@@ -66,27 +66,34 @@
   animation_player_.set_target(nullptr);
 }
 
-void UiElement::set_name(UiElementName name) {
+void UiElement::SetName(UiElementName name) {
   name_ = name;
   OnSetName();
 }
 
 void UiElement::OnSetName() {}
 
-void UiElement::set_type(UiElementType type) {
+void UiElement::SetType(UiElementType type) {
   type_ = type;
   OnSetType();
 }
 
 void UiElement::OnSetType() {}
 
-void UiElement::set_draw_phase(DrawPhase draw_phase) {
+void UiElement::SetDrawPhase(DrawPhase draw_phase) {
   draw_phase_ = draw_phase;
   OnSetDrawPhase();
 }
 
 void UiElement::OnSetDrawPhase() {}
 
+void UiElement::set_focusable(bool focusable) {
+  focusable_ = focusable;
+  OnSetFocusable();
+}
+
+void UiElement::OnSetFocusable() {}
+
 void UiElement::Render(UiElementRenderer* renderer,
                        const CameraModel& model) const {
   // Elements without an overridden implementation of Render should have their
@@ -190,10 +197,6 @@
   return IsVisible() && hit_testable_;
 }
 
-bool UiElement::IsEditable() {
-  return false;
-}
-
 void UiElement::SetSize(float width, float height) {
   animation_player_.TransitionSizeTo(last_frame_time_, BOUNDS, size_,
                                      gfx::SizeF(width, height));
diff --git a/chrome/browser/vr/elements/ui_element.h b/chrome/browser/vr/elements/ui_element.h
index 34a2325..2fda3df 100644
--- a/chrome/browser/vr/elements/ui_element.h
+++ b/chrome/browser/vr/elements/ui_element.h
@@ -114,7 +114,7 @@
   };
 
   UiElementName name() const { return name_; }
-  void set_name(UiElementName name);
+  void SetName(UiElementName name);
   virtual void OnSetName();
 
   UiElementName owner_name_for_test() const { return owner_name_for_test_; }
@@ -123,11 +123,11 @@
   }
 
   UiElementType type() const { return type_; }
-  void set_type(UiElementType type);
+  void SetType(UiElementType type);
   virtual void OnSetType();
 
   DrawPhase draw_phase() const { return draw_phase_; }
-  void set_draw_phase(DrawPhase draw_phase);
+  void SetDrawPhase(DrawPhase draw_phase);
   virtual void OnSetDrawPhase();
 
   // Returns true if the element needs to be re-drawn.
@@ -140,10 +140,6 @@
   // Indicates whether the element should be tested for cursor input.
   bool IsHitTestable() const;
 
-  // Indicates whether the element is an editable element. Editable elements
-  // such as the input field should override this.
-  virtual bool IsEditable();
-
   virtual void Render(UiElementRenderer* renderer,
                       const CameraModel& model) const;
 
@@ -201,6 +197,10 @@
   bool hit_testable() const { return hit_testable_; }
   void set_hit_testable(bool hit_testable) { hit_testable_ = hit_testable; }
 
+  bool focusable() const { return focusable_; }
+  void set_focusable(bool focusable);
+  virtual void OnSetFocusable();
+
   bool scrollable() const { return scrollable_; }
   void set_scrollable(bool scrollable) { scrollable_ = scrollable; }
 
@@ -430,6 +430,9 @@
   // If false, the reticle will not hit the element, even if visible.
   bool hit_testable_ = true;
 
+  // If false, clicking on the element doesn't give it focus.
+  bool focusable_ = true;
+
   // A signal to the input routing machinery that this element accepts scrolls.
   bool scrollable_ = false;
 
diff --git a/chrome/browser/vr/elements/ui_element_iterator_unittest.cc b/chrome/browser/vr/elements/ui_element_iterator_unittest.cc
index eb18848..a23d7ff 100644
--- a/chrome/browser/vr/elements/ui_element_iterator_unittest.cc
+++ b/chrome/browser/vr/elements/ui_element_iterator_unittest.cc
@@ -24,31 +24,31 @@
 //     8 kCeiling
 void MakeTree(UiScene* scene) {
   auto element = base::MakeUnique<UiElement>();
-  element->set_name(k2dBrowsingRoot);
+  element->SetName(k2dBrowsingRoot);
   scene->AddUiElement(kRoot, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(kFloor);
+  element->SetName(kFloor);
   scene->AddUiElement(k2dBrowsingRoot, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(k2dBrowsingContentGroup);
+  element->SetName(k2dBrowsingContentGroup);
   scene->AddUiElement(k2dBrowsingRoot, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(kBackplane);
+  element->SetName(kBackplane);
   scene->AddUiElement(k2dBrowsingContentGroup, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(kContentQuad);
+  element->SetName(kContentQuad);
   scene->AddUiElement(k2dBrowsingContentGroup, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(kUrlBar);
+  element->SetName(kUrlBar);
   scene->AddUiElement(k2dBrowsingContentGroup, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(kCeiling);
+  element->SetName(kCeiling);
   scene->AddUiElement(k2dBrowsingRoot, std::move(element));
 }
 
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc
index 283dde5..b1368d4b 100644
--- a/chrome/browser/vr/elements/ui_element_name.cc
+++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -52,7 +52,8 @@
     "kCloseButton",
     "kVoiceSearchButton",
     "kScreenDimmer",
-    "kExitWarning",
+    "kExitWarningText",
+    "kExitWarningBackground",
     "kExitPrompt",
     "kExitPromptBackplane",
     "kAudioPermissionPrompt",
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h
index 96c4906..f95d98ba 100644
--- a/chrome/browser/vr/elements/ui_element_name.h
+++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -51,7 +51,8 @@
   kCloseButton,
   kVoiceSearchButton,
   kScreenDimmer,
-  kExitWarning,
+  kExitWarningText,
+  kExitWarningBackground,
   kExitPrompt,
   kExitPromptBackplane,
   kAudioPermissionPrompt,
diff --git a/chrome/browser/vr/elements/ui_texture.cc b/chrome/browser/vr/elements/ui_texture.cc
index a426b79..25ae33b7 100644
--- a/chrome/browser/vr/elements/ui_texture.cc
+++ b/chrome/browser/vr/elements/ui_texture.cc
@@ -66,11 +66,25 @@
     gfx::Rect* bounds,
     UiTexture::TextAlignment text_alignment,
     UiTexture::WrappingBehavior wrapping_behavior) {
+  TextRenderParameters parameters;
+  parameters.color = color;
+  parameters.text_alignment = text_alignment;
+  parameters.wrapping_behavior = wrapping_behavior;
+  return PrepareDrawStringRect(text, font_list, bounds, parameters);
+}
+
+std::vector<std::unique_ptr<gfx::RenderText>> UiTexture::PrepareDrawStringRect(
+    const base::string16& text,
+    const gfx::FontList& font_list,
+    gfx::Rect* bounds,
+    const TextRenderParameters& parameters) {
   DCHECK(bounds);
 
   std::vector<std::unique_ptr<gfx::RenderText>> lines;
 
-  if (wrapping_behavior == kWrappingBehaviorWrap) {
+  if (parameters.wrapping_behavior == kWrappingBehaviorWrap) {
+    DCHECK(!parameters.cursor_enabled);
+
     gfx::Rect rect(*bounds);
     std::vector<base::string16> strings;
     gfx::ElideRectangleText(text, font_list, bounds->width(),
@@ -81,7 +95,7 @@
     int line_height = 0;
     for (size_t i = 0; i < strings.size(); i++) {
       std::unique_ptr<gfx::RenderText> render_text = CreateConfiguredRenderText(
-          strings[i], font_list, color, text_alignment);
+          strings[i], font_list, parameters.color, parameters.text_alignment);
 
       if (i == 0) {
         // Measure line and center text vertically.
@@ -104,10 +118,14 @@
       bounds->set_height(height);
 
   } else {
-    std::unique_ptr<gfx::RenderText> render_text =
-        CreateConfiguredRenderText(text, font_list, color, text_alignment);
-    if (bounds->width() != 0)
+    std::unique_ptr<gfx::RenderText> render_text = CreateConfiguredRenderText(
+        text, font_list, parameters.color, parameters.text_alignment);
+    if (bounds->width() != 0 && !parameters.cursor_enabled)
       render_text->SetElideBehavior(gfx::TRUNCATE);
+    if (parameters.cursor_enabled) {
+      render_text->SetCursorEnabled(true);
+      render_text->SetCursorPosition(parameters.cursor_position);
+    }
 
     if (bounds->width() == 0)
       bounds->set_width(render_text->GetStringSize().width());
@@ -121,8 +139,7 @@
 }
 
 std::unique_ptr<gfx::RenderText> UiTexture::CreateRenderText() {
-  std::unique_ptr<gfx::RenderText> render_text(
-      gfx::RenderText::CreateInstance());
+  auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
 
   // Subpixel rendering is counterproductive when drawing VR textures.
   render_text->set_subpixel_rendering_suppressed(true);
diff --git a/chrome/browser/vr/elements/ui_texture.h b/chrome/browser/vr/elements/ui_texture.h
index bf5c55c..6f4eaacb 100644
--- a/chrome/browser/vr/elements/ui_texture.h
+++ b/chrome/browser/vr/elements/ui_texture.h
@@ -75,6 +75,14 @@
     kWrappingBehaviorNoWrap,
   };
 
+  struct TextRenderParameters {
+    SkColor color = SK_ColorBLACK;
+    TextAlignment text_alignment = kTextAlignmentNone;
+    WrappingBehavior wrapping_behavior = kWrappingBehaviorNoWrap;
+    bool cursor_enabled = false;
+    int cursor_position = 0;
+  };
+
  protected:
   virtual void Draw(SkCanvas* canvas, const gfx::Size& texture_size) = 0;
 
@@ -85,7 +93,7 @@
     *target = value;
   }
 
-  // Prepares a set of RenderText objects with the given color and fonts.
+  // Prepares a set of RenderText objects with the given parameters.
   // Attempts to fit the text within the provided size. |flags| specifies how
   // the text should be rendered. If multiline is requested and provided height
   // is 0, it will be set to the minimum needed to fit the whole text. If
@@ -94,6 +102,14 @@
   static std::vector<std::unique_ptr<gfx::RenderText>> PrepareDrawStringRect(
       const base::string16& text,
       const gfx::FontList& font_list,
+      gfx::Rect* bounds,
+      const TextRenderParameters& parameters);
+
+  // Deprecated legacy text prep function. UI elements that use this routine
+  // should migrate to use Text elements, rather than drawing text directly.
+  static std::vector<std::unique_ptr<gfx::RenderText>> PrepareDrawStringRect(
+      const base::string16& text,
+      const gfx::FontList& font_list,
       SkColor color,
       gfx::Rect* bounds,
       TextAlignment text_alignment,
diff --git a/chrome/browser/vr/elements/viewport_aware_root_unittest.cc b/chrome/browser/vr/elements/viewport_aware_root_unittest.cc
index e9ce469..ab6df2a 100644
--- a/chrome/browser/vr/elements/viewport_aware_root_unittest.cc
+++ b/chrome/browser/vr/elements/viewport_aware_root_unittest.cc
@@ -68,12 +68,12 @@
   void SetUp() override {
     scene_ = base::MakeUnique<UiScene>();
     auto viewport_aware_root = base::MakeUnique<ViewportAwareRootForTesting>();
-    viewport_aware_root->set_draw_phase(kPhaseForeground);
+    viewport_aware_root->SetDrawPhase(kPhaseForeground);
     viewport_root = viewport_aware_root.get();
     scene_->AddUiElement(kRoot, std::move(viewport_aware_root));
 
     auto element = base::MakeUnique<UiElement>();
-    element->set_draw_phase(kPhaseForeground);
+    element->SetDrawPhase(kPhaseForeground);
     element->SetTranslate(0.f, 0.f, -1.f);
     viewport_element = element.get();
     viewport_root->AddChild(std::move(element));
@@ -223,16 +223,16 @@
 
 TEST_F(ViewportAwareRootTest, IsChildrenVisible) {
   auto element = base::MakeUnique<UiElement>();
-  element->set_draw_phase(kPhaseNone);
+  element->SetDrawPhase(kPhaseNone);
   UiElement* child = element.get();
   viewport_element->AddChild(std::move(element));
-  viewport_element->set_draw_phase(kPhaseNone);
+  viewport_element->SetDrawPhase(kPhaseNone);
   // root
   //   viewport_element  -> no draw, visible
   //     child           -> no draw, visible
   EXPECT_FALSE(viewport_root->HasVisibleChildren());
 
-  child->set_draw_phase(kPhaseForeground);
+  child->SetDrawPhase(kPhaseForeground);
   // root
   //   viewport_element  -> no draw, visible
   //     child           -> drawable, visible
@@ -246,13 +246,13 @@
   EXPECT_FALSE(viewport_root->HasVisibleChildren());
 
   child->SetVisibleImmediately(true);
-  viewport_element->set_draw_phase(kPhaseForeground);
+  viewport_element->SetDrawPhase(kPhaseForeground);
   // root
   //   viewport_element  -> drawable, visible
   //     child           -> drawable, visible
   EXPECT_TRUE(viewport_root->HasVisibleChildren());
 
-  viewport_element->set_draw_phase(kPhaseForeground);
+  viewport_element->SetDrawPhase(kPhaseForeground);
   viewport_element->SetVisibleImmediately(false);
   // root
   //   viewport_element  -> drawable, invisible
diff --git a/chrome/browser/vr/keyboard_delegate.h b/chrome/browser/vr/keyboard_delegate.h
index b2ccf9f0..ac06f1d 100644
--- a/chrome/browser/vr/keyboard_delegate.h
+++ b/chrome/browser/vr/keyboard_delegate.h
@@ -9,6 +9,7 @@
 
 namespace gfx {
 class Point3F;
+class PointF;
 class Transform;
 }  // namespace gfx
 
@@ -28,6 +29,12 @@
                        gfx::Point3F* hit_position) = 0;
   virtual void OnBeginFrame() {}
   virtual void Draw(const CameraModel&) = 0;
+
+  virtual void OnHoverEnter(const gfx::PointF& position) {}
+  virtual void OnHoverLeave() {}
+  virtual void OnMove(const gfx::PointF& position) {}
+  virtual void OnButtonDown(const gfx::PointF& position) {}
+  virtual void OnButtonUp(const gfx::PointF& position) {}
 };
 
 }  // namespace vr
diff --git a/chrome/browser/vr/model/omnibox_suggestions.h b/chrome/browser/vr/model/omnibox_suggestions.h
index 7cf3de4..6c81554b 100644
--- a/chrome/browser/vr/model/omnibox_suggestions.h
+++ b/chrome/browser/vr/model/omnibox_suggestions.h
@@ -31,6 +31,19 @@
   std::vector<OmniboxSuggestion> suggestions;
 };
 
+// This struct represents the current request to the AutocompleteController.
+struct AutocompleteStatus {
+  bool active = false;
+  base::string16 input;
+
+  bool operator==(const AutocompleteStatus& other) const {
+    return active == other.active && input == other.input;
+  }
+  bool operator!=(const AutocompleteStatus& other) const {
+    return !(*this == other);
+  }
+};
+
 }  // namespace vr
 
 #endif  // CHROME_BROWSER_VR_MODEL_OMNIBOX_SUGGESTIONS_H_
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc
index 8f1b939..0e977af 100644
--- a/chrome/browser/vr/testapp/vr_test_context.cc
+++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -102,6 +102,8 @@
 
   text_input_delegate_->SetRequestFocusCallback(
       base::BindRepeating(&vr::Ui::RequestFocus, base::Unretained(ui_.get())));
+  text_input_delegate_->SetRequestUnfocusCallback(base::BindRepeating(
+      &vr::Ui::RequestUnfocus, base::Unretained(ui_.get())));
   text_input_delegate_->SetUpdateInputCallback(
       base::BindRepeating(&TestKeyboardDelegate::UpdateInput,
                           base::Unretained(keyboard_delegate_.get())));
@@ -171,9 +173,6 @@
         incognito_ = !incognito_;
         ui_->SetIncognito(incognito_);
         break;
-      case ui::DomCode::US_O:
-        CreateFakeOmniboxSuggestions();
-        break;
       case ui::DomCode::US_D:
         ui_->Dump();
         break;
@@ -190,9 +189,16 @@
         ui_->OnWebVrFrameAvailable();
         break;
       case ui::DomCode::US_A: {
-        CreateFakeTextInput();
+        CreateFakeTextInputOrCommit(false);
         break;
       }
+      case ui::DomCode::ENTER: {
+        CreateFakeTextInputOrCommit(true);
+        break;
+      }
+      case ui::DomCode::US_E:
+        model_->exiting_vr = !model_->exiting_vr;
+        break;
       default:
         break;
     }
@@ -351,38 +357,23 @@
   return texture_id;
 }
 
-void VrTestContext::CreateFakeTextInput() {
+void VrTestContext::CreateFakeTextInputOrCommit(bool commit) {
   // Every time this method is called, change the number of suggestions shown.
   const std::string text =
       "what is the actual meaning of life when considering all factors";
 
   static int len = 0;
-  len = (len + 1) % text.size();
+  if (!commit)
+    len = (len + 1) % text.size();
 
   TextInputInfo info;
   info.text = base::UTF8ToUTF16(text.substr(0, len));
   info.selection_start = len;
   info.selection_end = len;
-  ui_->OnInputEdited(info);
-}
-
-void VrTestContext::CreateFakeOmniboxSuggestions() {
-  // Every time this method is called, change the number of suggestions shown.
-  static int num_suggestions = 0;
-
-  auto result = base::MakeUnique<OmniboxSuggestions>();
-  for (int i = 0; i < num_suggestions; i++) {
-    result->suggestions.emplace_back(OmniboxSuggestion(
-        base::UTF8ToUTF16("Suggestion ") + base::IntToString16(i + 1),
-        base::UTF8ToUTF16(
-            "Very lengthy description of the suggestion that would wrap "
-            "if not truncated through some other means."),
-        AutocompleteMatch::Type::VOICE_SUGGEST, GURL("http://www.test.com/")));
-  }
-  ui_->SetOmniboxSuggestions(std::move(result));
-
-  num_suggestions++;
-  num_suggestions %= 5;
+  if (commit)
+    ui_->OnInputCommitted(info);
+  else
+    ui_->OnInputEdited(info);
 }
 
 void VrTestContext::CreateFakeVoiceSearchResult() {
@@ -476,7 +467,22 @@
 }
 
 void VrTestContext::OnContentScreenBoundsChanged(const gfx::SizeF& bounds) {}
-void VrTestContext::StartAutocomplete(const base::string16& string) {}
-void VrTestContext::StopAutocomplete() {}
+
+void VrTestContext::StartAutocomplete(const base::string16& string) {
+  auto result = base::MakeUnique<OmniboxSuggestions>();
+  for (int i = 0; i < 5; i++) {
+    result->suggestions.emplace_back(OmniboxSuggestion(
+        base::UTF8ToUTF16("Suggestion ") + base::IntToString16(i + 1),
+        base::UTF8ToUTF16(
+            "Very lengthy description of the suggestion that would wrap "
+            "if not truncated through some other means."),
+        AutocompleteMatch::Type::VOICE_SUGGEST, GURL("http://www.test.com/")));
+  }
+  ui_->SetOmniboxSuggestions(std::move(result));
+}
+
+void VrTestContext::StopAutocomplete() {
+  ui_->SetOmniboxSuggestions(base::MakeUnique<OmniboxSuggestions>());
+}
 
 }  // namespace vr
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h
index 3ae5024..daf3040 100644
--- a/chrome/browser/vr/testapp/vr_test_context.h
+++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -58,7 +58,7 @@
   unsigned int CreateFakeContentTexture();
   void CreateFakeOmniboxSuggestions();
   void CreateFakeVoiceSearchResult();
-  void CreateFakeTextInput();
+  void CreateFakeTextInputOrCommit(bool commit);
   void CycleWebVrModes();
   void ToggleSplashScreen();
   gfx::Transform ProjectionMatrix() const;
diff --git a/chrome/browser/vr/text_input_delegate.cc b/chrome/browser/vr/text_input_delegate.cc
index b293d2e..6193017 100644
--- a/chrome/browser/vr/text_input_delegate.cc
+++ b/chrome/browser/vr/text_input_delegate.cc
@@ -16,6 +16,11 @@
   request_focus_callback_ = callback;
 }
 
+void TextInputDelegate::SetRequestUnfocusCallback(
+    const RequestUnfocusCallback& callback) {
+  request_unfocus_callback_ = callback;
+}
+
 void TextInputDelegate::SetUpdateInputCallback(
     const UpdateInputCallback& callback) {
   update_input_callback_ = callback;
@@ -26,6 +31,11 @@
     request_focus_callback_.Run(element_id);
 }
 
+void TextInputDelegate::RequestUnfocus(int element_id) {
+  if (!request_unfocus_callback_.is_null())
+    request_unfocus_callback_.Run(element_id);
+}
+
 void TextInputDelegate::UpdateInput(const vr::TextInputInfo& info) {
   if (!update_input_callback_.is_null())
     update_input_callback_.Run(info);
diff --git a/chrome/browser/vr/text_input_delegate.h b/chrome/browser/vr/text_input_delegate.h
index 001f386c6..bdcccf6 100644
--- a/chrome/browser/vr/text_input_delegate.h
+++ b/chrome/browser/vr/text_input_delegate.h
@@ -17,21 +17,26 @@
   TextInputDelegate();
   virtual ~TextInputDelegate();
 
-  // RequestFocusCallback gets called when an element request's focus.
+  // RequestFocusCallback gets called when an element requests focus.
   typedef base::RepeatingCallback<void(int)> RequestFocusCallback;
+  // RequestUnfocusCallback gets called when an element requests unfocus.
+  typedef base::RepeatingCallback<void(int)> RequestUnfocusCallback;
   // UpdateInputCallback gets called when the text input info changes for the
   // element being edited.
   typedef base::RepeatingCallback<void(const TextInputInfo&)>
       UpdateInputCallback;
 
   void SetRequestFocusCallback(const RequestFocusCallback& callback);
+  void SetRequestUnfocusCallback(const RequestUnfocusCallback& callback);
   void SetUpdateInputCallback(const UpdateInputCallback& callback);
 
   virtual void RequestFocus(int element_id);
+  virtual void RequestUnfocus(int element_id);
   virtual void UpdateInput(const TextInputInfo& info);
 
  private:
   RequestFocusCallback request_focus_callback_;
+  RequestUnfocusCallback request_unfocus_callback_;
   UpdateInputCallback update_input_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(TextInputDelegate);
diff --git a/chrome/browser/vr/text_input_unittest.cc b/chrome/browser/vr/text_input_unittest.cc
index 4ace6ef9..a97fbf7 100644
--- a/chrome/browser/vr/text_input_unittest.cc
+++ b/chrome/browser/vr/text_input_unittest.cc
@@ -57,6 +57,11 @@
                bool(const gfx::Point3F&, const gfx::Point3F&, gfx::Point3F*));
   MOCK_METHOD0(OnBeginFrame, void());
   MOCK_METHOD1(Draw, void(const CameraModel&));
+  MOCK_METHOD1(OnHoverEnter, void(const gfx::PointF&));
+  MOCK_METHOD0(OnHoverLeave, void());
+  MOCK_METHOD1(OnMove, void(const gfx::PointF&));
+  MOCK_METHOD1(OnButtonDown, void(const gfx::PointF&));
+  MOCK_METHOD1(OnButtonUp, void(const gfx::PointF&));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockKeyboardDelegate);
@@ -138,13 +143,33 @@
   text_input_->get_text_element()->OnButtonUp({0, 0});
 }
 
+TEST(TextInputTest, ControllerInteractionsSentToDelegate) {
+  auto keyboard = base::MakeUnique<Keyboard>();
+  auto kb_delegate = base::MakeUnique<StrictMock<MockKeyboardDelegate>>();
+  testing::Sequence s;
+  EXPECT_CALL(*kb_delegate, HideKeyboard()).InSequence(s);
+  keyboard->SetKeyboardDelegate(kb_delegate.get());
+
+  EXPECT_CALL(*kb_delegate, OnHoverEnter(_)).InSequence(s);
+  EXPECT_CALL(*kb_delegate, OnHoverLeave()).InSequence(s);
+  EXPECT_CALL(*kb_delegate, OnMove(_)).InSequence(s);
+  EXPECT_CALL(*kb_delegate, OnButtonDown(_)).InSequence(s);
+  EXPECT_CALL(*kb_delegate, OnButtonUp(_)).InSequence(s);
+  gfx::PointF p;
+  keyboard->OnHoverEnter(p);
+  keyboard->OnHoverLeave();
+  keyboard->OnMove(p);
+  keyboard->OnButtonDown(p);
+  keyboard->OnButtonUp(p);
+}
+
 TEST(TextInputTest, HintText) {
   UiScene scene;
 
   auto instance =
       base::MakeUnique<TextInput>(512, 10, TextInput::OnFocusChangedCallback(),
                                   TextInput::OnInputEditedCallback());
-  instance->set_name(kOmniboxTextField);
+  instance->SetName(kOmniboxTextField);
   instance->SetSize(1, 0);
   TextInput* element = instance.get();
   scene.root_element().AddChild(std::move(instance));
@@ -167,7 +192,7 @@
   auto instance =
       base::MakeUnique<TextInput>(512, 10, TextInput::OnFocusChangedCallback(),
                                   TextInput::OnInputEditedCallback());
-  instance->set_name(kOmniboxTextField);
+  instance->SetName(kOmniboxTextField);
   instance->SetSize(1, 0);
   TextInput* element = instance.get();
   scene.root_element().AddChild(std::move(instance));
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc
index 7a3c296..57243f4 100644
--- a/chrome/browser/vr/ui.cc
+++ b/chrome/browser/vr/ui.cc
@@ -197,6 +197,10 @@
   input_manager_->RequestFocus(element_id);
 }
 
+void Ui::RequestUnfocus(int element_id) {
+  input_manager_->RequestUnfocus(element_id);
+}
+
 void Ui::OnInputEdited(const TextInputInfo& info) {
   input_manager_->OnInputEdited(info);
 }
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h
index d0f2ed4..4e2615e1 100644
--- a/chrome/browser/vr/ui.h
+++ b/chrome/browser/vr/ui.h
@@ -115,6 +115,7 @@
 
   // Keyboard input related.
   void RequestFocus(int element_id);
+  void RequestUnfocus(int element_id);
   void OnInputEdited(const TextInputInfo& info) override;
   void OnInputCommitted(const TextInputInfo& info) override;
   void OnKeyboardHidden() override;
diff --git a/chrome/browser/vr/ui_input_manager.cc b/chrome/browser/vr/ui_input_manager.cc
index 7a883b4..256a4ead 100644
--- a/chrome/browser/vr/ui_input_manager.cc
+++ b/chrome/browser/vr/ui_input_manager.cc
@@ -326,7 +326,7 @@
     // Clicking outside of the focused element causes it to lose focus.
     // TODO(ymalik): We will lose focus if we hit an element inside the focused
     // element, which is incorrect behavior.
-    if (target->id() != focused_element_id_ && target->name() != kKeyboard) {
+    if (target->id() != focused_element_id_ && target->focusable()) {
       UnfocusFocusedElement();
     }
   } else {
@@ -433,10 +433,10 @@
     return;
 
   UiElement* focused = scene_->GetUiElementById(focused_element_id_);
-  if (focused && focused->IsEditable()) {
+  if (focused && focused->focusable()) {
     focused->OnFocusChanged(false);
   }
-  focused_element_id_ = -1;
+  focused_element_id_ = 0;
 }
 
 void UiInputManager::RequestFocus(int element_id) {
@@ -446,24 +446,33 @@
   UnfocusFocusedElement();
 
   UiElement* focused = scene_->GetUiElementById(element_id);
-  if (!focused || !focused->IsEditable())
+  if (!focused || !focused->focusable())
     return;
 
   focused_element_id_ = element_id;
   focused->OnFocusChanged(true);
 }
 
+void UiInputManager::RequestUnfocus(int element_id) {
+  if (element_id != focused_element_id_)
+    return;
+
+  UnfocusFocusedElement();
+}
+
 void UiInputManager::OnInputEdited(const TextInputInfo& info) {
   UiElement* focused = scene_->GetUiElementById(focused_element_id_);
-  if (!focused || !focused->IsEditable())
+  if (!focused)
     return;
+  DCHECK(focused->focusable());
   focused->OnInputEdited(info);
 }
 
 void UiInputManager::OnInputCommitted(const TextInputInfo& info) {
   UiElement* focused = scene_->GetUiElementById(focused_element_id_);
-  if (!focused || !focused->IsEditable())
+  if (!focused || !focused->focusable())
     return;
+  DCHECK(focused->focusable());
   focused->OnInputCommitted(info);
 }
 
diff --git a/chrome/browser/vr/ui_input_manager.h b/chrome/browser/vr/ui_input_manager.h
index 8fb3578..c277ebf 100644
--- a/chrome/browser/vr/ui_input_manager.h
+++ b/chrome/browser/vr/ui_input_manager.h
@@ -58,6 +58,7 @@
 
   // Text input related.
   void RequestFocus(int element_id);
+  void RequestUnfocus(int element_id);
   void OnInputEdited(const TextInputInfo& info);
   void OnInputCommitted(const TextInputInfo& info);
   void OnKeyboardHidden();
diff --git a/chrome/browser/vr/ui_input_manager_unittest.cc b/chrome/browser/vr/ui_input_manager_unittest.cc
index c8ccd58d..5ed7a12 100644
--- a/chrome/browser/vr/ui_input_manager_unittest.cc
+++ b/chrome/browser/vr/ui_input_manager_unittest.cc
@@ -47,6 +47,9 @@
   MOCK_METHOD1(OnMove, void(const gfx::PointF& position));
   MOCK_METHOD1(OnButtonDown, void(const gfx::PointF& position));
   MOCK_METHOD1(OnButtonUp, void(const gfx::PointF& position));
+  MOCK_METHOD1(OnFocusChanged, void(bool));
+  MOCK_METHOD1(OnInputEdited, void(const TextInputInfo&));
+  MOCK_METHOD1(OnInputCommitted, void(const TextInputInfo&));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockRect);
@@ -76,21 +79,19 @@
     input_manager_ = base::MakeUnique<UiInputManager>(scene_.get());
   }
 
-  StrictMock<MockRect>* CreateMockElement(float z_position) {
+  StrictMock<MockRect>* CreateAndAddMockElement(float z_position) {
     auto element = base::MakeUnique<StrictMock<MockRect>>();
     StrictMock<MockRect>* p_element = element.get();
     element->SetTranslate(0, 0, z_position);
-    element->SetVisible(true);
     scene_->AddUiElement(kRoot, std::move(element));
     scene_->OnBeginFrame(base::TimeTicks(), kForwardVector);
     return p_element;
   }
 
-  StrictMock<MockTextInput>* CreateMockInputElement(float z_position) {
+  StrictMock<MockTextInput>* CreateAndAddMockInputElement(float z_position) {
     auto element = base::MakeUnique<StrictMock<MockTextInput>>();
     StrictMock<MockTextInput>* p_element = element.get();
     element->SetTranslate(0, 0, z_position);
-    element->SetVisible(true);
     scene_->AddUiElement(kRoot, std::move(element));
     scene_->OnBeginFrame(base::TimeTicks(), kForwardVector);
     return p_element;
@@ -133,8 +134,8 @@
 };
 
 TEST_F(UiInputManagerTest, FocusedElement) {
-  StrictMock<MockTextInput>* p_element1 = CreateMockInputElement(-5.f);
-  StrictMock<MockTextInput>* p_element2 = CreateMockInputElement(-5.f);
+  StrictMock<MockTextInput>* p_element1 = CreateAndAddMockInputElement(-5.f);
+  StrictMock<MockTextInput>* p_element2 = CreateAndAddMockInputElement(-5.f);
   TextInputInfo edit(base::ASCIIToUTF16("asdfg"));
 
   // Focus request triggers OnFocusChanged.
@@ -156,11 +157,58 @@
   input_manager_->RequestFocus(p_element2->id());
 }
 
+// Verify that a focusable child clears focus off its parent. Note that the
+// child isn't any different from other elements in that it should also steal
+// focus from its parent.
+TEST_F(UiInputManagerTest, FocusableChildStealsFocus) {
+  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);
+
+  auto child = base::MakeUnique<StrictMock<MockRect>>();
+  auto* p_child = child.get();
+  child->set_hit_testable(true);
+  child->set_focusable(true);
+  p_element->AddChild(std::move(child));
+  scene_->OnBeginFrame(base::TimeTicks(), kForwardVector);
+
+  // Focus element.
+  testing::Sequence s;
+  EXPECT_CALL(*p_element, OnFocusChanged(true)).InSequence(s);
+  input_manager_->RequestFocus(p_element->id());
+
+  // Focus child.
+  EXPECT_CALL(*p_child, OnHoverEnter(_)).InSequence(s);
+  EXPECT_CALL(*p_child, OnButtonDown(_)).InSequence(s);
+  EXPECT_CALL(*p_element, OnFocusChanged(false)).InSequence(s);
+  HandleInput(kForwardVector, kDown);
+}
+
+// Verify that a non-focusable child does not clear focus off its parent.
+TEST_F(UiInputManagerTest, NonFocusableChildDoestNotStealFocus) {
+  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);
+
+  auto child = base::MakeUnique<StrictMock<MockRect>>();
+  auto* p_child = child.get();
+  child->set_hit_testable(true);
+  child->set_focusable(false);
+  p_element->AddChild(std::move(child));
+  scene_->OnBeginFrame(base::TimeTicks(), kForwardVector);
+
+  // Focus element.
+  testing::Sequence s;
+  EXPECT_CALL(*p_element, OnFocusChanged(true)).InSequence(s);
+  input_manager_->RequestFocus(p_element->id());
+
+  // Focus child.
+  EXPECT_CALL(*p_child, OnHoverEnter(_)).InSequence(s);
+  EXPECT_CALL(*p_child, OnButtonDown(_)).InSequence(s);
+  EXPECT_CALL(*p_element, OnFocusChanged(false)).Times(0).InSequence(s);
+  HandleInput(kForwardVector, kDown);
+}
+
 TEST_F(UiInputManagerTest, ReticleRenderTarget) {
   auto element = base::MakeUnique<Rect>();
   UiElement* p_element = element.get();
   element->SetTranslate(0, 0, -1.f);
-  element->SetVisible(true);
   scene_->AddUiElement(kRoot, std::move(element));
   scene_->OnBeginFrame(base::TimeTicks(), kForwardVector);
 
@@ -186,7 +234,7 @@
 // either directly at (forward) or directly away from (backward) a test element.
 // Verify mock expectations along the way to make failures easier to track.
 TEST_F(UiInputManagerTest, HoverClick) {
-  StrictMock<MockRect>* p_element = CreateMockElement(-5.f);
+  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);
 
   // Move over the test element.
   EXPECT_CALL(*p_element, OnHoverEnter(_));
@@ -244,8 +292,8 @@
 // releasing the button. Upon release, the previous element should see its click
 // and hover states cleared, and the new element should see a hover.
 TEST_F(UiInputManagerTest, ReleaseButtonOnAnotherElement) {
-  StrictMock<MockRect>* p_front_element = CreateMockElement(-5.f);
-  StrictMock<MockRect>* p_back_element = CreateMockElement(5.f);
+  StrictMock<MockRect>* p_front_element = CreateAndAddMockElement(-5.f);
+  StrictMock<MockRect>* p_back_element = CreateAndAddMockElement(5.f);
 
   // Press on an element, move away, then release.
   EXPECT_CALL(*p_front_element, OnHoverEnter(_));
@@ -262,7 +310,7 @@
 
 // Test that input is tolerant of disappearing elements.
 TEST_F(UiInputManagerTest, ElementDeletion) {
-  StrictMock<MockRect>* p_element = CreateMockElement(-5.f);
+  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);
 
   // Hover on an element.
   EXPECT_CALL(*p_element, OnHoverEnter(_));
@@ -297,7 +345,6 @@
   auto element = base::MakeUnique<Rect>();
   auto* p_element = element.get();
   element->SetTranslate(0, 0, -2.5);
-  element->SetVisible(true);
   element->SetSize(1000.0f, 1000.0f);
   scene_->AddUiElement(kRoot, std::move(element));
   scene_->OnBeginFrame(base::TimeTicks(), kForwardVector);
diff --git a/chrome/browser/vr/ui_scene.cc b/chrome/browser/vr/ui_scene.cc
index aea044a..573d2e9 100644
--- a/chrome/browser/vr/ui_scene.cc
+++ b/chrome/browser/vr/ui_scene.cc
@@ -68,7 +68,7 @@
     }
     if (reticle_parent_id == element.id()) {
       elements.push_back(reticle);
-      reticle->set_draw_phase(element.draw_phase());
+      reticle->SetDrawPhase(element.draw_phase());
     }
   }
   return elements;
@@ -81,8 +81,11 @@
   CHECK_GE(element->id(), 0);
   CHECK_EQ(GetUiElementById(element->id()), nullptr);
   CHECK_GE(element->draw_phase(), 0);
-  if (gl_initialized_)
-    element->Initialize(provider_);
+  if (gl_initialized_) {
+    for (auto& child : *element) {
+      child.Initialize(provider_);
+    }
+  }
   GetUiElementByName(parent)->AddChild(std::move(element));
   is_dirty_ = true;
 }
@@ -256,7 +259,7 @@
             // included in a list of elements we vend. The other controller
             // elements are drawn in the foreground phase, so we will update the
             // reticle to match here.
-            reticle->set_draw_phase(kPhaseForeground);
+            reticle->SetDrawPhase(kPhaseForeground);
           }
           return need_to_add_reticle;
         }
@@ -283,9 +286,8 @@
 
 UiScene::UiScene() {
   root_element_ = base::MakeUnique<UiElement>();
-  root_element_->set_name(kRoot);
-  root_element_->set_draw_phase(kPhaseNone);
-  root_element_->SetVisible(true);
+  root_element_->SetName(kRoot);
+  root_element_->SetDrawPhase(kPhaseNone);
   root_element_->set_hit_testable(false);
 }
 
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h
index de982d6..4f13433 100644
--- a/chrome/browser/vr/ui_scene_constants.h
+++ b/chrome/browser/vr/ui_scene_constants.h
@@ -18,8 +18,11 @@
 static constexpr float kTransientWarningWidthDMM = 0.512f;
 
 static constexpr float kExitWarningDistance = 0.6f;
-static constexpr float kExitWarningHeight = 0.160f;
-static constexpr float kExitWarningWidth = 0.512f;
+static constexpr float kExitWarningTextWidthDMM = 0.44288f;
+static constexpr float kExitWarningFontHeightDMM = 0.024576f;
+static constexpr float kExitWarningXPaddingDMM = 0.033f;
+static constexpr float kExitWarningYPaddingDMM = 0.023f;
+static constexpr float kExitWarningCornerRadiusDMM = 0.008f;
 
 static constexpr float kContentDistance = 2.5;
 static constexpr float kContentWidthDMM = 0.96f;
@@ -186,11 +189,11 @@
 
 static constexpr float kOmniboxWidthDMM = 0.848f;
 static constexpr float kOmniboxHeightDMM = 0.088f;
-static constexpr float kOmniboxVerticalOffsetDMM = -0.1f;
+static constexpr float kOmniboxVerticalOffsetDMM = -0.2f;
 static constexpr float kOmniboxTextHeightDMM = 0.032f;
 static constexpr float kOmniboxTextMarginDMM = 0.024f;
-static constexpr float kOmniboxCloseButtonDiameterDMM = 0.088f;
-static constexpr float kOmniboxCloseButtonVerticalOffsetDMM = -0.5;
+static constexpr float kOmniboxCloseButtonDiameterDMM = kButtonDiameterDMM;
+static constexpr float kOmniboxCloseButtonVerticalOffsetDMM = -0.75f;
 
 static constexpr float kSuggestionHeightDMM = 0.088f;
 static constexpr float kSuggestionGapDMM = 0.008f;
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc
index 831bdedb..09fda43 100644
--- a/chrome/browser/vr/ui_scene_creator.cc
+++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -84,8 +84,8 @@
                             Model* model,
                             SuggestionBinding* element_binding) {
   auto icon = base::MakeUnique<VectorIcon>(100);
-  icon->set_draw_phase(kPhaseForeground);
-  icon->set_type(kTypeOmniboxSuggestionIcon);
+  icon->SetDrawPhase(kPhaseForeground);
+  icon->SetType(kTypeOmniboxSuggestionIcon);
   icon->set_hit_testable(false);
   icon->SetSize(kSuggestionIconSizeDMM, kSuggestionIconSizeDMM);
   BindColor(model, icon.get(), &ColorScheme::omnibox_icon,
@@ -93,15 +93,16 @@
   VectorIcon* p_icon = icon.get();
 
   auto icon_box = base::MakeUnique<UiElement>();
-  icon_box->set_draw_phase(kPhaseNone);
-  icon_box->set_type(kTypeOmniboxSuggestionIconField);
+  icon_box->SetDrawPhase(kPhaseNone);
+  icon_box->SetType(kTypeOmniboxSuggestionIconField);
   icon_box->SetSize(kSuggestionIconFieldWidthDMM, kSuggestionHeightDMM);
   icon_box->AddChild(std::move(icon));
 
   auto content_text =
       base::MakeUnique<Text>(1024, kSuggestionContentTextHeightDMM);
-  content_text->set_draw_phase(kPhaseForeground);
-  content_text->set_type(kTypeOmniboxSuggestionContentText);
+  content_text->SetDrawPhase(kPhaseForeground);
+  content_text->SetType(kTypeOmniboxSuggestionContentText);
+  content_text->set_hit_testable(false);
   content_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
   content_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
   content_text->SetMultiLine(false);
@@ -111,8 +112,9 @@
 
   auto description_text =
       base::MakeUnique<Text>(1024, kSuggestionDescriptionTextHeightDMM);
-  description_text->set_draw_phase(kPhaseForeground);
-  description_text->set_type(kTypeOmniboxSuggestionDescriptionText);
+  description_text->SetDrawPhase(kPhaseForeground);
+  description_text->SetType(kTypeOmniboxSuggestionDescriptionText);
+  description_text->set_hit_testable(false);
   description_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
   description_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
   description_text->SetMultiLine(false);
@@ -121,25 +123,28 @@
   Text* p_description_text = description_text.get();
 
   auto text_layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown);
-  text_layout->set_type(kTypeOmniboxSuggestionTextLayout);
+  text_layout->SetType(kTypeOmniboxSuggestionTextLayout);
+  text_layout->set_hit_testable(false);
   text_layout->set_margin(kSuggestionLineGapDMM);
   text_layout->AddChild(std::move(content_text));
   text_layout->AddChild(std::move(description_text));
-  text_layout->SetVisible(true);
 
   auto right_margin = base::MakeUnique<UiElement>();
-  right_margin->set_draw_phase(kPhaseNone);
+  right_margin->SetDrawPhase(kPhaseNone);
   right_margin->SetSize(kSuggestionRightMarginDMM, kSuggestionHeightDMM);
 
   auto suggestion_layout = base::MakeUnique<LinearLayout>(LinearLayout::kRight);
-  suggestion_layout->set_type(kTypeOmniboxSuggestionLayout);
+  suggestion_layout->SetType(kTypeOmniboxSuggestionLayout);
+  suggestion_layout->set_hit_testable(false);
   suggestion_layout->AddChild(std::move(icon_box));
   suggestion_layout->AddChild(std::move(text_layout));
   suggestion_layout->AddChild(std::move(right_margin));
 
   auto background = base::MakeUnique<Rect>();
-  background->set_type(kTypeOmniboxSuggestionBackground);
-  background->set_draw_phase(kPhaseForeground);
+  background->SetType(kTypeOmniboxSuggestionBackground);
+  background->SetDrawPhase(kPhaseForeground);
+  background->set_hit_testable(true);
+  background->set_bubble_events(true);
   background->set_bounds_contain_children(true);
   background->SetColor(SK_ColorGREEN);
   background->AddChild(std::move(suggestion_layout));
@@ -185,7 +190,7 @@
   auto element = base::MakeUnique<SimpleTransientElement>(
       base::TimeDelta::FromSeconds(timeout_seconds));
   TransientElement* to_return = element.get();
-  element->set_name(name);
+  element->SetName(name);
   element->SetVisible(false);
   element->set_hit_testable(false);
   if (animate_opacity)
@@ -197,8 +202,8 @@
 template <typename T, typename... Args>
 std::unique_ptr<T> Create(UiElementName name, DrawPhase phase, Args&&... args) {
   auto element = base::MakeUnique<T>(std::forward<Args>(args)...);
-  element->set_name(name);
-  element->set_draw_phase(phase);
+  element->SetName(name);
+  element->SetDrawPhase(phase);
   return element;
 }
 
@@ -244,28 +249,26 @@
 
 void UiSceneCreator::Create2dBrowsingSubtreeRoots() {
   auto element = base::MakeUnique<UiElement>();
-  element->set_name(k2dBrowsingRoot);
-  element->SetVisible(true);
+  element->SetName(k2dBrowsingRoot);
   element->set_hit_testable(false);
   element->AddBinding(VR_BIND_FUNC(bool, Model, model_, browsing_mode(),
                                    UiElement, element.get(), SetVisible));
   scene_->AddUiElement(kRoot, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(k2dBrowsingBackground);
-  element->SetVisible(true);
+  element->SetName(k2dBrowsingBackground);
   element->set_hit_testable(false);
   scene_->AddUiElement(k2dBrowsingRoot, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(k2dBrowsingVisibiltyControlForOmnibox);
+  element->SetName(k2dBrowsingVisibiltyControlForOmnibox);
   element->set_hit_testable(false);
   element->AddBinding(VR_BIND(bool, Model, model_, omnibox_input_active,
                               UiElement, element.get(), SetVisible(!value)));
   scene_->AddUiElement(k2dBrowsingRoot, std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(k2dBrowsingForeground);
+  element->SetName(k2dBrowsingForeground);
   element->set_hit_testable(false);
   element->SetTransitionedProperties({OPACITY});
   element->SetTransitionDuration(base::TimeDelta::FromMilliseconds(
@@ -290,7 +293,7 @@
                        std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_name(k2dBrowsingContentGroup);
+  element->SetName(k2dBrowsingContentGroup);
   element->SetTranslate(0, kContentVerticalOffset, -kContentDistance);
   element->SetSize(kContentWidth, kContentHeight);
   element->set_hit_testable(false);
@@ -305,8 +308,7 @@
 
 void UiSceneCreator::CreateWebVrRoot() {
   auto element = base::MakeUnique<UiElement>();
-  element->set_name(kWebVrRoot);
-  element->SetVisible(true);
+  element->SetName(kWebVrRoot);
   element->set_hit_testable(false);
   element->AddBinding(VR_BIND_FUNC(bool, Model, model_,
                                    browsing_mode() == false, UiElement,
@@ -316,8 +318,8 @@
 
 void UiSceneCreator::CreateWebVRExitWarning() {
   auto scrim = base::MakeUnique<FullScreenRect>();
-  scrim->set_name(kScreenDimmer);
-  scrim->set_draw_phase(kPhaseOverlayBackground);
+  scrim->SetName(kScreenDimmer);
+  scrim->SetDrawPhase(kPhaseOverlayBackground);
   scrim->SetVisible(false);
   scrim->set_hit_testable(false);
   scrim->SetOpacity(kScreenDimmerOpacity);
@@ -327,25 +329,37 @@
                                  scrim.get(), SetVisible));
   scene_->AddUiElement(k2dBrowsingRoot, std::move(scrim));
 
-  // TODO(mthiesse): Programatically compute the proper texture size for these
-  // textured UI elements.
   // Create transient exit warning.
-  auto exit_warning = base::MakeUnique<ExitWarning>(1024);
-  exit_warning->set_name(kExitWarning);
-  exit_warning->set_draw_phase(kPhaseOverlayForeground);
-  exit_warning->SetSize(kExitWarningWidth, kExitWarningHeight);
-  exit_warning->SetTranslate(0, 0, -kExitWarningDistance);
-  exit_warning->SetScale(kExitWarningDistance, kExitWarningDistance, 1);
-  exit_warning->SetVisible(false);
-  exit_warning->set_hit_testable(false);
-  exit_warning->AddBinding(VR_BIND_FUNC(bool, Model, model_, exiting_vr,
-                                        UiElement, exit_warning.get(),
-                                        SetVisible));
-  BindColor(model_, exit_warning.get(), &ColorScheme::exit_warning_background,
-            &TexturedElement::SetBackgroundColor);
-  BindColor(model_, exit_warning.get(), &ColorScheme::exit_warning_foreground,
-            &TexturedElement::SetForegroundColor);
-  scene_->AddUiElement(k2dBrowsingViewportAwareRoot, std::move(exit_warning));
+  auto scaler = base::MakeUnique<ScaledDepthAdjuster>(kExitWarningDistance);
+  auto exit_warning_text =
+      base::MakeUnique<Text>(1024, kExitWarningFontHeightDMM);
+  exit_warning_text->SetName(kExitWarningText);
+  exit_warning_text->SetDrawPhase(kPhaseOverlayForeground);
+  exit_warning_text->SetText(
+      l10n_util::GetStringUTF16(IDS_VR_BROWSER_UNSUPPORTED_PAGE));
+  exit_warning_text->SetSize(kExitWarningTextWidthDMM, 0);
+  exit_warning_text->SetMultiLine(true);
+  exit_warning_text->SetVisible(true);
+  exit_warning_text->set_hit_testable(false);
+  BindColor(model_, exit_warning_text.get(),
+            &ColorScheme::exit_warning_foreground, &Text::SetColor);
+
+  auto exit_warning_bg = base::MakeUnique<Rect>();
+  exit_warning_bg->SetName(kExitWarningBackground);
+  exit_warning_bg->SetDrawPhase(kPhaseOverlayForeground);
+  exit_warning_bg->set_bounds_contain_children(true);
+  exit_warning_bg->set_padding(kExitWarningXPaddingDMM,
+                               kExitWarningYPaddingDMM);
+  exit_warning_bg->set_corner_radius(kExitWarningCornerRadiusDMM);
+  exit_warning_bg->set_hit_testable(false);
+  exit_warning_bg->AddChild(std::move(exit_warning_text));
+  exit_warning_bg->AddBinding(VR_BIND_FUNC(bool, Model, model_, exiting_vr,
+                                           UiElement, exit_warning_bg.get(),
+                                           SetVisible));
+  BindColor(model_, exit_warning_bg.get(),
+            &ColorScheme::exit_warning_background, &Rect::SetColor);
+  scaler->AddChild(std::move(exit_warning_bg));
+  scene_->AddUiElement(k2dBrowsingViewportAwareRoot, std::move(scaler));
 }
 
 void UiSceneCreator::CreateSystemIndicators() {
@@ -373,7 +387,7 @@
 
   std::unique_ptr<LinearLayout> indicator_layout =
       base::MakeUnique<LinearLayout>(LinearLayout::kRight);
-  indicator_layout->set_name(kIndicatorLayout);
+  indicator_layout->SetName(kIndicatorLayout);
   indicator_layout->set_hit_testable(false);
   indicator_layout->set_y_anchoring(TOP);
   indicator_layout->SetTranslate(0, kIndicatorVerticalOffset,
@@ -388,8 +402,8 @@
     auto element = base::MakeUnique<SystemIndicator>(512);
     element->GetDerivedTexture()->SetIcon(indicator.icon);
     element->GetDerivedTexture()->SetMessageId(indicator.resource_string);
-    element->set_name(indicator.name);
-    element->set_draw_phase(kPhaseForeground);
+    element->SetName(indicator.name);
+    element->SetDrawPhase(kPhaseForeground);
     element->set_requires_layout(false);
     element->SetSize(0, kIndicatorHeight);
     element->SetVisible(false);
@@ -417,8 +431,8 @@
   // Place an invisible but hittable plane behind the content quad, to keep the
   // reticle roughly planar with the content if near content.
   auto hit_plane = base::MakeUnique<InvisibleHitTarget>();
-  hit_plane->set_name(kBackplane);
-  hit_plane->set_draw_phase(kPhaseForeground);
+  hit_plane->SetName(kBackplane);
+  hit_plane->SetDrawPhase(kPhaseForeground);
   hit_plane->SetSize(kBackplaneSize, kSceneHeight);
   scene_->AddUiElement(k2dBrowsingContentGroup, std::move(hit_plane));
 
@@ -426,8 +440,8 @@
       content_input_delegate_,
       base::Bind(&UiBrowserInterface::OnContentScreenBoundsChanged,
                  base::Unretained(browser_)));
-  main_content->set_name(kContentQuad);
-  main_content->set_draw_phase(kPhaseForeground);
+  main_content->SetName(kContentQuad);
+  main_content->SetDrawPhase(kPhaseForeground);
   main_content->SetSize(kContentWidth, kContentHeight);
   main_content->set_corner_radius(kContentCornerRadius);
   main_content->SetTransitionedProperties({BOUNDS});
@@ -453,15 +467,13 @@
 
 void UiSceneCreator::CreateSplashScreenForDirectWebVrLaunch() {
   auto element = base::MakeUnique<UiElement>();
-  element->set_name(kSplashScreenRoot);
-  element->SetVisible(true);
+  element->SetName(kSplashScreenRoot);
   element->set_hit_testable(false);
   scene_->AddUiElement(kRoot, std::move(element));
 
   // Create viewport aware root.
   element = base::MakeUnique<ViewportAwareRoot>();
-  element->set_name(kSplashScreenViewportAwareRoot);
-  element->SetVisible(true);
+  element->SetName(kSplashScreenViewportAwareRoot);
   element->set_hit_testable(false);
   scene_->AddUiElement(kSplashScreenRoot, std::move(element));
 
@@ -482,7 +494,7 @@
             }
           },
           base::Unretained(model_), base::Unretained(browser_)));
-  transient_parent->set_name(kSplashScreenTransientParent);
+  transient_parent->SetName(kSplashScreenTransientParent);
   transient_parent->AddBinding(
       VR_BIND_FUNC(bool, Model, model_, web_vr_show_splash_screen, UiElement,
                    transient_parent.get(), SetVisible));
@@ -500,9 +512,8 @@
   BindColor(model_, text.get(), &ColorScheme::splash_screen_text_color,
             &Text::SetColor);
   text->SetText(l10n_util::GetStringUTF16(IDS_VR_POWERED_BY_CHROME_MESSAGE));
-  text->set_name(kSplashScreenText);
-  text->SetVisible(true);
-  text->set_draw_phase(kPhaseOverlayForeground);
+  text->SetName(kSplashScreenText);
+  text->SetDrawPhase(kPhaseOverlayForeground);
   text->set_hit_testable(false);
   text->SetSize(kSplashScreenTextWidthM, kSplashScreenTextHeightM);
   text->SetTranslate(0, kSplashScreenTextVerticalOffset,
@@ -511,16 +522,15 @@
 
   // Add splash screen background.
   auto bg = base::MakeUnique<FullScreenRect>();
-  bg->set_name(kSplashScreenBackground);
-  bg->set_draw_phase(kPhaseOverlayBackground);
-  bg->SetVisible(true);
+  bg->SetName(kSplashScreenBackground);
+  bg->SetDrawPhase(kPhaseOverlayBackground);
   bg->set_hit_testable(false);
   bg->SetColor(model_->color_scheme().splash_screen_background);
   scene_->AddUiElement(kSplashScreenText, std::move(bg));
 
   auto spinner = base::MakeUnique<Spinner>(512);
-  spinner->set_name(kWebVrTimeoutSpinner);
-  spinner->set_draw_phase(kPhaseOverlayForeground);
+  spinner->SetName(kWebVrTimeoutSpinner);
+  spinner->SetDrawPhase(kPhaseOverlayForeground);
   spinner->SetVisible(false);
   spinner->SetSize(kSpinnerWidth, kSpinnerHeight);
   spinner->SetTranslate(0, kSpinnerVerticalOffset, -kSpinnerDistance);
@@ -534,8 +544,8 @@
   // Note, this cannot be a descendant of the viewport aware root, otherwise it
   // will fade out when the viewport aware elements reposition.
   auto spinner_bg = base::MakeUnique<FullScreenRect>();
-  spinner_bg->set_name(kWebVrTimeoutSpinnerBackground);
-  spinner_bg->set_draw_phase(kPhaseOverlayBackground);
+  spinner_bg->SetName(kWebVrTimeoutSpinnerBackground);
+  spinner_bg->SetDrawPhase(kPhaseOverlayBackground);
   spinner_bg->SetVisible(false);
   spinner_bg->set_hit_testable(false);
   spinner_bg->SetColor(model_->color_scheme().spinner_background);
@@ -566,13 +576,11 @@
   auto timeout_layout = Create<LinearLayout>(kWebVrTimeoutMessageLayout,
                                              kPhaseNone, LinearLayout::kRight);
   timeout_layout->set_hit_testable(false);
-  timeout_layout->SetVisible(true);
   timeout_layout->set_margin(kTimeoutMessageLayoutGapDMM);
 
   auto timeout_icon = Create<VectorIcon>(kWebVrTimeoutMessageIcon,
                                          kPhaseOverlayForeground, 512);
   timeout_icon->SetIcon(kSadTabIcon);
-  timeout_icon->SetVisible(true);
   timeout_icon->SetSize(kTimeoutMessageIconWidthDMM,
                         kTimeoutMessageIconHeightDMM);
 
@@ -583,7 +591,6 @@
       l10n_util::GetStringUTF16(IDS_VR_WEB_VR_TIMEOUT_MESSAGE));
   timeout_text->SetColor(model_->color_scheme().timeout_message_foreground);
   timeout_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
-  timeout_text->SetVisible(true);
   timeout_text->SetSize(kTimeoutMessageTextWidthDMM,
                         kTimeoutMessageTextHeightDMM);
 
@@ -614,7 +621,6 @@
   timeout_button_text->SetText(
       l10n_util::GetStringUTF16(IDS_VR_WEB_VR_EXIT_BUTTON_LABEL));
   timeout_button_text->SetColor(model_->color_scheme().spinner_color);
-  timeout_button_text->SetVisible(true);
   timeout_button_text->SetSize(kTimeoutButtonTextWidthDMM,
                                kTimeoutButtonTextHeightDMM);
   timeout_button_text->set_y_anchoring(BOTTOM);
@@ -635,14 +641,13 @@
   BindColor(model_, text.get(), &ColorScheme::world_background_text,
             &Text::SetColor);
   text->SetText(l10n_util::GetStringUTF16(IDS_VR_UNDER_DEVELOPMENT_NOTICE));
-  text->set_name(kUnderDevelopmentNotice);
-  text->set_draw_phase(kPhaseForeground);
+  text->SetName(kUnderDevelopmentNotice);
+  text->SetDrawPhase(kPhaseForeground);
   text->set_hit_testable(false);
   text->SetSize(kUnderDevelopmentNoticeWidthDMM,
                 kUnderDevelopmentNoticeHeightDMM);
   text->SetTranslate(0, -kUnderDevelopmentNoticeVerticalOffsetDMM, 0);
   text->SetRotate(1, 0, 0, kUnderDevelopmentNoticeRotationRad);
-  text->SetVisible(true);
   text->set_y_anchoring(BOTTOM);
   scene_->AddUiElement(kUrlBar, std::move(text));
 }
@@ -668,8 +673,8 @@
   };
   for (auto& panel : panels) {
     auto panel_element = base::MakeUnique<Rect>();
-    panel_element->set_name(panel.name);
-    panel_element->set_draw_phase(kPhaseBackground);
+    panel_element->SetName(panel.name);
+    panel_element->SetDrawPhase(kPhaseBackground);
     panel_element->SetSize(kSceneSize, kSceneSize);
     panel_element->SetTranslate(panel.x_offset * kSceneSize / 2,
                                 panel.y_offset * kSceneSize / 2,
@@ -687,8 +692,8 @@
 
   // Floor.
   auto floor = base::MakeUnique<Grid>();
-  floor->set_name(kFloor);
-  floor->set_draw_phase(kPhaseFloorCeiling);
+  floor->SetName(kFloor);
+  floor->SetDrawPhase(kPhaseFloorCeiling);
   floor->SetSize(kSceneSize, kSceneSize);
   floor->SetTranslate(0.0, -kSceneHeight / 2, 0.0);
   floor->SetRotate(1, 0, 0, -base::kPiFloat / 2);
@@ -701,8 +706,8 @@
 
   // Ceiling.
   auto ceiling = base::MakeUnique<Rect>();
-  ceiling->set_name(kCeiling);
-  ceiling->set_draw_phase(kPhaseFloorCeiling);
+  ceiling->SetName(kCeiling);
+  ceiling->SetDrawPhase(kPhaseFloorCeiling);
   ceiling->SetSize(kSceneSize, kSceneSize);
   ceiling->SetTranslate(0.0, kSceneHeight / 2, 0.0);
   ceiling->SetRotate(1, 0, 0, base::kPiFloat / 2);
@@ -717,14 +722,12 @@
 
 void UiSceneCreator::CreateViewportAwareRoot() {
   auto element = base::MakeUnique<ViewportAwareRoot>();
-  element->set_name(kWebVrViewportAwareRoot);
-  element->SetVisible(true);
+  element->SetName(kWebVrViewportAwareRoot);
   element->set_hit_testable(false);
   scene_->AddUiElement(kWebVrRoot, std::move(element));
 
   element = base::MakeUnique<ViewportAwareRoot>();
-  element->set_name(k2dBrowsingViewportAwareRoot);
-  element->SetVisible(true);
+  element->SetName(k2dBrowsingViewportAwareRoot);
   element->set_hit_testable(false);
   scene_->AddUiElement(k2dBrowsingRoot, std::move(element));
 }
@@ -755,7 +758,7 @@
   scene_->AddUiElement(kUrlBar, std::move(voice_search_button));
 
   auto speech_recognition_root = base::MakeUnique<UiElement>();
-  speech_recognition_root->set_name(kSpeechRecognitionRoot);
+  speech_recognition_root->SetName(kSpeechRecognitionRoot);
   speech_recognition_root->SetTranslate(0.f, 0.f, -kContentDistance);
   speech_recognition_root->set_hit_testable(false);
   scene_->AddUiElement(k2dBrowsingRoot, std::move(speech_recognition_root));
@@ -786,8 +789,8 @@
           speech_result_parent)));
   auto speech_result =
       base::MakeUnique<Text>(256, kVoiceSearchRecognitionResultTextHeight);
-  speech_result->set_name(kSpeechRecognitionResultText);
-  speech_result->set_draw_phase(kPhaseForeground);
+  speech_result->SetName(kSpeechRecognitionResultText);
+  speech_result->SetDrawPhase(kPhaseForeground);
   speech_result->SetTranslate(0.f, kSpeechRecognitionResultTextYOffset, 0.f);
   speech_result->set_hit_testable(false);
   speech_result->SetSize(kVoiceSearchRecognitionResultTextWidth, 0);
@@ -800,8 +803,8 @@
   speech_result_parent->AddChild(std::move(speech_result));
 
   auto circle = base::MakeUnique<Rect>();
-  circle->set_name(kSpeechRecognitionResultCircle);
-  circle->set_draw_phase(kPhaseForeground);
+  circle->SetName(kSpeechRecognitionResultCircle);
+  circle->SetDrawPhase(kPhaseForeground);
   circle->SetSize(kCloseButtonWidth * 2, kCloseButtonHeight * 2);
   circle->set_corner_radius(kCloseButtonWidth);
   circle->set_hit_testable(false);
@@ -811,22 +814,22 @@
   scene_->AddUiElement(kSpeechRecognitionResult, std::move(circle));
 
   auto microphone = base::MakeUnique<VectorIcon>(512);
-  microphone->set_name(kSpeechRecognitionResultMicrophoneIcon);
+  microphone->SetName(kSpeechRecognitionResultMicrophoneIcon);
   microphone->SetIcon(vector_icons::kMicrophoneIcon);
-  microphone->set_draw_phase(kPhaseForeground);
+  microphone->SetDrawPhase(kPhaseForeground);
   microphone->set_hit_testable(false);
   microphone->SetSize(kCloseButtonWidth, kCloseButtonHeight);
   scene_->AddUiElement(kSpeechRecognitionResult, std::move(microphone));
 
   auto hit_target = base::MakeUnique<InvisibleHitTarget>();
-  hit_target->set_name(kSpeechRecognitionResultBackplane);
-  hit_target->set_draw_phase(kPhaseForeground);
+  hit_target->SetName(kSpeechRecognitionResultBackplane);
+  hit_target->SetDrawPhase(kPhaseForeground);
   hit_target->SetSize(kPromptBackplaneSize, kPromptBackplaneSize);
   scene_->AddUiElement(kSpeechRecognitionResult, std::move(hit_target));
 
   auto speech_recognition_listening = base::MakeUnique<UiElement>();
   UiElement* listening_ui_root = speech_recognition_listening.get();
-  speech_recognition_listening->set_name(kSpeechRecognitionListening);
+  speech_recognition_listening->SetName(kSpeechRecognitionListening);
   speech_recognition_listening->set_hit_testable(false);
   // We need to explicitly set the initial visibility of this element for the
   // same reason as kSpeechRecognitionResult.
@@ -852,8 +855,8 @@
                        std::move(speech_recognition_listening));
 
   auto growing_circle = base::MakeUnique<Throbber>();
-  growing_circle->set_name(kSpeechRecognitionListeningGrowingCircle);
-  growing_circle->set_draw_phase(kPhaseForeground);
+  growing_circle->SetName(kSpeechRecognitionListeningGrowingCircle);
+  growing_circle->SetDrawPhase(kPhaseForeground);
   growing_circle->SetSize(kCloseButtonWidth * 2, kCloseButtonHeight * 2);
   growing_circle->set_corner_radius(kCloseButtonWidth);
   growing_circle->set_hit_testable(false);
@@ -869,8 +872,8 @@
   scene_->AddUiElement(kSpeechRecognitionListening, std::move(growing_circle));
 
   auto inner_circle = base::MakeUnique<Rect>();
-  inner_circle->set_name(kSpeechRecognitionListeningInnerCircle);
-  inner_circle->set_draw_phase(kPhaseForeground);
+  inner_circle->SetName(kSpeechRecognitionListeningInnerCircle);
+  inner_circle->SetDrawPhase(kPhaseForeground);
   inner_circle->SetSize(kCloseButtonWidth * 2, kCloseButtonHeight * 2);
   inner_circle->set_corner_radius(kCloseButtonWidth);
   inner_circle->set_hit_testable(false);
@@ -881,8 +884,8 @@
 
   auto microphone_icon = base::MakeUnique<VectorIcon>(512);
   microphone_icon->SetIcon(vector_icons::kMicrophoneIcon);
-  microphone_icon->set_name(kSpeechRecognitionListeningMicrophoneIcon);
-  microphone_icon->set_draw_phase(kPhaseForeground);
+  microphone_icon->SetName(kSpeechRecognitionListeningMicrophoneIcon);
+  microphone_icon->SetDrawPhase(kPhaseForeground);
   microphone_icon->set_hit_testable(false);
   microphone_icon->SetSize(kCloseButtonWidth, kCloseButtonHeight);
   scene_->AddUiElement(kSpeechRecognitionListening, std::move(microphone_icon));
@@ -920,8 +923,7 @@
 
 void UiSceneCreator::CreateController() {
   auto root = base::MakeUnique<UiElement>();
-  root->set_name(kControllerRoot);
-  root->SetVisible(true);
+  root->SetName(kControllerRoot);
   root->set_hit_testable(false);
   root->AddBinding(VR_BIND_FUNC(
       bool, Model, model_,
@@ -930,8 +932,7 @@
   scene_->AddUiElement(kRoot, std::move(root));
 
   auto group = base::MakeUnique<UiElement>();
-  group->set_name(kControllerGroup);
-  group->SetVisible(true);
+  group->SetName(kControllerGroup);
   group->set_hit_testable(false);
   group->SetTransitionedProperties({OPACITY});
   group->AddBinding(base::MakeUnique<Binding<bool>>(
@@ -950,7 +951,7 @@
   scene_->AddUiElement(kControllerRoot, std::move(group));
 
   auto controller = base::MakeUnique<Controller>();
-  controller->set_draw_phase(kPhaseForeground);
+  controller->SetDrawPhase(kPhaseForeground);
   controller->AddBinding(VR_BIND_FUNC(gfx::Transform, Model, model_,
                                       controller.transform, Controller,
                                       controller.get(), set_local_transform));
@@ -970,13 +971,13 @@
   scene_->AddUiElement(kControllerGroup, std::move(controller));
 
   auto laser = base::MakeUnique<Laser>(model_);
-  laser->set_draw_phase(kPhaseForeground);
+  laser->SetDrawPhase(kPhaseForeground);
   laser->AddBinding(VR_BIND_FUNC(float, Model, model_, controller.opacity,
                                  Laser, laser.get(), SetOpacity));
   scene_->AddUiElement(kControllerGroup, std::move(laser));
 
   auto reticle = base::MakeUnique<Reticle>(scene_, model_);
-  reticle->set_draw_phase(kPhaseForeground);
+  reticle->SetDrawPhase(kPhaseForeground);
   scene_->AddUiElement(kControllerGroup, std::move(reticle));
 }
 
@@ -996,7 +997,7 @@
             *model = text_input_info;
           },
           base::Unretained(text_input_model)));
-  text_input->set_draw_phase(kPhaseNone);
+  text_input->SetDrawPhase(kPhaseNone);
   text_input->set_hit_testable(false);
   text_input->SetTextInputDelegate(text_input_delegate);
   text_input->AddBinding(base::MakeUnique<Binding<TextInputInfo>>(
@@ -1013,7 +1014,7 @@
 void UiSceneCreator::CreateKeyboard() {
   auto keyboard = base::MakeUnique<Keyboard>();
   keyboard->SetKeyboardDelegate(keyboard_delegate_);
-  keyboard->set_draw_phase(kPhaseForeground);
+  keyboard->SetDrawPhase(kPhaseForeground);
   keyboard->SetTranslate(0.0, kKeyboardVerticalOffset, -kKeyboardDistance);
   keyboard->AddBinding(VR_BIND_FUNC(bool, Model, model_, editing_input,
                                     UiElement, keyboard.get(), SetVisible));
@@ -1022,7 +1023,7 @@
 
 void UiSceneCreator::CreateUrlBar() {
   auto scaler = base::MakeUnique<ScaledDepthAdjuster>(kUrlBarDistance);
-  scaler->set_name(kUrlBarDmmRoot);
+  scaler->SetName(kUrlBarDmmRoot);
   scene_->AddUiElement(k2dBrowsingForeground, std::move(scaler));
 
   base::RepeatingCallback<void()> url_click_callback;
@@ -1043,8 +1044,8 @@
       url_click_callback,
       base::BindRepeating(&UiBrowserInterface::OnUnsupportedMode,
                           base::Unretained(browser_)));
-  url_bar->set_name(kUrlBar);
-  url_bar->set_draw_phase(kPhaseForeground);
+  url_bar->SetName(kUrlBar);
+  url_bar->SetDrawPhase(kPhaseForeground);
   url_bar->SetTranslate(0, kUrlBarVerticalOffsetDMM, 0);
   url_bar->SetRotate(1, 0, 0, kUrlBarRotationRad);
   url_bar->SetSize(kUrlBarWidthDMM, kUrlBarHeightDMM);
@@ -1063,8 +1064,8 @@
   scene_->AddUiElement(kUrlBarDmmRoot, std::move(url_bar));
 
   auto indicator_bg = base::MakeUnique<Rect>();
-  indicator_bg->set_name(kLoadingIndicator);
-  indicator_bg->set_draw_phase(kPhaseForeground);
+  indicator_bg->SetName(kLoadingIndicator);
+  indicator_bg->SetDrawPhase(kPhaseForeground);
   indicator_bg->SetTranslate(0, kLoadingIndicatorVerticalOffsetDMM, 0);
   indicator_bg->SetSize(kLoadingIndicatorWidthDMM, kLoadingIndicatorHeightDMM);
   indicator_bg->set_y_anchoring(TOP);
@@ -1078,8 +1079,8 @@
   scene_->AddUiElement(kUrlBar, std::move(indicator_bg));
 
   auto indicator_fg = base::MakeUnique<Rect>();
-  indicator_fg->set_draw_phase(kPhaseForeground);
-  indicator_fg->set_name(kLoadingIndicatorForeground);
+  indicator_fg->SetDrawPhase(kPhaseForeground);
+  indicator_fg->SetName(kLoadingIndicatorForeground);
   indicator_fg->set_x_anchoring(LEFT);
   indicator_fg->set_corner_radius(kLoadingIndicatorHeightDMM * 0.5f);
   indicator_fg->set_hit_testable(false);
@@ -1101,12 +1102,12 @@
 
 void UiSceneCreator::CreateOmnibox() {
   auto scaler = base::MakeUnique<ScaledDepthAdjuster>(kUrlBarDistance);
-  scaler->set_name(kOmniboxDmmRoot);
+  scaler->SetName(kOmniboxDmmRoot);
   scene_->AddUiElement(k2dBrowsingRoot, std::move(scaler));
 
   auto omnibox_root = base::MakeUnique<UiElement>();
-  omnibox_root->set_name(kOmniboxRoot);
-  omnibox_root->set_draw_phase(kPhaseNone);
+  omnibox_root->SetName(kOmniboxRoot);
+  omnibox_root->SetDrawPhase(kPhaseNone);
   omnibox_root->SetVisible(false);
   omnibox_root->set_hit_testable(false);
   omnibox_root->SetTransitionedProperties({OPACITY});
@@ -1116,17 +1117,20 @@
   scene_->AddUiElement(kOmniboxDmmRoot, std::move(omnibox_root));
 
   auto omnibox_container = base::MakeUnique<Rect>();
-  omnibox_container->set_name(kOmniboxContainer);
-  omnibox_container->set_draw_phase(kPhaseForeground);
+  omnibox_container->SetName(kOmniboxContainer);
+  omnibox_container->SetDrawPhase(kPhaseForeground);
   omnibox_container->SetSize(kOmniboxWidthDMM, kOmniboxHeightDMM);
   omnibox_container->SetColor(SK_ColorWHITE);
+  omnibox_container->SetTranslate(0, kUrlBarVerticalOffsetDMM, 0);
   omnibox_container->SetTransitionedProperties({TRANSFORM});
+  omnibox_container->set_focusable(false);
   omnibox_container->AddBinding(base::MakeUnique<Binding<bool>>(
       base::Bind([](Model* m) { return m->omnibox_input_active; },
                  base::Unretained(model_)),
       base::Bind(
           [](UiElement* e, const bool& v) {
-            float y_offset = v ? kOmniboxVerticalOffsetDMM : 0;
+            float y_offset =
+                v ? kOmniboxVerticalOffsetDMM : kUrlBarVerticalOffsetDMM;
             e->SetTranslate(0, y_offset, 0);
           },
           omnibox_container.get())));
@@ -1136,13 +1140,21 @@
   auto omnibox_text_field =
       CreateTextInput(1024, kOmniboxTextHeightDMM, model_,
                       &model_->omnibox_text_field_info, text_input_delegate_);
+  omnibox_text_field->set_input_committed_callback(base::BindRepeating(
+      [](Model* model, UiBrowserInterface* browser, const TextInputInfo& text) {
+        if (!model->omnibox_suggestions.empty()) {
+          browser->Navigate(model->omnibox_suggestions.front().destination);
+          model->omnibox_input_active = false;
+        }
+      },
+      base::Unretained(model_), base::Unretained(browser_)));
   omnibox_text_field->AddBinding(
       VR_BIND(TextInputInfo, Model, model_, omnibox_text_field_info,
               UiBrowserInterface, browser_, StartAutocomplete(value.text)));
   omnibox_text_field->SetSize(width, 0);
   omnibox_text_field->SetHintText(
       l10n_util::GetStringUTF16(IDS_SEARCH_OR_TYPE_URL));
-  omnibox_text_field->set_name(kOmniboxTextField);
+  omnibox_text_field->SetName(kOmniboxTextField);
   omnibox_text_field->set_x_anchoring(LEFT);
   omnibox_text_field->set_x_centering(LEFT);
   omnibox_text_field->SetTranslate(kOmniboxTextMarginDMM, 0, 0);
@@ -1150,12 +1162,34 @@
       base::BindRepeating([](Model* m) { return m->omnibox_input_active; },
                           base::Unretained(model_)),
       base::BindRepeating(
-          [](TextInput* e, const bool& v) {
+          [](TextInput* e, Model* m, const bool& v) {
+            m->omnibox_text_field_info = TextInputInfo();
             if (v) {
               e->RequestFocus();
+            } else {
+              e->RequestUnfocus();
             }
           },
-          base::Unretained(omnibox_text_field.get()))));
+          base::Unretained(omnibox_text_field.get()),
+          base::Unretained(model_))));
+  omnibox_text_field->AddBinding(base::MakeUnique<Binding<AutocompleteStatus>>(
+      base::BindRepeating(
+          [](Model* m) {
+            AutocompleteStatus state;
+            state.active = m->omnibox_input_active;
+            state.input = m->omnibox_text_field_info.text;
+            return state;
+          },
+          base::Unretained(model_)),
+      base::BindRepeating(
+          [](UiBrowserInterface* browser, const AutocompleteStatus& r) {
+            if (r.active) {
+              browser->StartAutocomplete(r.input);
+            } else {
+              browser->StopAutocomplete();
+            }
+          },
+          base::Unretained(browser_))));
   BindColor(model_, omnibox_text_field.get(), &ColorScheme::omnibox_text,
             &TextInput::SetTextColor);
   BindColor(model_, omnibox_text_field.get(), &ColorScheme::cursor,
@@ -1165,19 +1199,6 @@
 
   scene_->AddUiElement(kOmniboxContainer, std::move(omnibox_text_field));
 
-  auto close_button = Create<Button>(
-      kOmniboxCloseButton, kPhaseForeground,
-      base::Bind([](Model* m) { m->omnibox_input_active = false; },
-                 base::Unretained(model_)),
-      vector_icons::kClose16Icon);
-  close_button->SetSize(kOmniboxCloseButtonDiameterDMM,
-                        kOmniboxCloseButtonDiameterDMM);
-  close_button->SetTranslate(0, kOmniboxCloseButtonVerticalOffsetDMM, 0);
-  close_button->set_hover_offset(kButtonZOffsetHoverDMM);
-  BindButtonColors(model_, close_button.get(), &ColorScheme::button_colors,
-                   &Button::SetButtonColors);
-  scene_->AddUiElement(kOmniboxContainer, std::move(close_button));
-
   // Set up the vector binding to manage suggestions dynamically.
   SuggestionSetBinding::ModelAddedCallback added_callback =
       base::Bind(&OnSuggestionModelAdded, base::Unretained(scene_),
@@ -1186,8 +1207,8 @@
       base::Bind(&OnSuggestionModelRemoved, base::Unretained(scene_));
 
   auto suggestions_layout = base::MakeUnique<LinearLayout>(LinearLayout::kUp);
-  suggestions_layout->set_name(kOmniboxSuggestions);
-  suggestions_layout->set_draw_phase(kPhaseNone);
+  suggestions_layout->SetName(kOmniboxSuggestions);
+  suggestions_layout->SetDrawPhase(kPhaseNone);
   suggestions_layout->set_hit_testable(false);
   suggestions_layout->set_y_anchoring(TOP);
   suggestions_layout->set_y_centering(BOTTOM);
@@ -1196,6 +1217,20 @@
       &model_->omnibox_suggestions, added_callback, removed_callback));
 
   scene_->AddUiElement(kOmniboxContainer, std::move(suggestions_layout));
+
+  auto close_button = Create<Button>(
+      kOmniboxCloseButton, kPhaseForeground,
+      base::BindRepeating([](Model* m) { m->omnibox_input_active = false; },
+                          base::Unretained(model_)),
+      vector_icons::kClose16Icon);
+  close_button->SetSize(kOmniboxCloseButtonDiameterDMM,
+                        kOmniboxCloseButtonDiameterDMM);
+  close_button->SetTranslate(0, kOmniboxCloseButtonVerticalOffsetDMM, 0);
+  close_button->SetRotate(1, 0, 0, atan(kOmniboxCloseButtonVerticalOffsetDMM));
+  close_button->set_hover_offset(kButtonZOffsetHoverDMM);
+  BindButtonColors(model_, close_button.get(), &ColorScheme::button_colors,
+                   &Button::SetButtonColors);
+  scene_->AddUiElement(kOmniboxRoot, std::move(close_button));
 }
 
 void UiSceneCreator::CreateWebVrUrlToast() {
@@ -1211,10 +1246,9 @@
   auto element = base::MakeUnique<WebVrUrlToast>(
       512, base::Bind(&UiBrowserInterface::OnUnsupportedMode,
                       base::Unretained(browser_)));
-  element->set_name(kWebVrUrlToast);
+  element->SetName(kWebVrUrlToast);
   element->set_opacity_when_visible(0.8f);
-  element->set_draw_phase(kPhaseOverlayForeground);
-  element->SetVisible(true);
+  element->SetDrawPhase(kPhaseOverlayForeground);
   element->set_hit_testable(false);
   element->SetTranslate(0, kWebVrToastDistance * sin(kWebVrUrlToastRotationRad),
                         -kWebVrToastDistance * cos(kWebVrUrlToastRotationRad));
@@ -1279,8 +1313,8 @@
   // Place an invisible but hittable plane behind the exit prompt, to keep the
   // reticle roughly planar with the content if near content.
   auto backplane = base::MakeUnique<InvisibleHitTarget>();
-  backplane->set_name(kExitPromptBackplane);
-  backplane->set_draw_phase(kPhaseForeground);
+  backplane->SetName(kExitPromptBackplane);
+  backplane->SetDrawPhase(kPhaseForeground);
   backplane->SetSize(kPromptBackplaneSize, kPromptBackplaneSize);
   backplane->SetTranslate(0.0,
                           kContentVerticalOffset + kExitPromptVerticalOffset,
@@ -1306,9 +1340,8 @@
                  base::Unretained(browser_), ExitVrPromptChoice::CHOICE_STAY),
       base::Bind(&UiBrowserInterface::OnExitVrPromptResult,
                  base::Unretained(browser_), ExitVrPromptChoice::CHOICE_EXIT));
-  exit_prompt->set_name(kExitPrompt);
-  exit_prompt->set_draw_phase(kPhaseForeground);
-  exit_prompt->SetVisible(true);
+  exit_prompt->SetName(kExitPrompt);
+  exit_prompt->SetDrawPhase(kPhaseForeground);
   exit_prompt->SetSize(kExitPromptWidth, kExitPromptHeight);
   BindColor(model_, exit_prompt.get(), &ColorScheme::prompt_foreground,
             &TexturedElement::SetForegroundColor);
@@ -1344,8 +1377,8 @@
   // Place an invisible but hittable plane behind the exit prompt, to keep the
   // reticle roughly planar with the content if near content.
   auto backplane = base::MakeUnique<InvisibleHitTarget>();
-  backplane->set_draw_phase(kPhaseForeground);
-  backplane->set_name(kAudioPermissionPromptBackplane);
+  backplane->SetDrawPhase(kPhaseForeground);
+  backplane->SetName(kAudioPermissionPromptBackplane);
   backplane->SetSize(kPromptBackplaneSize, kPromptBackplaneSize);
   backplane->SetTranslate(0.0, kContentVerticalOffset, -kOverlayPlaneDistance);
   EventHandlers event_handlers;
@@ -1366,8 +1399,8 @@
       UiElement, backplane.get(), SetVisible));
 
   std::unique_ptr<Shadow> shadow = base::MakeUnique<Shadow>();
-  shadow->set_draw_phase(kPhaseForeground);
-  shadow->set_name(kAudioPermissionPromptShadow);
+  shadow->SetDrawPhase(kPhaseForeground);
+  shadow->SetName(kAudioPermissionPromptShadow);
   shadow->set_corner_radius(kContentCornerRadius);
 
   std::unique_ptr<AudioPermissionPrompt> prompt =
@@ -1381,8 +1414,8 @@
               &UiBrowserInterface::OnExitVrPromptResult,
               base::Unretained(browser_), ExitVrPromptChoice::CHOICE_STAY,
               UiUnsupportedMode::kVoiceSearchNeedsRecordAudioOsPermission));
-  prompt->set_name(kAudioPermissionPrompt);
-  prompt->set_draw_phase(kPhaseForeground);
+  prompt->SetName(kAudioPermissionPrompt);
+  prompt->SetDrawPhase(kPhaseForeground);
   prompt->SetSize(kAudioPermissionPromptWidth, kAudioPermissionPromptHeight);
   prompt->SetTranslate(0.0, 0.0f, kAudionPermisionPromptDepth);
   BindButtonColors(model_, prompt.get(),
@@ -1418,8 +1451,8 @@
                                   parent, SetVisible));
 
   auto element = base::MakeUnique<ExclusiveScreenToast>(512);
-  element->set_name(kExclusiveScreenToast);
-  element->set_draw_phase(kPhaseForeground);
+  element->SetName(kExclusiveScreenToast);
+  element->SetDrawPhase(kPhaseForeground);
   element->SetSize(kToastWidthDMM, kToastHeightDMM);
   element->SetTranslate(
       0,
@@ -1450,8 +1483,8 @@
                    UiElement, parent, SetVisible));
 
   element = base::MakeUnique<ExclusiveScreenToast>(512);
-  element->set_name(kExclusiveScreenToastViewportAware);
-  element->set_draw_phase(kPhaseOverlayForeground);
+  element->SetName(kExclusiveScreenToastViewportAware);
+  element->SetDrawPhase(kPhaseOverlayForeground);
   element->SetSize(kToastWidthDMM, kToastHeightDMM);
   element->SetTranslate(0, kWebVrToastDistance * sin(kWebVrAngleRadians),
                         -kWebVrToastDistance * cos(kWebVrAngleRadians));
diff --git a/chrome/browser/vr/ui_scene_unittest.cc b/chrome/browser/vr/ui_scene_unittest.cc
index 5309f916..adba8c8 100644
--- a/chrome/browser/vr/ui_scene_unittest.cc
+++ b/chrome/browser/vr/ui_scene_unittest.cc
@@ -60,7 +60,7 @@
   EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 1u);
 
   auto element = base::MakeUnique<UiElement>();
-  element->set_draw_phase(kPhaseForeground);
+  element->SetDrawPhase(kPhaseForeground);
   UiElement* parent = element.get();
   int parent_id = parent->id();
   scene.AddUiElement(kRoot, std::move(element));
@@ -68,7 +68,7 @@
   EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 2u);
 
   element = base::MakeUnique<UiElement>();
-  element->set_draw_phase(kPhaseForeground);
+  element->SetDrawPhase(kPhaseForeground);
   UiElement* child = element.get();
   int child_id = child->id();
 
@@ -148,7 +148,7 @@
   UiScene scene;
   auto element = base::MakeUnique<UiElement>();
   UiElement* container = element.get();
-  element->set_name(kWebVrRoot);
+  element->SetName(kWebVrRoot);
   scene.AddUiElement(kRoot, std::move(element));
 
   auto root = base::MakeUnique<ViewportAwareRoot>();
@@ -157,11 +157,11 @@
 
   element = base::MakeUnique<UiElement>();
   UiElement* child = element.get();
-  element->set_draw_phase(kPhaseOverlayForeground);
+  element->SetDrawPhase(kPhaseOverlayForeground);
   viewport_aware_root->AddChild(std::move(element));
 
   element = base::MakeUnique<UiElement>();
-  element->set_draw_phase(kPhaseOverlayForeground);
+  element->SetDrawPhase(kPhaseOverlayForeground);
   child->AddChild(std::move(element));
 
   EXPECT_FALSE(scene.GetVisibleWebVrOverlayForegroundElements().empty());
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc
index 9aeb940..84d97b77 100644
--- a/chrome/browser/vr/ui_unittest.cc
+++ b/chrome/browser/vr/ui_unittest.cc
@@ -79,8 +79,7 @@
     kTypeButtonHitTarget, kTypeTextInputText,
 };
 const std::set<UiElementName> kElementsVisibleWithExitWarning = {
-    kScreenDimmer, kExitWarning,
-};
+    kScreenDimmer, kExitWarningBackground, kExitWarningText};
 const std::vector<std::string> kElementsInDrawOrder = {
     "kBackgroundFront",
     "kBackgroundLeft",
@@ -141,7 +140,8 @@
     "kLaser",
     "kReticle",
     "kKeyboard",
-    "kExitWarning",
+    "kExitWarningBackground",
+    "kExitWarningText",
     "kWebVrUrlToast",
     "kExclusiveScreenToastViewportAware",
     "kSplashScreenText",
@@ -1002,13 +1002,13 @@
   Model model;
 
   auto reticle = base::MakeUnique<Reticle>(&scene, &model);
-  reticle->set_draw_phase(kPhaseNone);
+  reticle->SetDrawPhase(kPhaseNone);
   scene.root_element().AddChild(std::move(reticle));
 
   auto element = base::MakeUnique<UiElement>();
   UiElement* parent = element.get();
-  parent->set_draw_phase(kPhaseForeground);
-  parent->set_name(k2dBrowsingRoot);
+  parent->SetDrawPhase(kPhaseForeground);
+  parent->SetName(k2dBrowsingRoot);
   scene.root_element().AddChild(std::move(element));
   model.reticle.target_element_id = parent->id();
 
@@ -1020,7 +1020,7 @@
   //   - Rotated
   for (int i = 0; i < 4; i++) {
     element = base::MakeUnique<UiElement>();
-    element->set_draw_phase(kPhaseForeground);
+    element->SetDrawPhase(kPhaseForeground);
     parent->AddChild(std::move(element));
   }
   parent->children()[1]->SetTranslate(1, 0, 0);
@@ -1081,7 +1081,7 @@
   CreateScene(kNotInCct, kNotInWebVr);
   UiElement* element = scene_->GetUiElementByName(kContentQuad);
   EXPECT_TRUE(element);
-  element->set_draw_phase(kPhaseOverlayForeground);
+  element->SetDrawPhase(kPhaseOverlayForeground);
   model_->reticle.target_element_id = element->id();
   auto unsorted = scene_->GetVisible2dBrowsingOverlayElements();
   auto sorted = UiRenderer::GetElementsInDrawOrder(unsorted);
@@ -1110,7 +1110,7 @@
   CreateScene(kNotInCct, kNotInWebVr);
   UiElement* element = scene_->GetUiElementByName(kReticle);
   EXPECT_TRUE(element);
-  element->set_draw_phase(kPhaseBackground);
+  element->SetDrawPhase(kPhaseBackground);
   EXPECT_NE(scene_->GetUiElementByName(kLaser)->draw_phase(),
             element->draw_phase());
   model_->reticle.target_element_id = 0;
diff --git a/chrome/browser/win/chrome_elf_init_unittest.cc b/chrome/browser/win/chrome_elf_init_unittest.cc
index f2b1b94f3..e122f11 100644
--- a/chrome/browser/win/chrome_elf_init_unittest.cc
+++ b/chrome/browser/win/chrome_elf_init_unittest.cc
@@ -79,7 +79,8 @@
 
   // Ensure the beacon values are now correct, indicating the
   // blacklist beacon was setup.
-  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());
+  ASSERT_EQ(static_cast<DWORD>(blacklist::BLACKLIST_ENABLED),
+            GetBlacklistState());
   base::string16 version(base::UTF8ToUTF16(version_info::GetVersionNumber()));
   ASSERT_EQ(version, GetBlacklistVersion());
 }
@@ -105,7 +106,8 @@
 
   // Ensure invalid values are returned to indicate that the beacon
   // values are indeed gone.
-  ASSERT_EQ(blacklist::BLACKLIST_STATE_MAX, GetBlacklistState());
+  ASSERT_EQ(static_cast<DWORD>(blacklist::BLACKLIST_STATE_MAX),
+            GetBlacklistState());
   ASSERT_EQ(base::string16(), GetBlacklistVersion());
 }
 
@@ -113,7 +115,8 @@
   BrowserBlacklistBeaconSetup();
 
   // Verify the state is properly set after the first run.
-  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());
+  ASSERT_EQ(static_cast<DWORD>(blacklist::BLACKLIST_ENABLED),
+            GetBlacklistState());
 
   base::string16 version(base::UTF8ToUTF16(version_info::GetVersionNumber()));
   ASSERT_EQ(version, GetBlacklistVersion());
@@ -129,7 +132,8 @@
 
   BrowserBlacklistBeaconSetup();
 
-  ASSERT_EQ(blacklist::BLACKLIST_DISABLED, GetBlacklistState());
+  ASSERT_EQ(static_cast<DWORD>(blacklist::BLACKLIST_DISABLED),
+            GetBlacklistState());
 }
 
 TEST_F(ChromeBlacklistTrialTest, VersionChanged) {
@@ -146,7 +150,8 @@
   BrowserBlacklistBeaconSetup();
 
   // The beacon should now be marked as enabled for the current version.
-  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());
+  ASSERT_EQ(static_cast<DWORD>(blacklist::BLACKLIST_ENABLED),
+            GetBlacklistState());
 
   base::string16 expected_version(
       base::UTF8ToUTF16(version_info::GetVersionNumber()));
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 3b10adaf..be0af73 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -581,7 +581,7 @@
 
 // Enables or disables Instant Tethering on Chrome OS.
 const base::Feature kInstantTethering{"InstantTethering",
-                                      base::FEATURE_ENABLED_BY_DEFAULT};
+                                      base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Enables or disables EasyUnlock promotions on Chrome OS.
 const base::Feature kEasyUnlockPromotions{"EasyUnlockPromotions",
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc
index acd02ea3..223bc65 100644
--- a/chrome/common/crash_keys.cc
+++ b/chrome/common/crash_keys.cc
@@ -28,8 +28,6 @@
 
 const char kActiveURL[] = "url-chunk";
 
-const char kFontKeyName[] = "font_key_name";
-
 const char kExtensionID[] = "extension-%" PRIuS;
 const char kNumExtensionsCount[] = "num-extensions";
 
@@ -37,11 +35,6 @@
 const char kBrowserUnpinTrace[] = "browser-unpin-trace";
 
 #if defined(OS_WIN)
-const char kHungRendererOutstandingAckCount[] = "hung-outstanding-acks";
-const char kHungRendererOutstandingEventType[] = "hung-outstanding-event-type";
-const char kHungRendererLastEventType[] = "hung-last-event-type";
-const char kHungRendererReason[] = "hung-reason";
-
 const char kIsEnterpriseManaged[] = "is-enterprise-managed";
 
 // Registry values used to determine Chrome's update channel; see
@@ -50,8 +43,6 @@
 const char kCohortName[] = "cohort-name";
 #endif
 
-const char kInputEventFilterSendFailure[] = "input-event-filter-send-failure";
-
 const char kPrinterInfo[] = "prn-info-%" PRIuS;
 
 const char kViewCount[] = "view-count";
@@ -103,27 +94,13 @@
     {gpu::crash_keys::kGPUGLContextIsVirtual, kSmallSize},
 
     // content/:
-    {"bad_message_reason", kSmallSize},
     {"discardable-memory-allocated", kSmallSize},
     {"discardable-memory-free", kSmallSize},
-    {kFontKeyName, kSmallSize},
-    {"mojo-message-error", kMediumSize},
-    {"ppapi_path", kMediumSize},
     {"subresource_url", kLargeSize},
     {"total-discardable-memory-allocated", kSmallSize},
 #if defined(OS_WIN)
-    {kHungRendererOutstandingAckCount, kSmallSize},
-    {kHungRendererOutstandingEventType, kSmallSize},
-    {kHungRendererLastEventType, kSmallSize},
-    {kHungRendererReason, kSmallSize},
     {kIsEnterpriseManaged, kSmallSize},
 #endif
-    {kInputEventFilterSendFailure, kSmallSize},
-#if defined(OS_MACOSX)
-    // content/:
-    {"text-input-context-client", kMediumSize},
-// media/:
-#endif
     {kViewCount, kSmallSize},
 
     // sandbox/:
@@ -143,10 +120,6 @@
 
     // TODO(sunnyps): Remove after fixing crbug.com/724999.
     {"gl-context-set-current-stack-trace", kMediumSize},
-
-    // Accessibility keys. Temporary for http://crbug.com/765490.
-    {"ax_tree_error", kSmallSize},
-    {"ax_tree_update", kMediumSize},
   };
 
   // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/chrome/common/crash_keys.h b/chrome/common/crash_keys.h
index ad277101..8a63d8b4 100644
--- a/chrome/common/crash_keys.h
+++ b/chrome/common/crash_keys.h
@@ -75,12 +75,6 @@
 #if defined(OS_WIN)
 extern const char kHungAudioThreadDetails[];
 
-// Hung renderer crash reports are only sent on Windows.
-extern const char kHungRendererOutstandingAckCount[];
-extern const char kHungRendererOutstandingEventType[];
-extern const char kHungRendererLastEventType[];
-extern const char kHungRendererReason[];
-
 // Whether the machine is enterprise managed (only sent on Windows).
 extern const char kIsEnterpriseManaged[];
 
@@ -91,10 +85,6 @@
 extern const char kCohortName[];
 #endif
 
-// Number of input event send IPC failures. Added to debug
-// crbug.com/615090.
-extern const char kInputEventFilterSendFailure[];
-
 // The user's printers, up to kPrinterInfoCount. Should be set with
 // ScopedPrinterInfo.
 const size_t kPrinterInfoCount = 4;
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl
index 04b60fe3..9b49a35b 100644
--- a/chrome/common/extensions/api/file_manager_private.idl
+++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -336,7 +336,10 @@
   // Id the provided file system (for provided file systems).
   DOMString? fileSystemId;
 
-  // Extension providing this volume (for provided file systems).
+  // ID of the provider, if the volume is backed by FSP.
+  DOMString? providerId;
+
+  // Extension ID of the provider if it is an extension.
   DOMString? extensionId;
 
   // Source of the volume's data.
@@ -563,12 +566,16 @@
   DOMString devicePath;
 };
 
-// Describes an installed providing extension.
-dictionary ProvidingExtension {
-  // ID of the providing extension.
-  DOMString extensionId;
+// Describes an installed provider.
+dictionary Provider {
+  // ID of the provider.
+  DOMString providerId;
 
-  // Name of the providing extension.
+  // ID of the providing extension, if the provider is an extension. Otherwise
+  // undefined.
+  DOMString? extensionId;
+
+  // Name of the provider.
   DOMString name;
 
   // Whether supports configuration dialog.
@@ -677,8 +684,8 @@
 // |checksum| Result checksum.
 callback ComputeChecksumCallback = void(DOMString checksum);
 
-// |extensions| List of providing extensions.
-callback GetProvidingExtensionsCallback = void(ProvidingExtension[] extensions);
+// |extensions| List of providers.
+callback GetProvidersCallback = void(Provider[] extensions);
 
 // |actions| List of actions.
 callback GetCustomActionsCallback = void(fileSystemProvider.Action[] actions);
@@ -989,12 +996,12 @@
   // Returns if Piex loader is enabled.
   static void isPiexLoaderEnabled(BooleanCallback callback);
 
-  // Returns list of available providing extensions.
-  static void getProvidingExtensions(GetProvidingExtensionsCallback callback);
+  // Returns list of available providers.
+  static void getProviders(GetProvidersCallback callback);
 
   // Requests adding a new provided file system. If not possible, then an error
   // via chrome.runtime.lastError is returned.
-  static void addProvidedFileSystem(DOMString extension_id,
+  static void addProvidedFileSystem(DOMString provider_id,
                                     SimpleCallback callback);
 
   // Requests configuring an existing volume. If not possible, then returns
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index e3ec676..a040394 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -17,6 +17,11 @@
 // *************** PROFILE PREFS ***************
 // These are attached to the user profile
 
+// A bool pref that indicates whether interventions for abusive experiences
+// should be enforced.
+const char kAbusiveExperienceInterventionEnforce[] =
+    "abusive_experience_intervention_enforce";
+
 // A bool pref that keeps whether the child status for this profile was already
 // successfully checked via ChildAccountService.
 const char kChildAccountStatusKnown[] = "child_account_status_known";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 0577830..b2c383fb 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -20,6 +20,7 @@
 namespace prefs {
 
 // Profile prefs. Please add Local State prefs below instead.
+extern const char kAbusiveExperienceInterventionEnforce[];
 extern const char kChildAccountStatusKnown[];
 extern const char kDefaultApps[];
 extern const char kSafeBrowsingForTrustedSourcesEnabled[];
diff --git a/chrome/common/printing/BUILD.gn b/chrome/common/printing/BUILD.gn
index 0599f9fa..7f4c2d53 100644
--- a/chrome/common/printing/BUILD.gn
+++ b/chrome/common/printing/BUILD.gn
@@ -7,10 +7,12 @@
 mojom("interfaces") {
   sources = [
     "pdf_render_settings.mojom",
+    "pdf_to_emf_converter.mojom",
     "pdf_to_pwg_raster_converter.mojom",
   ]
 
   deps = [
+    "//mojo/common:common_custom_types",
     "//ui/gfx/geometry/mojo",
   ]
 }
diff --git a/chrome/common/printing/pdf_to_emf_converter.mojom b/chrome/common/printing/pdf_to_emf_converter.mojom
new file mode 100644
index 0000000..8784d237
--- /dev/null
+++ b/chrome/common/printing/pdf_to_emf_converter.mojom
@@ -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.
+
+module printing.mojom;
+
+import "chrome/common/printing/pdf_render_settings.mojom";
+import "mojo/common/string16.mojom";
+
+// This set of interfaces is used to convert PDF files to EMF.
+// Usage:
+// - generate a PdfToEmfConverter by binding the PdfToEmfConverterFactory
+//   interface and calling PdfToEmfConverterFactory.CreateConverter(). This also
+//   returns the number of pages that will be generated.
+// - call PdfToEmfConverter.ConvertPage() for each page to generate the EMF
+//   files.
+
+interface PdfToEmfConverterClient {
+  [Sync]
+  PreCacheFontCharacters(array<uint8> logfont,
+                         mojo.common.mojom.String16 characters) => ();
+};
+
+interface PdfToEmfConverter {
+  ConvertPage(uint32 page_number, handle emf_file_out) =>
+      (bool success, float scale_factor);
+};
+
+interface PdfToEmfConverterFactory {
+  CreateConverter(handle pdf_file_in, PdfRenderSettings render_settings,
+         PdfToEmfConverterClient client) => (PdfToEmfConverter converter,
+            uint32 page_count);
+};
diff --git a/chrome/installer/util/l10n_string_util_unittest.cc b/chrome/installer/util/l10n_string_util_unittest.cc
index 688c97de..4dfb650 100644
--- a/chrome/installer/util/l10n_string_util_unittest.cc
+++ b/chrome/installer/util/l10n_string_util_unittest.cc
@@ -69,7 +69,8 @@
 
   // Run through all install modes, checking that the mode-specific strings are
   // mapped properly by GetBaseMessageIdForMode.
-  ASSERT_EQ(install_static::NUM_INSTALL_MODES, mode_to_strings.size());
+  ASSERT_EQ(static_cast<size_t>(install_static::NUM_INSTALL_MODES),
+            mode_to_strings.size());
   for (int mode_index = 0; mode_index < install_static::NUM_INSTALL_MODES;
        ++mode_index) {
     SCOPED_TRACE(testing::Message() << "install mode index: " << mode_index);
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index af191503..e328c5e 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -1217,6 +1217,256 @@
     EXPECT_EQ(5, input_element.SelectionEnd());
   }
 
+  void TestFillFormAndModifyValues(const char* html,
+                                   const char* placeholder_firstname,
+                                   const char* placeholder_lastname,
+                                   const char* placeholder_phone,
+                                   const char* placeholder_creditcard) {
+    LoadHTML(html);
+    WebLocalFrame* web_frame = GetMainFrame();
+    ASSERT_NE(nullptr, web_frame);
+
+    FormCache form_cache(web_frame);
+    std::vector<FormData> forms = form_cache.ExtractNewForms();
+    ASSERT_EQ(1U, forms.size());
+
+    // Get the input element we want to find.
+    WebInputElement input_element = GetInputElementById("firstname");
+    WebFormElement form_element = input_element.Form();
+    std::vector<WebFormControlElement> control_elements =
+        ExtractAutofillableElementsInForm(form_element);
+
+    ASSERT_EQ(4U, control_elements.size());
+    // We now modify the values.
+    // This will be ignored.
+    control_elements[0].SetValue(WebString::FromUTF16(
+        base::char16(base::i18n::kLeftToRightMark) + ASCIIToUTF16("     ")));
+    // This will be considered as a value entered by the user.
+    control_elements[1].SetValue(WebString::FromUTF16(ASCIIToUTF16("Earp")));
+    // This will be ignored.
+    control_elements[2].SetValue(
+        WebString::FromUTF16(ASCIIToUTF16("(___)-___-____")));
+    // This will be ignored.
+    control_elements[3].SetValue(
+        WebString::FromUTF16(ASCIIToUTF16("____-____-____-____")));
+
+    // Find the form that contains the input element.
+    FormData form;
+    FormFieldData field;
+    EXPECT_TRUE(
+        FindFormAndFieldForFormControlElement(input_element, &form, &field));
+    EXPECT_EQ(GetCanonicalOriginForDocument(web_frame->GetDocument()),
+              form.origin);
+    EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
+    EXPECT_EQ(GURL("http://abc.com"), form.action);
+
+    const std::vector<FormFieldData>& fields = form.fields;
+    ASSERT_EQ(4U, fields.size());
+
+    // Preview the form and verify that the cursor position has been updated.
+    form.fields[0].value = ASCIIToUTF16("Wyatt");
+    form.fields[1].value = ASCIIToUTF16("Earpagus");
+    form.fields[2].value = ASCIIToUTF16("888-123-4567");
+    form.fields[3].value = ASCIIToUTF16("1111-2222-3333-4444");
+    form.fields[0].is_autofilled = true;
+    form.fields[1].is_autofilled = true;
+    form.fields[2].is_autofilled = true;
+    form.fields[3].is_autofilled = true;
+    PreviewForm(form, input_element);
+    // Since the suggestion is previewed as a placeholder, there should be no
+    // selected text.
+    EXPECT_EQ(0, input_element.SelectionStart());
+    EXPECT_EQ(0, input_element.SelectionEnd());
+
+    // Fill the form.
+    FillForm(form, input_element);
+
+    // Find the newly-filled form that contains the input element.
+    FormData form2;
+    FormFieldData field2;
+    EXPECT_TRUE(
+        FindFormAndFieldForFormControlElement(input_element, &form2, &field2));
+    EXPECT_EQ(GetCanonicalOriginForDocument(web_frame->GetDocument()),
+              form2.origin);
+    EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
+    EXPECT_EQ(GURL("http://abc.com"), form2.action);
+
+    const std::vector<FormFieldData>& fields2 = form2.fields;
+    ASSERT_EQ(4U, fields2.size());
+
+    FormFieldData expected;
+    expected.form_control_type = "text";
+    expected.max_length = WebInputElement::DefaultMaxLength();
+
+    expected.name = ASCIIToUTF16("firstname");
+    expected.value = ASCIIToUTF16("Wyatt");
+    if (placeholder_firstname) {
+      expected.label = ASCIIToUTF16(placeholder_firstname);
+      expected.placeholder = ASCIIToUTF16(placeholder_firstname);
+    } else {
+      expected.label.clear();
+      expected.placeholder.clear();
+    }
+    expected.is_autofilled = true;
+    EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
+
+    // The last name field is not filled, because there is a value in it.
+    expected.name = ASCIIToUTF16("lastname");
+    expected.value = ASCIIToUTF16("Earp");
+    if (placeholder_lastname) {
+      expected.label = ASCIIToUTF16(placeholder_lastname);
+      expected.placeholder = ASCIIToUTF16(placeholder_lastname);
+    } else {
+      expected.label.clear();
+      expected.placeholder.clear();
+    }
+    expected.is_autofilled = false;
+    EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
+
+    expected.name = ASCIIToUTF16("phone");
+    expected.value = ASCIIToUTF16("888-123-4567");
+    if (placeholder_phone) {
+      expected.label = ASCIIToUTF16(placeholder_phone);
+      expected.placeholder = ASCIIToUTF16(placeholder_phone);
+    } else {
+      expected.label.clear();
+      expected.placeholder.clear();
+    }
+    expected.is_autofilled = true;
+    EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
+
+    expected.name = ASCIIToUTF16("cc");
+    expected.value = ASCIIToUTF16("1111-2222-3333-4444");
+    if (placeholder_creditcard) {
+      expected.label = ASCIIToUTF16(placeholder_creditcard);
+      expected.placeholder = ASCIIToUTF16(placeholder_creditcard);
+    } else {
+      expected.label.clear();
+      expected.placeholder.clear();
+    }
+    expected.is_autofilled = true;
+    EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[3]);
+
+    // Verify that the cursor position has been updated.
+    EXPECT_EQ(5, input_element.SelectionStart());
+    EXPECT_EQ(5, input_element.SelectionEnd());
+  }
+
+  void TestFillFormAndModifyInitiatingValue(const char* html,
+                                            const char* placeholder_creditcard,
+                                            const char* placeholder_expiration,
+                                            const char* placeholder_name) {
+    LoadHTML(html);
+    WebLocalFrame* web_frame = GetMainFrame();
+    ASSERT_NE(nullptr, web_frame);
+
+    FormCache form_cache(web_frame);
+    std::vector<FormData> forms = form_cache.ExtractNewForms();
+    ASSERT_EQ(1U, forms.size());
+
+    // Get the input element we want to find.
+    WebInputElement input_element = GetInputElementById("cc");
+    WebFormElement form_element = input_element.Form();
+    std::vector<WebFormControlElement> control_elements =
+        ExtractAutofillableElementsInForm(form_element);
+
+    ASSERT_EQ(3U, control_elements.size());
+    // We now modify the values.
+    // This will be ignored.
+    control_elements[0].SetValue(
+        WebString::FromUTF16(ASCIIToUTF16("____-____-____-____")));
+    // This will be ignored.
+    control_elements[1].SetValue(WebString::FromUTF16(ASCIIToUTF16("____/__")));
+    control_elements[2].SetValue(
+        WebString::FromUTF16(ASCIIToUTF16("John Smith")));
+
+    // Find the form that contains the input element.
+    FormData form;
+    FormFieldData field;
+    EXPECT_TRUE(
+        FindFormAndFieldForFormControlElement(input_element, &form, &field));
+    EXPECT_EQ(GetCanonicalOriginForDocument(web_frame->GetDocument()),
+              form.origin);
+    EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
+    EXPECT_EQ(GURL("http://abc.com"), form.action);
+
+    const std::vector<FormFieldData>& fields = form.fields;
+    ASSERT_EQ(3U, fields.size());
+
+    // Preview the form and verify that the cursor position has been updated.
+    form.fields[0].value = ASCIIToUTF16("1111-2222-3333-4444");
+    form.fields[1].value = ASCIIToUTF16("03/2030");
+    form.fields[2].value = ASCIIToUTF16("Susan Smith");
+    form.fields[0].is_autofilled = true;
+    form.fields[1].is_autofilled = true;
+    form.fields[2].is_autofilled = true;
+    PreviewForm(form, input_element);
+    // Since the suggestion is previewed as a placeholder, there should be no
+    // selected text.
+    EXPECT_EQ(0, input_element.SelectionStart());
+    EXPECT_EQ(0, input_element.SelectionEnd());
+
+    // Fill the form.
+    FillForm(form, input_element);
+
+    // Find the newly-filled form that contains the input element.
+    FormData form2;
+    FormFieldData field2;
+    EXPECT_TRUE(
+        FindFormAndFieldForFormControlElement(input_element, &form2, &field2));
+    EXPECT_EQ(GetCanonicalOriginForDocument(web_frame->GetDocument()),
+              form2.origin);
+    EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
+    EXPECT_EQ(GURL("http://abc.com"), form2.action);
+
+    const std::vector<FormFieldData>& fields2 = form2.fields;
+    ASSERT_EQ(3U, fields2.size());
+
+    FormFieldData expected;
+    expected.form_control_type = "text";
+    expected.max_length = WebInputElement::DefaultMaxLength();
+
+    expected.name = ASCIIToUTF16("cc");
+    expected.value = ASCIIToUTF16("1111-2222-3333-4444");
+    if (placeholder_creditcard) {
+      expected.label = ASCIIToUTF16(placeholder_creditcard);
+      expected.placeholder = ASCIIToUTF16(placeholder_creditcard);
+    } else {
+      expected.label.clear();
+      expected.placeholder.clear();
+    }
+    expected.is_autofilled = true;
+    EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
+
+    expected.name = ASCIIToUTF16("expiration_date");
+    expected.value = ASCIIToUTF16("03/2030");
+    if (placeholder_expiration) {
+      expected.label = ASCIIToUTF16(placeholder_expiration);
+      expected.placeholder = ASCIIToUTF16(placeholder_expiration);
+    } else {
+      expected.label.clear();
+      expected.placeholder.clear();
+    }
+    expected.is_autofilled = true;
+    EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
+
+    expected.name = ASCIIToUTF16("name");
+    expected.value = ASCIIToUTF16("John Smith");
+    if (placeholder_name) {
+      expected.label = ASCIIToUTF16(placeholder_name);
+      expected.placeholder = ASCIIToUTF16(placeholder_name);
+    } else {
+      expected.label.clear();
+      expected.placeholder.clear();
+    }
+    expected.is_autofilled = false;
+    EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
+
+    // Verify that the cursor position has been updated.
+    EXPECT_EQ(19, input_element.SelectionStart());
+    EXPECT_EQ(19, input_element.SelectionEnd());
+  }
+
   void TestClearFormWithNode(const char* html, bool unowned) {
     LoadHTML(html);
     WebLocalFrame* web_frame = GetMainFrame();
@@ -4150,6 +4400,35 @@
       false, "Enter last name", "Enter email", nullptr, nullptr, nullptr);
 }
 
+TEST_F(FormAutofillTest, FillFormModifyValues) {
+  TestFillFormAndModifyValues(
+      "<FORM name='TestForm' action='http://abc.com' method='post'>"
+      "  <INPUT type='text' id='firstname' placeholder='First Name' "
+      "value='First Name'/>"
+      "  <INPUT type='text' id='lastname' placeholder='Last Name' value='Last "
+      "Name'/>"
+      "  <INPUT type='text' id='phone' placeholder='Phone' value='Phone'/>"
+      "  <INPUT type='text' id='cc' placeholder='Credit Card Number' "
+      "value='Credit Card'/>"
+      "  <INPUT type='submit' value='Send'/>"
+      "</FORM>",
+      "First Name", "Last Name", "Phone", "Credit Card Number");
+}
+
+TEST_F(FormAutofillTest, FillFormModifyInitiatingValue) {
+  TestFillFormAndModifyInitiatingValue(
+      "<FORM name='TestForm' action='http://abc.com' method='post'>"
+      "  <INPUT type='text' id='cc' placeholder='Credit Card Number' "
+      "value='Credit Card'/>"
+      "  <INPUT type='text' id='expiration_date' placeholder='Expiration Date' "
+      "value='Expiration Date'/>"
+      "  <INPUT type='text' id='name' placeholder='Full Name' "
+      "value='Full Name'/>"
+      "  <INPUT type='submit' value='Send'/>"
+      "</FORM>",
+      "Credit Card Number", "Expiration Date", "Full Name");
+}
+
 TEST_F(FormAutofillTest, FillFormNonEmptyFieldsWithPlaceholderValues) {
   TestFillFormNonEmptyField(
       "<FORM name='TestForm' action='http://abc.com' method='post'>"
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc
index 1470aff..1f5077d 100644
--- a/chrome/renderer/net/net_error_helper.cc
+++ b/chrome/renderer/net/net_error_helper.cc
@@ -351,6 +351,7 @@
 
   blink::WebURLRequest request(page_url);
   request.SetCacheMode(blink::mojom::FetchCacheMode::kOnlyIfCached);
+  request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(page_url));
   web_frame->LoadRequest(request);
 }
 
diff --git a/chrome/renderer/resources/extensions/media_router_bindings.js b/chrome/renderer/resources/extensions/media_router_bindings.js
index d2b8580..b28b6d31 100644
--- a/chrome/renderer/resources/extensions/media_router_bindings.js
+++ b/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -754,8 +754,11 @@
       this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then(
           function(response) {
             return {
-              'enable_dial_discovery': response.enableDialDiscovery,
-              'enable_cast_discovery': response.enableCastDiscovery,
+              'instance_id': response.instanceId,
+              'config': {
+                'enable_dial_discovery': response.config.enableDialDiscovery,
+                'enable_cast_discovery': response.config.enableCastDiscovery,
+              }
             };
           });
 }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 1d38906..5ec9dfe 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -672,6 +672,7 @@
 
       # If this list is used on Android in the future, these browser/speech/*
       # files will probably not be applicable.
+      "../browser/chrome_network_service_restart_browsertest.cc",
       "../browser/net/network_connection_tracker_browsertest.cc",
       "../browser/speech/extension_api/tts_extension_apitest.cc",
       "../browser/speech/speech_recognition_browsertest.cc",
@@ -2114,6 +2115,7 @@
     "../browser/android/ntp/content_suggestions_notifier_service_unittest.cc",
     "../browser/android/ntp/content_suggestions_notifier_unittest.cc",
     "../browser/android/oom_intervention/near_oom_monitor_unittest.cc",
+    "../browser/android/oom_intervention/oom_intervention_decider_unittest.cc",
     "../browser/android/physical_web/eddystone_encoder_bridge_unittest.cc",
     "../browser/android/physical_web/physical_web_data_source_android_unittest.cc",
     "../browser/android/preferences/pref_service_bridge_unittest.cc",
@@ -2660,7 +2662,10 @@
   }
 
   if (enable_dice_support) {
-    sources += [ "../browser/signin/dice_response_handler_unittest.cc" ]
+    sources += [
+      "../browser/signin/dice_response_handler_unittest.cc",
+      "../browser/signin/dice_tab_helper_unittest.cc",
+    ]
   }
 
   if (enable_offline_pages) {
@@ -2752,6 +2757,7 @@
       "../browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc",
       "../browser/resource_coordinator/background_tab_navigation_throttle_unittest.cc",
       "../browser/resource_coordinator/lifecycle_unit_unittest.cc",
+      "../browser/resource_coordinator/tab_lifecycle_unit_unittest.cc",
       "../browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc",
       "../browser/resource_coordinator/tab_manager_stats_collector_unittest.cc",
       "../browser/resource_coordinator/tab_manager_unittest.cc",
@@ -2932,8 +2938,6 @@
       "../browser/media/router/discovery/mdns/dns_sd_registry_unittest.cc",
       "../browser/media/router/discovery/media_sink_discovery_metrics_unittest.cc",
       "../browser/media/router/event_page_request_manager_unittest.cc",
-      "../common/media_router/discovery/media_sink_internal_unittest.cc",
-      "../common/media_router/discovery/media_sink_service_base_unittest.cc",
       "../browser/media/router/mojo/extension_media_route_provider_proxy_unittest.cc",
       "../browser/media/router/mojo/media_route_controller_unittest.cc",
       "../browser/media/router/mojo/media_router_desktop_unittest.cc",
@@ -2961,6 +2965,8 @@
       "../browser/ui/webui/media_router/media_router_web_ui_test.h",
       "../browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc",
       "../browser/ui/webui/media_router/query_result_manager_unittest.cc",
+      "../common/media_router/discovery/media_sink_internal_unittest.cc",
+      "../common/media_router/discovery/media_sink_service_base_unittest.cc",
       "../common/media_router/mojo/media_router_struct_traits_unittest.cc",
     ]
     deps += [ "//components/bubble:test_support" ]
@@ -3444,7 +3450,7 @@
     ]
   }
   if (use_gio) {
-    deps += [ "//build/linux/libgio" ]
+    configs += [ "//build/linux:gio_config" ]
   }
   if (!is_chromeos && !use_ozone && is_linux) {
     deps += [ "//chrome/browser/ui/libgtkui" ]
diff --git a/chrome/test/chromedriver/net/websocket.cc b/chrome/test/chromedriver/net/websocket.cc
index 6e15f3dd..b24b43c 100644
--- a/chrome/test/chromedriver/net/websocket.cc
+++ b/chrome/test/chromedriver/net/websocket.cc
@@ -30,6 +30,7 @@
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
 #include "net/log/net_log_source.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/websockets/websocket_frame.h"
 
 #if defined(OS_WIN)
@@ -182,9 +183,9 @@
     pending_write_.clear();
   }
   int code =
-      socket_->Write(write_buffer_.get(),
-                     write_buffer_->BytesRemaining(),
-                     base::Bind(&WebSocket::OnWrite, base::Unretained(this)));
+      socket_->Write(write_buffer_.get(), write_buffer_->BytesRemaining(),
+                     base::Bind(&WebSocket::OnWrite, base::Unretained(this)),
+                     TRAFFIC_ANNOTATION_FOR_TESTS);
   if (code != net::ERR_IO_PENDING)
     OnWrite(code);
 }
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 59ab731a..b737f36 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -97,6 +97,8 @@
 _VERSION_SPECIFIC_FILTER['63'] = [
     # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2025
     'ChromeDriverTest.testDoesntHangOnFragmentNavigation',
+    'ChromeDriverPageLoadTimeoutTest.testHistoryNavigationWithPageLoadTimeout',
+    'ChromeDriverPageLoadTimeoutTest.testRefreshWithPageLoadTimeout',
 ]
 
 _OS_SPECIFIC_FILTER = {}
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations
index 04ab70f6..5551350 100644
--- a/chrome/test/chromedriver/test/test_expectations
+++ b/chrome/test/chromedriver/test/test_expectations
@@ -274,6 +274,9 @@
         'CorrectEventFiringTest.testShouldReportTheXAndYCoordinatesWhenClicking',
         # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2077
         'CorrectEventFiringTest.testShouldEmitClickEventWhenClickingOnATextInputElement',
+        # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2025
+        'MiscTest.testStimulatesStrangeOnloadInteractionInFirefox',
+        'PageLoadingTest.testShouldNotHangIfDocumentOpenCallIsNeverFollowedByDocumentCloseCall',
     ]
 )
 
diff --git a/chrome/test/data/extensions/api_test/file_browser/mount_test/test.js b/chrome/test/data/extensions/api_test/file_browser/mount_test/test.js
index 634498a..8d73698 100644
--- a/chrome/test/data/extensions/api_test/file_browser/mount_test/test.js
+++ b/chrome/test/data/extensions/api_test/file_browser/mount_test/test.js
@@ -112,6 +112,7 @@
   hasMedia: false,
   configurable: true,
   watchable: false,
+  providerId: 'testing-extension-id',
   extensionId: 'testing-extension-id',
   source: 'network',
   mountContext: 'auto',
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/configure/test.js b/chrome/test/data/extensions/api_test/file_system_provider/configure/test.js
index 413e62c..95631d8 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/configure/test.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/configure/test.js
@@ -30,15 +30,15 @@
       chrome.fileSystemProvider.onConfigureRequested.addListener(
           onConfigureRequested);
 
-      chrome.fileManagerPrivate.getProvidingExtensions(
-          chrome.test.callbackPass(function(extensions) {
-            chrome.test.assertEq(extensions.length, 1);
-            chrome.test.assertEq(chrome.runtime.id, extensions[0].extensionId);
+      chrome.fileManagerPrivate.getProviders(
+          chrome.test.callbackPass(function(providers) {
+            chrome.test.assertEq(providers.length, 1);
+            chrome.test.assertEq(chrome.runtime.id, providers[0].extensionId);
             chrome.test.assertEq(
-                chrome.runtime.getManifest().name, extensions[0].name);
-            chrome.test.assertTrue(extensions[0].configurable);
-            chrome.test.assertFalse(extensions[0].multipleMounts);
-            chrome.test.assertEq('device', extensions[0].source);
+                chrome.runtime.getManifest().name, providers[0].name);
+            chrome.test.assertTrue(providers[0].configurable);
+            chrome.test.assertFalse(providers[0].multipleMounts);
+            chrome.test.assertEq('device', providers[0].source);
           }));
 
       chrome.fileManagerPrivate.configureVolume(test_util.volumeId,
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/mount/test.js b/chrome/test/data/extensions/api_test/file_system_provider/mount/test.js
index 0a968c6b..df7c3b6 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/mount/test.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/mount/test.js
@@ -147,16 +147,16 @@
 
     chrome.fileSystemProvider.onMountRequested.addListener(
         onMountRequested);
-    chrome.fileManagerPrivate.getProvidingExtensions(
-        chrome.test.callbackPass(function(extensions) {
-          chrome.test.assertEq(extensions.length, 1);
-          chrome.test.assertEq(chrome.runtime.id, extensions[0].extensionId);
+    chrome.fileManagerPrivate.getProviders(
+        chrome.test.callbackPass(function(providers) {
+          chrome.test.assertEq(providers.length, 1);
+          chrome.test.assertEq(chrome.runtime.id, providers[0].extensionId);
           chrome.test.assertEq(
-              chrome.runtime.getManifest().name, extensions[0].name);
-          chrome.test.assertFalse(extensions[0].configurable);
-          chrome.test.assertFalse(extensions[0].watchable);
-          chrome.test.assertFalse(extensions[0].multipleMounts);
-          chrome.test.assertEq('network', extensions[0].source);
+              chrome.runtime.getManifest().name, providers[0].name);
+          chrome.test.assertFalse(providers[0].configurable);
+          chrome.test.assertFalse(providers[0].watchable);
+          chrome.test.assertFalse(providers[0].multipleMounts);
+          chrome.test.assertEq('network', providers[0].source);
         }));
 
     chrome.fileManagerPrivate.addProvidedFileSystem(
diff --git a/chrome/test/data/extensions/api_test/webrequest/framework.js b/chrome/test/data/extensions/api_test/webrequest/framework.js
index 4aec309..ec2a03f4 100644
--- a/chrome/test/data/extensions/api_test/webrequest/framework.js
+++ b/chrome/test/data/extensions/api_test/webrequest/framework.js
@@ -13,7 +13,6 @@
 var frameIdMap;
 var testWebSocketPort;
 var testServerPort;
-var usingBrowserSideNavigation = false;
 var testServer = "www.a.com";
 var defaultScheme = "http";
 var eventsCaptured;
@@ -53,7 +52,6 @@
   chrome.test.getConfig(function(config) {
     testServerPort = config.testServer.port;
     testWebSocketPort = config.testWebSocketPort;
-    usingBrowserSideNavigation = config.browserSideNavigationEnabled;
     chrome.test.runTests(tests);
   });
 }
@@ -89,27 +87,23 @@
     throw new Error("Unknown navigation type.");
 }
 
-// Similar to getURL without the path. If tests are run with
-// --enable-browser-side-navigation (PlzNavigate) browser initiated navigation
-// will have no initiator. The |navigationType| specifies if the navigation was
-// performed by the browser or the renderer.
+// Similar to getURL without the path. The |navigationType| specifies if the
+// navigation was performed by the browser or the renderer. A browser initiated
+// navigation doesn't have an initiator.
 function getDomain(navigationType) {
   validateNavigationType(navigationType);
-  if (navigationType == initiators.BROWSER_INITIATED &&
-      usingBrowserSideNavigation)
+  if (navigationType == initiators.BROWSER_INITIATED)
     return undefined;
   else
     return getURL('').slice(0,-1);
 }
 
-// Similar to getServerURL without the path. If tests are run with
-// --enable-browser-side-navigation (PlzNavigate) browser initiated navigation
-// will have no initiator. The |navigationType| specifies if the navigation was
-// performed by the browser or the renderer.
+// Similar to getServerURL without the path. The |navigationType| specifies if
+// the navigation was performed by the browser or the renderer. A browser
+// initiated navigation doesn't have an initiator.
 function getServerDomain(navigationType, opt_host, opt_scheme) {
   validateNavigationType(navigationType);
-  if (navigationType == initiators.BROWSER_INITIATED &&
-      usingBrowserSideNavigation)
+  if (navigationType == initiators.BROWSER_INITIATED)
     return undefined;
   else
     return getServerURL(undefined, opt_host, opt_scheme).slice(0, -1);
diff --git a/chrome/test/data/local_ntp/local_ntp_browsertest.html b/chrome/test/data/local_ntp/local_ntp_browsertest.html
index d0e3b83..94f9f301 100644
--- a/chrome/test/data/local_ntp/local_ntp_browsertest.html
+++ b/chrome/test/data/local_ntp/local_ntp_browsertest.html
@@ -5,11 +5,11 @@
      found in the LICENSE file. -->
 <head>
   <script>window.localNTPUnitTest = true;</script>
-  <script src="chrome-search://local-ntp/config.js" charset="utf-8"></script>
+  <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp.css"></link>
+  <link rel="stylesheet" href="chrome-search://local-ntp/voice.css"></link>
   <script src="chrome-search://local-ntp/local-ntp.js" charset="utf-8"></script>
   <script src="chrome-search://local-ntp/voice.js" charset="utf-8"></script>
-  <script src="chrome-search://most-visited/util.js" charset="utf-8"></script>
-  <link rel="stylesheet" href="chrome-search://local-ntp/local-ntp.css"></link>
+  <script src="chrome-search://local-ntp/config.js" charset="utf-8"></script>
   <script src="test_utils.js" charset="utf-8"></script>
   <script src="local_ntp_browsertest.js" charset="utf-8"></script>
   <template id="local-ntp-template">
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 8eecc4e..f8d0205 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3390,6 +3390,16 @@
     ]
   },
 
+  "AbusiveExperienceInterventionEnforce": {
+    "os": ["win", "linux", "mac", "chromeos"],
+    "test_policy": {
+      "AbusiveExperienceInterventionEnforce": false
+    },
+    "pref_mappings": [
+      { "pref": "abusive_experience_intervention_enforce"}
+    ]
+  },
+
   "----- Chrome Frame policies -------------------------------------------": {},
 
   "ChromeFrameRendererSettings": {
diff --git a/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js b/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js
index d67ddf98..1a7f226 100644
--- a/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js
+++ b/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-var ROOT_PATH = '../../../../../';
+const ROOT_PATH = '../../../../../';
 
 GEN_INCLUDE(
         [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
@@ -27,21 +27,20 @@
   extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([
       ROOT_PATH + 'chrome/test/data/webui/test_browser_proxy.js',
       'native_layer_stub.js',
+      ROOT_PATH + 'chrome/test/data/webui/settings/test_util.js',
     ]),
 
 };
 
-TEST_F('PrintPreviewDestinationSearchTest', 'Select', function() {
-  var self = this;
-
+TEST_F('PrintPreviewDestinationSearchTest', 'Select', function(){
   suite('DestinationSearchTest', function() {
-    var root_;
+    let root_;
 
-    var destinationSearch_;
-    var nativeLayer_;
-    var invitationStore_;
-    var destinationStore_;
-    var userInfo_;
+    let destinationSearch_;
+    let nativeLayer_;
+    let invitationStore_;
+    let destinationStore_;
+    let userInfo_;
 
     function getCaps() {
       return {
@@ -91,22 +90,11 @@
       };
     }
 
-    function waitForEvent(element, eventName) {
-      return new Promise(function(resolve) {
-        var listener = function(e) {
-          resolve();
-          element.removeEventListener(eventName, listener);
-        };
-
-        element.addEventListener(eventName, listener);
-      });
-    }
-
     function requestSetup(destId, destinationSearch) {
-      var origin = cr.isChromeOS ? print_preview.DestinationOrigin.CROS :
+      const origin = cr.isChromeOS ? print_preview.DestinationOrigin.CROS :
                                    print_preview.DestinationOrigin.LOCAL;
 
-      var dest = new print_preview.Destination(destId,
+      const dest = new print_preview.Destination(destId,
           print_preview.DestinationType.LOCAL,
           origin,
           "displayName",
@@ -128,17 +116,17 @@
       print_preview.NativeLayer.setInstance(nativeLayer_);
       invitationStore_ = new print_preview.InvitationStore();
       destinationStore_ = new print_preview.DestinationStore(
-          new print_preview.UserInfo(), new print_preview.AppState(),
-          new WebUIListenerTracker());
+          new print_preview.UserInfo(), new WebUIListenerTracker());
       userInfo_ = new print_preview.UserInfo();
 
       destinationSearch_ = new print_preview.DestinationSearch(
-          destinationStore_, invitationStore_, userInfo_);
+          destinationStore_, invitationStore_, userInfo_,
+          new print_preview.AppState(destinationStore_));
       destinationSearch_.decorate($('destination-search'));
     });
 
     test('ResolutionFails', function() {
-      var destId = "001122DEADBEEF";
+      const destId = "001122DEADBEEF";
       if (cr.isChromeOS) {
         nativeLayer_.setSetupPrinterResponse(true, {printerId: destId,
                                                     success: false,});
@@ -150,7 +138,8 @@
                                                      true);
       }
       requestSetup(destId, destinationSearch_);
-      var callback = cr.isChromeOS ? 'setupPrinter' : 'getPrinterCapabilities';
+      const callback =
+          cr.isChromeOS ? 'setupPrinter' : 'getPrinterCapabilities';
       return nativeLayer_.whenCalled(callback).then(
           function(actualDestId) {
             assertEquals(destId, actualDestId);
@@ -158,8 +147,8 @@
     });
 
     test('ReceiveSuccessfulSetup', function() {
-      var destId = "00112233DEADBEEF";
-      var response = {
+      const destId = "00112233DEADBEEF";
+      const response = {
         printerId: destId,
         capabilities: getCaps(),
         success: true,
@@ -172,11 +161,12 @@
                                                       },
                                                       capabilities: getCaps()});
 
-      var waiter = waitForEvent(
-          destinationStore_,
-          print_preview.DestinationStore.EventType.DESTINATION_SELECT);
+      const waiter = test_util.eventToPromise(
+          print_preview.DestinationStore.EventType.DESTINATION_SELECT,
+          destinationStore_);
       requestSetup(destId, destinationSearch_);
-      var callback = cr.isChromeOS ? 'setupPrinter' : 'getPrinterCapabilities';
+      const callback =
+          cr.isChromeOS ? 'setupPrinter' : 'getPrinterCapabilities';
       return Promise.all([nativeLayer_.whenCalled(callback), waiter]).then(
           function(results) {
             assertEquals(destId, results[0]);
@@ -189,8 +179,8 @@
     if (cr.isChromeOS) {
       // The 'ResolutionFails' test covers this case for non-CrOS.
       test('ReceiveFailedSetup', function() {
-        var destId = '00112233DEADBEEF';
-        var response = {
+        const destId = '00112233DEADBEEF';
+        const response = {
           printerId: destId,
           capabilities: getCaps(),
           success: false,
@@ -207,10 +197,10 @@
     }
 
     test('CloudKioskPrinter', function() {
-      var printerId = 'cloud-printer-id';
+      const printerId = 'cloud-printer-id';
 
       // Create cloud destination.
-      var cloudDest = new print_preview.Destination(printerId,
+      const cloudDest = new print_preview.Destination(printerId,
           print_preview.DestinationType.GOOGLE,
           print_preview.DestinationOrigin.DEVICE,
           "displayName",
@@ -219,7 +209,7 @@
 
       // Place destination in the local list as happens for Kiosk printers.
       destinationSearch_.printList_.updateDestinations([cloudDest]);
-      var dest = destinationSearch_.printList_.getDestinationItem(printerId);
+      const dest = destinationSearch_.printList_.getDestinationItem(printerId);
       // Simulate a click.
       dest.onActivate_();
 
diff --git a/chrome/test/data/webui/settings/chrome_cleanup_page_test.js b/chrome/test/data/webui/settings/chrome_cleanup_page_test.js
index 06a742b..7f3c7a7 100644
--- a/chrome/test/data/webui/settings/chrome_cleanup_page_test.js
+++ b/chrome/test/data/webui/settings/chrome_cleanup_page_test.js
@@ -11,6 +11,7 @@
       'restartComputer',
       'setLogsUploadPermission',
       'startCleanup',
+      'startScanning',
       'notifyShowDetails',
       'notifyLearnMoreClicked',
     ]);
@@ -42,6 +43,11 @@
   }
 
   /** @override */
+  startScanning(logsUploadEnabled) {
+    this.methodCalled('startScanning', logsUploadEnabled);
+  }
+
+  /** @override */
   notifyShowDetails(enabled) {
     this.methodCalled('notifyShowDetails', enabled);
   }
@@ -57,104 +63,284 @@
 /** @type {?TestDownloadsBrowserProxy} */
 var ChromeCleanupProxy = null;
 
-suite('ChromeCleanupHandler', function() {
-  setup(function() {
-    ChromeCleanupProxy = new TestChromeCleanupProxy();
-    settings.ChromeCleanupProxyImpl.instance_ = ChromeCleanupProxy;
+function initParametrizedTest(userInitiatedCleanupsEnabled) {
+  ChromeCleanupProxy = new TestChromeCleanupProxy();
+  settings.ChromeCleanupProxyImpl.instance_ = ChromeCleanupProxy;
 
-    PolymerTest.clearBody();
+  PolymerTest.clearBody();
 
-    chromeCleanupPage = document.createElement('settings-chrome-cleanup-page');
-    document.body.appendChild(chromeCleanupPage);
+  loadTimeData.overrideValues({
+    userInitiatedCleanupsEnabled: userInitiatedCleanupsEnabled,
   });
 
-  teardown(function() {
-    chromeCleanupPage.remove();
+  chromeCleanupPage = document.createElement('settings-chrome-cleanup-page');
+  document.body.appendChild(chromeCleanupPage);
+}
+
+function startCleanupFromInfected() {
+  cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false);
+  cr.webUIListenerCallback(
+      'chrome-cleanup-on-infected', ['file 1', 'file 2', 'file 3']);
+  Polymer.dom.flush();
+
+  var showFilesButton = chromeCleanupPage.$$('#show-files-button');
+  assertTrue(!!showFilesButton);
+  MockInteractions.tap(showFilesButton);
+  filesToRemove = chromeCleanupPage.$$('#files-to-remove-list');
+  assertTrue(!!filesToRemove);
+  assertEquals(filesToRemove.getElementsByTagName('li').length, 3);
+
+  var actionButton = chromeCleanupPage.$$('#action-button');
+  assertTrue(!!actionButton);
+  MockInteractions.tap(actionButton);
+  return ChromeCleanupProxy.whenCalled('startCleanup')
+      .then(function(logsUploadEnabled) {
+        assertFalse(logsUploadEnabled);
+        cr.webUIListenerCallback('chrome-cleanup-on-cleaning', false);
+        Polymer.dom.flush();
+
+        var spinner = chromeCleanupPage.$$('#waiting-spinner');
+        assertTrue(spinner.active);
+      });
+}
+
+function rebootFromRebootRequired() {
+  cr.webUIListenerCallback('chrome-cleanup-on-reboot-required');
+  Polymer.dom.flush();
+
+  var actionButton = chromeCleanupPage.$$('#action-button');
+  assertTrue(!!actionButton);
+  MockInteractions.tap(actionButton);
+  return ChromeCleanupProxy.whenCalled('restartComputer');
+}
+
+function cleanupFailure(userInitiatedCleanupsEnabled) {
+  cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false);
+  cr.webUIListenerCallback('chrome-cleanup-on-cleaning', false);
+  cr.webUIListenerCallback(
+      'chrome-cleanup-on-idle',
+      settings.ChromeCleanupIdleReason.CLEANING_FAILED);
+  Polymer.dom.flush();
+
+  var actionButton = chromeCleanupPage.$$('#action-button');
+  if (userInitiatedCleanupsEnabled) {
+    assertFalse(!!actionButton);
+  } else {
+    assertTrue(!!actionButton);
+    MockInteractions.tap(actionButton);
+    return ChromeCleanupProxy.whenCalled('dismissCleanupPage');
+  }
+}
+
+function cleanupSuccess(userInitiatedCleanupsEnabled) {
+  cr.webUIListenerCallback('chrome-cleanup-on-cleaning', false);
+  cr.webUIListenerCallback(
+      'chrome-cleanup-on-idle',
+      settings.ChromeCleanupIdleReason.CLEANING_SUCCEEDED);
+  Polymer.dom.flush();
+
+  var actionButton = chromeCleanupPage.$$('#action-button');
+  if (userInitiatedCleanupsEnabled) {
+    assertFalse(!!actionButton);
+  } else {
+    assertTrue(!!actionButton);
+    MockInteractions.tap(actionButton);
+    return ChromeCleanupProxy.whenCalled('dismissCleanupPage');
+  }
+}
+
+function testLogsUploading(testingScanOffered) {
+  if (testingScanOffered) {
+    cr.webUIListenerCallback(
+        'chrome-cleanup-on-infected', ['file 1', 'file 2', 'file 3']);
+  } else {
+    cr.webUIListenerCallback(
+        'chrome-cleanup-on-idle', settings.ChromeCleanupIdleReason.INITIAL);
+  }
+  Polymer.dom.flush();
+
+  var logsControl = chromeCleanupPage.$$('#chromeCleanupLogsUploadControl');
+  assertTrue(!!logsControl);
+
+  cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', true);
+  Polymer.dom.flush();
+  assertTrue(logsControl.checked);
+
+  cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false);
+  Polymer.dom.flush();
+  assertFalse(logsControl.checked);
+
+  MockInteractions.tap(logsControl.$.control);
+  return ChromeCleanupProxy.whenCalled('setLogsUploadPermission')
+      .then(function(logsUploadEnabled) {
+        assertTrue(logsUploadEnabled);
+      });
+}
+
+suite('ChromeCleanupHandler_UserInitiatedCleanupsDisabled', function() {
+  setup(function() {
+    initParametrizedTest(false);
   });
 
   test('startCleanupFromInfected', function() {
-    cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false);
-    cr.webUIListenerCallback(
-        'chrome-cleanup-on-infected', ['file 1', 'file 2', 'file 3']);
+    return startCleanupFromInfected();
+  });
+
+  test('rebootFromRebootRequired', function() {
+    return rebootFromRebootRequired();
+  });
+
+  test('cleanupFailure', function() {
+    return cleanupFailure(false);
+  });
+
+  test('cleanupSuccess', function() {
+    return cleanupSuccess(false);
+  });
+
+  test('logsUploadingOnInfected', function() {
+    return testLogsUploading(false);
+  });
+});
+
+suite('ChromeCleanupHandler_UserInitiatedCleanupsEnabled', function() {
+  setup(function() {
+    initParametrizedTest(true);
+  });
+
+  function scanOfferedOnInitiallyIdle(idleReason) {
+    cr.webUIListenerCallback('chrome-cleanup-on-idle', idleReason);
     Polymer.dom.flush();
 
-    var showFilesButton = chromeCleanupPage.$$('#show-files-button');
-    assertTrue(!!showFilesButton);
-    MockInteractions.tap(showFilesButton);
-    filesToRemove = chromeCleanupPage.$$('#files-to-remove-list');
-    assertTrue(!!filesToRemove);
-    assertEquals(filesToRemove.getElementsByTagName('li').length, 3);
+    var actionButton = chromeCleanupPage.$$('#action-button');
+    assertTrue(!!actionButton);
+  }
+
+  test('scanOfferedOnInitiallyIdle_ReporterFoundNothing', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.REPORTER_FOUND_NOTHING);
+  });
+
+  test('scanOfferedOnInitiallyIdle_ReporterFailed', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.REPORTER_FAILED);
+  });
+
+  test('scanOfferedOnInitiallyIdle_ScanningFoundNothing', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.SCANNING_FOUND_NOTHING);
+  });
+
+  test('scanOfferedOnInitiallyIdle_ScanningFailed', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.SCANNING_FAILED);
+  });
+
+  test('scanOfferedOnInitiallyIdle_ConnectionLost', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.CONNECTION_LOST);
+  });
+
+  test('scanOfferedOnInitiallyIdle_UserDeclinedCleanup', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.USER_DECLINED_CLEANUP);
+  });
+
+  test('scanOfferedOnInitiallyIdle_CleaningFailed', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.CLEANING_FAILED);
+  });
+
+  test('scanOfferedOnInitiallyIdle_CleaningSucceeded', function() {
+    scanOfferedOnInitiallyIdle(
+        settings.ChromeCleanupIdleReason.CLEANING_SUCCEEDED);
+  });
+
+  test('reporterFoundNothing', function() {
+    cr.webUIListenerCallback('chrome-cleanup-on-reporter-running');
+    cr.webUIListenerCallback(
+        'chrome-cleanup-on-idle',
+        settings.ChromeCleanupIdleReason.REPORTER_FOUND_NOTHING);
+    Polymer.dom.flush();
+
+    var actionButton = chromeCleanupPage.$$('#action-button');
+    assertFalse(!!actionButton);
+  });
+
+  test('reporterFoundNothing', function() {
+    cr.webUIListenerCallback('chrome-cleanup-on-reporter-running');
+    cr.webUIListenerCallback(
+        'chrome-cleanup-on-idle',
+        settings.ChromeCleanupIdleReason.REPORTER_FOUND_NOTHING);
+    Polymer.dom.flush();
+
+    var actionButton = chromeCleanupPage.$$('#action-button');
+    assertFalse(!!actionButton);
+  });
+
+  test('startScanFromIdle', function() {
+    cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false);
+    cr.webUIListenerCallback(
+        'chrome-cleanup-on-idle', settings.ChromeCleanupIdleReason.INITIAL);
+    Polymer.dom.flush();
 
     var actionButton = chromeCleanupPage.$$('#action-button');
     assertTrue(!!actionButton);
     MockInteractions.tap(actionButton);
-    ChromeCleanupProxy.whenCalled('startCleanup').then(
-        function(logsUploadEnabled) {
+    return ChromeCleanupProxy.whenCalled('startScanning')
+        .then(function(logsUploadEnabled) {
           assertFalse(logsUploadEnabled);
-          cr.webUIListenerCallback('chrome-cleanup-on-cleaning', false);
+          cr.webUIListenerCallback('chrome-cleanup-on-scanning', false);
           Polymer.dom.flush();
 
-          var spinner = chromeCleanupPage.$$('#cleaning-spinner');
+          var spinner = chromeCleanupPage.$$('#waiting-spinner');
           assertTrue(spinner.active);
         });
   });
 
+  test('scanFoundNothing', function() {
+    cr.webUIListenerCallback('chrome-cleanup-on-scanning', false);
+    cr.webUIListenerCallback(
+        'chrome-cleanup-on-idle',
+        settings.ChromeCleanupIdleReason.SCANNING_FOUND_NOTHING);
+    Polymer.dom.flush();
+
+    var actionButton = chromeCleanupPage.$$('#action-button');
+    assertFalse(!!actionButton);
+  });
+
+  test('scanFailure', function() {
+    cr.webUIListenerCallback('chrome-cleanup-on-scanning', false);
+    cr.webUIListenerCallback(
+        'chrome-cleanup-on-idle',
+        settings.ChromeCleanupIdleReason.SCANNING_FAILED);
+    Polymer.dom.flush();
+
+    var actionButton = chromeCleanupPage.$$('#action-button');
+    assertFalse(!!actionButton);
+  });
+
+  test('startCleanupFromInfected', function() {
+    return startCleanupFromInfected();
+  });
+
   test('rebootFromRebootRequired', function() {
-    cr.webUIListenerCallback('chrome-cleanup-on-reboot-required');
-    Polymer.dom.flush();
-
-    var actionButton = chromeCleanupPage.$$('#action-button');
-    assertTrue(!!actionButton);
-    MockInteractions.tap(actionButton);
-    return ChromeCleanupProxy.whenCalled('restartComputer');
+    return rebootFromRebootRequired();
   });
 
-  test('dismissFromIdleCleaningFailure', function() {
-    cr.webUIListenerCallback('chrome-cleanup-on-cleaning', false);
-    cr.webUIListenerCallback(
-        'chrome-cleanup-on-idle',
-        settings.ChromeCleanupIdleReason.CLEANING_FAILED);
-    Polymer.dom.flush();
-
-    var actionButton = chromeCleanupPage.$$('#action-button');
-    assertTrue(!!actionButton);
-    MockInteractions.tap(actionButton);
-    return ChromeCleanupProxy.whenCalled('dismissCleanupPage');
+  test('cleanupFailure', function() {
+    return cleanupFailure(true);
   });
 
-  test('dismissFromIdleCleaningSuccess', function() {
-    cr.webUIListenerCallback('chrome-cleanup-on-cleaning', false);
-    cr.webUIListenerCallback(
-        'chrome-cleanup-on-idle',
-        settings.ChromeCleanupIdleReason.CLEANING_SUCCEEDED);
-    Polymer.dom.flush();
-
-    var actionButton = chromeCleanupPage.$$('#action-button');
-    assertTrue(!!actionButton);
-    MockInteractions.tap(actionButton);
-    return ChromeCleanupProxy.whenCalled('dismissCleanupPage');
+  test('cleanupSuccess', function() {
+    return cleanupSuccess(true);
   });
 
-  test('setLogsUploadPermission', function() {
-    cr.webUIListenerCallback(
-        'chrome-cleanup-on-infected', ['file 1', 'file 2', 'file 3']);
-    Polymer.dom.flush();
+  test('logsUploadingOnScanOffered', function() {
+    return testLogsUploading(true);
+  });
 
-    var logsControl = chromeCleanupPage.$$('#chromeCleanupLogsUploadControl');
-    assertTrue(!!logsControl);
-
-    cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', true);
-    Polymer.dom.flush();
-    assertTrue(logsControl.checked);
-
-    cr.webUIListenerCallback('chrome-cleanup-upload-permission-change', false);
-    Polymer.dom.flush();
-    assertFalse(logsControl.checked);
-
-    MockInteractions.tap(logsControl.$.control);
-    return ChromeCleanupProxy.whenCalled('setLogsUploadPermission').then(
-        function(logsUploadEnabled) {
-          assertTrue(logsUploadEnabled);
-        });
+  test('logsUploadingOnInfected', function() {
+    return testLogsUploading(false);
   });
 });
diff --git a/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
index d8d464a..b628d051 100644
--- a/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
+++ b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
@@ -90,6 +90,19 @@
         assertDeepEquals([''], quickUnlockPrivateApi.credentials);
       });
 
+      test('EnterInvalidPasswordSelectsAllText', function() {
+        var confirmButton = getFromElement('#passwordInput');
+        quickUnlockPrivateApi.accountPassword = 'bar';
+        passwordElement.value = 'foo';
+        MockInteractions.tap(
+            getFromElement('paper-button[class="action-button"]'));
+
+        assertEquals(0, passwordElement.inputElement.selectionStart);
+        assertEquals(
+            passwordElement.value.length,
+            passwordElement.inputElement.selectionEnd);
+      });
+
       test('TapConfirmButtonWithWrongPasswordRestoresFocus', function() {
         var confirmButton = getFromElement('#passwordInput');
         quickUnlockPrivateApi.accountPassword = 'bar';
@@ -97,7 +110,7 @@
         MockInteractions.tap(
             getFromElement('paper-button[class="action-button"]'));
 
-        assertEquals(element.shadowRoot.activeElement, passwordElement);
+        assertTrue(passwordElement.focused);
       });
 
       // A bad password does not provide an authenticated setModes object, and a
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
index e199c38..bc53a719 100644
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -201,6 +201,14 @@
       "printing_handler.h",
     ]
     deps += [ "//pdf" ]
+    if (is_win) {
+      sources += [
+        "printing/pdf_to_emf_converter_factory_impl.cc",
+        "printing/pdf_to_emf_converter_factory_impl.h",
+        "printing/pdf_to_emf_converter_impl.cc",
+        "printing/pdf_to_emf_converter_impl.h",
+      ]
+    }
   }
 
   if (enable_basic_printing || enable_print_preview) {
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc
index 3b3e0ba3..aacb9c0 100644
--- a/chrome/utility/chrome_content_utility_client.cc
+++ b/chrome/utility/chrome_content_utility_client.cc
@@ -47,6 +47,7 @@
 #if defined(OS_WIN)
 #include "chrome/services/util_win/public/interfaces/constants.mojom.h"
 #include "chrome/services/util_win/util_win_service.h"
+#include "chrome/utility/printing/pdf_to_emf_converter_factory_impl.h"
 #endif
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -179,6 +180,11 @@
     registry->AddInterface(base::Bind(CreateResourceUsageReporter),
                            base::ThreadTaskRunnerHandle::Get());
 #endif  // !defined(OS_ANDROID)
+#if defined(OS_WIN)
+    registry->AddInterface(
+        base::Bind(printing::PdfToEmfConverterFactoryImpl::Create),
+        base::ThreadTaskRunnerHandle::Get());
+#endif
   }
 
   connection->AddConnectionFilter(
diff --git a/chrome/utility/printing/pdf_to_emf_converter_factory_impl.cc b/chrome/utility/printing/pdf_to_emf_converter_factory_impl.cc
new file mode 100644
index 0000000..6dff90e
--- /dev/null
+++ b/chrome/utility/printing/pdf_to_emf_converter_factory_impl.cc
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/utility/printing/pdf_to_emf_converter_factory_impl.h"
+
+#include "chrome/utility/printing/pdf_to_emf_converter_impl.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+
+namespace printing {
+
+PdfToEmfConverterFactoryImpl::PdfToEmfConverterFactoryImpl() = default;
+
+PdfToEmfConverterFactoryImpl::~PdfToEmfConverterFactoryImpl() = default;
+
+void PdfToEmfConverterFactoryImpl::CreateConverter(
+    mojo::ScopedHandle pdf_file_in,
+    const printing::PdfRenderSettings& render_settings,
+    mojom::PdfToEmfConverterClientPtr client,
+    CreateConverterCallback callback) {
+  auto converter = std::make_unique<PdfToEmfConverterImpl>(
+      std::move(pdf_file_in), render_settings, std::move(client));
+  uint32_t page_count = converter->total_page_count();
+  mojom::PdfToEmfConverterPtr converter_ptr;
+  mojo::MakeStrongBinding(std::move(converter),
+                          mojo::MakeRequest(&converter_ptr));
+
+  std::move(callback).Run(std::move(converter_ptr), page_count);
+}
+
+// static
+void PdfToEmfConverterFactoryImpl::Create(
+    mojom::PdfToEmfConverterFactoryRequest request) {
+  mojo::MakeStrongBinding(base::MakeUnique<PdfToEmfConverterFactoryImpl>(),
+                          std::move(request));
+}
+
+}  // namespace printing
diff --git a/chrome/utility/printing/pdf_to_emf_converter_factory_impl.h b/chrome/utility/printing/pdf_to_emf_converter_factory_impl.h
new file mode 100644
index 0000000..791addc
--- /dev/null
+++ b/chrome/utility/printing/pdf_to_emf_converter_factory_impl.h
@@ -0,0 +1,32 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_UTILITY_PRINTING_PDF_TO_EMF_CONVERTER_FACTORY_IMPL_H_
+#define CHROME_UTILITY_PRINTING_PDF_TO_EMF_CONVERTER_FACTORY_IMPL_H_
+
+#include "base/macros.h"
+#include "chrome/common/printing/pdf_to_emf_converter.mojom.h"
+
+namespace printing {
+
+class PdfToEmfConverterFactoryImpl : public mojom::PdfToEmfConverterFactory {
+ public:
+  PdfToEmfConverterFactoryImpl();
+  ~PdfToEmfConverterFactoryImpl() override;
+
+  static void Create(mojom::PdfToEmfConverterFactoryRequest request);
+
+ private:
+  // mojom::PdfToEmfConverterFactory implementation.
+  void CreateConverter(mojo::ScopedHandle pdf_file_in,
+                       const printing::PdfRenderSettings& render_settings,
+                       mojom::PdfToEmfConverterClientPtr client,
+                       CreateConverterCallback callback) override;
+
+  DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterFactoryImpl);
+};
+
+}  // namespace printing
+
+#endif  // CHROME_UTILITY_PRINTING_PDF_TO_EMF_CONVERTER_FACTORY_IMPL_H_
diff --git a/chrome/utility/printing/pdf_to_emf_converter_impl.cc b/chrome/utility/printing/pdf_to_emf_converter_impl.cc
new file mode 100644
index 0000000..359c33d
--- /dev/null
+++ b/chrome/utility/printing/pdf_to_emf_converter_impl.cc
@@ -0,0 +1,187 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/utility/printing/pdf_to_emf_converter_impl.h"
+
+#include <algorithm>
+
+#include "base/lazy_instance.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+#include "pdf/pdf.h"
+#include "printing/emf_win.h"
+#include "ui/gfx/gdi_util.h"
+
+namespace printing {
+
+namespace {
+
+base::LazyInstance<std::vector<mojom::PdfToEmfConverterClientPtr>>::Leaky
+    g_converter_clients = LAZY_INSTANCE_INITIALIZER;
+
+void PreCacheFontCharacters(const LOGFONT* logfont,
+                            const wchar_t* text,
+                            size_t text_length) {
+  if (g_converter_clients.Get().empty()) {
+    NOTREACHED()
+        << "PreCacheFontCharacters when no converter client is registered.";
+    return;
+  }
+
+  // We pass the LOGFONT as an array of bytes for simplicity (no typemaps
+  // required).
+  std::vector<uint8_t> logfont_mojo(sizeof(LOGFONT));
+  memcpy(logfont_mojo.data(), logfont, sizeof(LOGFONT));
+
+  g_converter_clients.Get().front()->PreCacheFontCharacters(
+      logfont_mojo, base::string16(text, text_length));
+}
+
+void OnConvertedClientDisconnected() {
+  // We have no direct way of tracking which PdfToEmfConverterClientPtr got
+  // disconnected as it is a movable type, short of using a wrapper.
+  // Just traverse the list of clients and remove the ones that are not bound.
+  std::remove_if(g_converter_clients.Get().begin(),
+                 g_converter_clients.Get().end(),
+                 [](const mojom::PdfToEmfConverterClientPtr& client) {
+                   return !client.is_bound();
+                 });
+}
+
+void RegisterConverterClient(mojom::PdfToEmfConverterClientPtr client) {
+  if (!g_converter_clients.IsCreated()) {
+    // First time this method is called.
+    chrome_pdf::SetPDFEnsureTypefaceCharactersAccessible(
+        PreCacheFontCharacters);
+  }
+  client.set_connection_error_handler(
+      base::BindOnce(&OnConvertedClientDisconnected));
+  g_converter_clients.Get().push_back(std::move(client));
+}
+
+}  // namespace
+
+PdfToEmfConverterImpl::PdfToEmfConverterImpl(
+    mojo::ScopedHandle pdf_file_in,
+    const printing::PdfRenderSettings& pdf_render_settings,
+    mojom::PdfToEmfConverterClientPtr client)
+    : pdf_render_settings_(pdf_render_settings) {
+  RegisterConverterClient(std::move(client));
+
+  chrome_pdf::SetPDFUseGDIPrinting(pdf_render_settings_.mode ==
+                                   PdfRenderSettings::Mode::GDI_TEXT);
+  int printing_mode;
+  switch (pdf_render_settings_.mode) {
+    case PdfRenderSettings::Mode::TEXTONLY:
+      printing_mode = chrome_pdf::PrintingMode::kTextOnly;
+      break;
+    case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2:
+      printing_mode = chrome_pdf::PrintingMode::kPostScript2;
+      break;
+    case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
+      printing_mode = chrome_pdf::PrintingMode::kPostScript3;
+      break;
+    default:
+      // Not using postscript or text only.
+      printing_mode = chrome_pdf::PrintingMode::kEmf;
+  }
+  chrome_pdf::SetPDFUsePrintMode(printing_mode);
+
+  base::PlatformFile pdf_file;
+  if (mojo::UnwrapPlatformFile(std::move(pdf_file_in), &pdf_file) !=
+      MOJO_RESULT_OK) {
+    LOG(ERROR) << "Invalid PDF file passed to PdfToEmfConverterImpl";
+    return;
+  }
+  LoadPdf(base::File(pdf_file));
+}
+
+PdfToEmfConverterImpl::~PdfToEmfConverterImpl() = default;
+
+void PdfToEmfConverterImpl::LoadPdf(base::File pdf_file) {
+  int64_t length64 = pdf_file.GetLength();
+  if (length64 <= 0 || length64 > std::numeric_limits<int>::max())
+    return;
+
+  int length = static_cast<int>(length64);
+  pdf_data_.resize(length);
+  if (length != pdf_file.Read(0, pdf_data_.data(), pdf_data_.size()))
+    return;
+
+  int page_count = 0;
+  chrome_pdf::GetPDFDocInfo(&pdf_data_.front(), pdf_data_.size(), &page_count,
+                            nullptr);
+  total_page_count_ = page_count;
+}
+
+bool PdfToEmfConverterImpl::RenderPdfPageToMetafile(int page_number,
+                                                    base::File output_file,
+                                                    float* scale_factor,
+                                                    bool postscript) {
+  Emf metafile;
+  metafile.Init();
+
+  // We need to scale down DC to fit an entire page into DC available area.
+  // Current metafile is based on screen DC and have current screen size.
+  // Writing outside of those boundaries will result in the cut-off output.
+  // On metafiles (this is the case here), scaling down will still record
+  // original coordinates and we'll be able to print in full resolution.
+  // Before playback we'll need to counter the scaling up that will happen
+  // in the service (print_system_win.cc).
+  //
+  // The postscript driver does not use the metafile size since it outputs
+  // postscript rather than a metafile. Instead it uses the printable area
+  // sent to RenderPDFPageToDC to determine the area to render. Therefore,
+  // don't scale the DC to match the metafile, and send the printer physical
+  // offsets to the driver.
+  if (!postscript) {
+    *scale_factor = gfx::CalculatePageScale(metafile.context(),
+                                            pdf_render_settings_.area.right(),
+                                            pdf_render_settings_.area.bottom());
+    gfx::ScaleDC(metafile.context(), *scale_factor);
+  }
+
+  // The underlying metafile is of type Emf and ignores the arguments passed
+  // to StartPage.
+  metafile.StartPage(gfx::Size(), gfx::Rect(), 1);
+  int offset_x = postscript ? pdf_render_settings_.offsets.x() : 0;
+  int offset_y = postscript ? pdf_render_settings_.offsets.y() : 0;
+
+  if (!chrome_pdf::RenderPDFPageToDC(
+          &pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(),
+          pdf_render_settings_.dpi, pdf_render_settings_.area.x() - offset_x,
+          pdf_render_settings_.area.y() - offset_y,
+          pdf_render_settings_.area.width(), pdf_render_settings_.area.height(),
+          true, false, true, true, pdf_render_settings_.autorotate)) {
+    return false;
+  }
+  metafile.FinishPage();
+  metafile.FinishDocument();
+  return metafile.SaveTo(&output_file);
+}
+
+void PdfToEmfConverterImpl::ConvertPage(uint32_t page_number,
+                                        mojo::ScopedHandle emf_file_out,
+                                        ConvertPageCallback callback) {
+  if (page_number >= total_page_count_) {
+    std::move(callback).Run(/*success=*/false, /*scale_factor=*/0.0);
+    return;
+  }
+
+  base::PlatformFile emf_file;
+  if (mojo::UnwrapPlatformFile(std::move(emf_file_out), &emf_file) !=
+      MOJO_RESULT_OK) {
+    std::move(callback).Run(/*success=*/false, /*scale_factor=*/0.0);
+    return;
+  }
+
+  float scale_factor = 1.0f;
+  bool postscript =
+      pdf_render_settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
+      pdf_render_settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
+  bool success = RenderPdfPageToMetafile(page_number, base::File(emf_file),
+                                         &scale_factor, postscript);
+  std::move(callback).Run(success, scale_factor);
+}
+
+}  // namespace printing
diff --git a/chrome/utility/printing/pdf_to_emf_converter_impl.h b/chrome/utility/printing/pdf_to_emf_converter_impl.h
new file mode 100644
index 0000000..56644fa
--- /dev/null
+++ b/chrome/utility/printing/pdf_to_emf_converter_impl.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 CHROME_UTILITY_PRINTING_PDF_TO_EMF_CONVERTER_IMPL_H_
+#define CHROME_UTILITY_PRINTING_PDF_TO_EMF_CONVERTER_IMPL_H_
+
+#include <vector>
+
+#include "base/files/file.h"
+#include "base/macros.h"
+#include "chrome/common/printing/pdf_to_emf_converter.mojom.h"
+#include "printing/pdf_render_settings.h"
+
+namespace printing {
+
+class PdfToEmfConverterImpl : public mojom::PdfToEmfConverter {
+ public:
+  PdfToEmfConverterImpl(mojo::ScopedHandle pdf_file_in,
+                        const PdfRenderSettings& render_settings,
+                        mojom::PdfToEmfConverterClientPtr client);
+  ~PdfToEmfConverterImpl() override;
+
+  int total_page_count() const { return total_page_count_; }
+
+ private:
+  // mojom::PdfToEmfConverter implementation.
+  void ConvertPage(uint32_t page_number,
+                   mojo::ScopedHandle emf_file_out,
+                   ConvertPageCallback callback) override;
+
+  void LoadPdf(base::File pdf_file);
+  bool RenderPdfPageToMetafile(int page_number,
+                               base::File output_file,
+                               float* scale_factor,
+                               bool postscript);
+
+  uint32_t total_page_count_ = 0;
+  PdfRenderSettings pdf_render_settings_;
+  std::vector<char> pdf_data_;
+
+  DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl);
+};
+
+}  // namespace printing
+
+#endif  // CHROME_UTILITY_PRINTING_PDF_TO_EMF_CONVERTER_IMPL_H_
diff --git a/chrome/utility/printing_handler.cc b/chrome/utility/printing_handler.cc
index 1b5b6395..1eb8186 100644
--- a/chrome/utility/printing_handler.cc
+++ b/chrome/utility/printing_handler.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/utility/printing_handler.h"
 
-#include <stdint.h>
 #include <utility>
 
 #include "base/files/file_util.h"
@@ -12,15 +11,8 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_utility_printing_messages.h"
 #include "content/public/utility/utility_thread.h"
-#include "pdf/pdf.h"
 #include "printing/features/features.h"
 #include "printing/page_range.h"
-#include "printing/pdf_render_settings.h"
-
-#if defined(OS_WIN)
-#include "printing/emf_win.h"
-#include "ui/gfx/gdi_util.h"
-#endif
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 #include "chrome/common/crash_keys.h"
@@ -39,36 +31,15 @@
   content::UtilityThread::Get()->ReleaseProcess();
 }
 
-#if defined(OS_WIN)
-void PreCacheFontCharacters(const LOGFONT* logfont,
-                            const wchar_t* text,
-                            size_t text_length) {
-  Send(new ChromeUtilityHostMsg_PreCacheFontCharacters(
-      *logfont, base::string16(text, text_length)));
-}
-#endif
-
 }  // namespace
 
-PrintingHandler::PrintingHandler() {
-#if defined(OS_WIN)
-  chrome_pdf::SetPDFEnsureTypefaceCharactersAccessible(PreCacheFontCharacters);
-#endif
-}
+PrintingHandler::PrintingHandler() = default;
 
-PrintingHandler::~PrintingHandler() {}
+PrintingHandler::~PrintingHandler() = default;
 
 bool PrintingHandler::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message)
-#if defined(OS_WIN)
-    IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
-                        OnRenderPDFPagesToMetafile)
-    IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage,
-                        OnRenderPDFPagesToMetafileGetPage)
-    IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop,
-                        OnRenderPDFPagesToMetafileStop)
-#endif  // OS_WIN
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterCapsAndDefaults,
                         OnGetPrinterCapsAndDefaults)
@@ -80,125 +51,6 @@
   return handled;
 }
 
-#if defined(OS_WIN)
-void PrintingHandler::OnRenderPDFPagesToMetafile(
-    IPC::PlatformFileForTransit pdf_transit,
-    const PdfRenderSettings& settings) {
-  pdf_rendering_settings_ = settings;
-  chrome_pdf::SetPDFUseGDIPrinting(pdf_rendering_settings_.mode ==
-                                   PdfRenderSettings::Mode::GDI_TEXT);
-  int printing_mode;
-  switch (pdf_rendering_settings_.mode) {
-    case PdfRenderSettings::Mode::TEXTONLY:
-      printing_mode = chrome_pdf::PrintingMode::kTextOnly;
-      break;
-    case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2:
-      printing_mode = chrome_pdf::PrintingMode::kPostScript2;
-      break;
-    case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
-      printing_mode = chrome_pdf::PrintingMode::kPostScript3;
-      break;
-    default:
-      // Not using postscript or text only.
-      printing_mode = chrome_pdf::PrintingMode::kEmf;
-  }
-  chrome_pdf::SetPDFUsePrintMode(printing_mode);
-
-  base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit);
-  int page_count = LoadPDF(std::move(pdf_file));
-  Send(
-      new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count));
-}
-
-void PrintingHandler::OnRenderPDFPagesToMetafileGetPage(
-    int page_number,
-    IPC::PlatformFileForTransit output_file) {
-  base::File emf_file = IPC::PlatformFileForTransitToFile(output_file);
-  float scale_factor = 1.0f;
-  bool postscript = pdf_rendering_settings_.mode ==
-                        PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
-                    pdf_rendering_settings_.mode ==
-                        PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
-  bool success = RenderPdfPageToMetafile(page_number, std::move(emf_file),
-                                         &scale_factor, postscript);
-  Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone(
-      success, scale_factor));
-}
-
-void PrintingHandler::OnRenderPDFPagesToMetafileStop() {
-  ReleaseProcess();
-}
-
-#endif  // defined(OS_WIN)
-
-#if defined(OS_WIN)
-int PrintingHandler::LoadPDF(base::File pdf_file) {
-  int64_t length64 = pdf_file.GetLength();
-  if (length64 <= 0 || length64 > std::numeric_limits<int>::max())
-    return 0;
-  int length = static_cast<int>(length64);
-
-  pdf_data_.resize(length);
-  if (length != pdf_file.Read(0, pdf_data_.data(), pdf_data_.size()))
-    return 0;
-
-  int total_page_count = 0;
-  if (!chrome_pdf::GetPDFDocInfo(&pdf_data_.front(), pdf_data_.size(),
-                                 &total_page_count, nullptr)) {
-    return 0;
-  }
-  return total_page_count;
-}
-
-bool PrintingHandler::RenderPdfPageToMetafile(int page_number,
-                                              base::File output_file,
-                                              float* scale_factor,
-                                              bool postscript) {
-  Emf metafile;
-  metafile.Init();
-
-  // We need to scale down DC to fit an entire page into DC available area.
-  // Current metafile is based on screen DC and have current screen size.
-  // Writing outside of those boundaries will result in the cut-off output.
-  // On metafiles (this is the case here), scaling down will still record
-  // original coordinates and we'll be able to print in full resolution.
-  // Before playback we'll need to counter the scaling up that will happen
-  // in the service (print_system_win.cc).
-  //
-  // The postscript driver does not use the metafile size since it outputs
-  // postscript rather than a metafile. Instead it uses the printable area
-  // sent to RenderPDFPageToDC to determine the area to render. Therefore,
-  // don't scale the DC to match the metafile, and send the printer physical
-  // offsets to the driver.
-  if (!postscript) {
-    *scale_factor = gfx::CalculatePageScale(
-        metafile.context(), pdf_rendering_settings_.area.right(),
-        pdf_rendering_settings_.area.bottom());
-    gfx::ScaleDC(metafile.context(), *scale_factor);
-  }
-
-  // The underlying metafile is of type Emf and ignores the arguments passed
-  // to StartPage.
-  metafile.StartPage(gfx::Size(), gfx::Rect(), 1);
-  int offset_x = postscript ? pdf_rendering_settings_.offsets.x() : 0;
-  int offset_y = postscript ? pdf_rendering_settings_.offsets.y() : 0;
-
-  if (!chrome_pdf::RenderPDFPageToDC(
-          &pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(),
-          pdf_rendering_settings_.dpi,
-          pdf_rendering_settings_.area.x() - offset_x,
-          pdf_rendering_settings_.area.y() - offset_y,
-          pdf_rendering_settings_.area.width(),
-          pdf_rendering_settings_.area.height(), true, false, true, true,
-          pdf_rendering_settings_.autorotate)) {
-    return false;
-  }
-  metafile.FinishPage();
-  metafile.FinishDocument();
-  return metafile.SaveTo(&output_file);
-}
-#endif  // defined(OS_WIN)
-
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 void PrintingHandler::OnGetPrinterCapsAndDefaults(
     const std::string& printer_name) {
diff --git a/chrome/utility/printing_handler.h b/chrome/utility/printing_handler.h
index de01251..14a00ff 100644
--- a/chrome/utility/printing_handler.h
+++ b/chrome/utility/printing_handler.h
@@ -5,13 +5,13 @@
 #ifndef CHROME_UTILITY_PRINTING_HANDLER_H_
 #define CHROME_UTILITY_PRINTING_HANDLER_H_
 
+#include <string>
+
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "chrome/utility/utility_message_handler.h"
-#include "ipc/ipc_platform_file.h"
 #include "printing/features/features.h"
-#include "printing/pdf_render_settings.h"
 
 #if !BUILDFLAG(ENABLE_PRINT_PREVIEW) && \
     !(BUILDFLAG(ENABLE_BASIC_PRINTING) && defined(OS_WIN))
@@ -31,32 +31,11 @@
 
  private:
   // IPC message handlers.
-#if defined(OS_WIN)
-  void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit,
-                                  const PdfRenderSettings& settings);
-  void OnRenderPDFPagesToMetafileGetPage(
-      int page_number,
-      IPC::PlatformFileForTransit output_file);
-  void OnRenderPDFPagesToMetafileStop();
-#endif  // OS_WIN
-
-#if defined(OS_WIN)
-  int LoadPDF(base::File pdf_file);
-  bool RenderPdfPageToMetafile(int page_number,
-                               base::File output_file,
-                               float* scale_factor,
-                               bool postscript);
-#endif  // OS_WIN
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   void OnGetPrinterCapsAndDefaults(const std::string& printer_name);
   void OnGetPrinterSemanticCapsAndDefaults(const std::string& printer_name);
 #endif  // ENABLE_PRINT_PREVIEW
 
-#if defined(OS_WIN)
-  std::vector<char> pdf_data_;
-  PdfRenderSettings pdf_rendering_settings_;
-#endif
-
   DISALLOW_COPY_AND_ASSIGN(PrintingHandler);
 };
 
diff --git a/chrome_elf/blacklist/test/blacklist_test.cc b/chrome_elf/blacklist/test/blacklist_test.cc
index 9fdb4ae4..4a61f0c 100644
--- a/chrome_elf/blacklist/test/blacklist_test.cc
+++ b/chrome_elf/blacklist/test/blacklist_test.cc
@@ -361,7 +361,8 @@
   result = blacklist_registry_key_->ReadValueDW(blacklist::kBeaconState,
                                                 &blacklist_state);
   EXPECT_EQ(ERROR_SUCCESS, result);
-  EXPECT_EQ(blacklist_state, blacklist::BLACKLIST_SETUP_FAILED);
+  EXPECT_EQ(blacklist_state,
+            static_cast<DWORD>(blacklist::BLACKLIST_SETUP_FAILED));
 }
 
 TEST_F(BlacklistTest, SetupSucceeded) {
@@ -379,7 +380,8 @@
   DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX;
   blacklist_registry_key_->ReadValueDW(blacklist::kBeaconState,
                                        &blacklist_state);
-  EXPECT_EQ(blacklist_state, blacklist::BLACKLIST_SETUP_RUNNING);
+  EXPECT_EQ(blacklist_state,
+            static_cast<DWORD>(blacklist::BLACKLIST_SETUP_RUNNING));
 
   DWORD attempt_count = blacklist::kBeaconMaxAttempts;
   blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount,
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
index 83963c85..da98ce91 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -123,7 +123,8 @@
     protected void handleIntent(Intent intent) {
         // Do not load the WebContents if we are simply bringing the same
         // activity to the foreground.
-        if (intent.getData() == null || mInstanceId.equals(intent.getData().getPath())) {
+        if (intent.getData() == null || intent.getData().getPath() == null
+                || (mInstanceId != null && mInstanceId.equals(intent.getData().getPath()))) {
             return;
         }
 
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java
index ec33bdf..4fe74f5 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java
@@ -52,9 +52,7 @@
             Intent intent = new Intent(Intent.ACTION_VIEW, getInstanceUri(mInstanceId), context,
                     CastWebContentsActivity.class);
             intent.putExtra(ACTION_EXTRA_WEB_CONTENTS, webContents);
-            // FLAG_ACTIVITY_SINGLE_TOP will try to reuse existing activity.
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
-                    | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
             context.startActivity(intent);
         }
 
diff --git a/chromecast/crash/cast_crash_keys.cc b/chromecast/crash/cast_crash_keys.cc
index d44aaaf..2697203 100644
--- a/chromecast/crash/cast_crash_keys.cc
+++ b/chromecast/crash/cast_crash_keys.cc
@@ -42,15 +42,10 @@
       {gpu::crash_keys::kGPUGLContextIsVirtual, ::crash_keys::kSmallSize},
 
       // content/:
-      {"bad_message_reason", ::crash_keys::kSmallSize},
       {"discardable-memory-allocated", ::crash_keys::kSmallSize},
       {"discardable-memory-free", ::crash_keys::kSmallSize},
-      {"font_key_name", ::crash_keys::kSmallSize},
-      {"mojo-message-error", ::crash_keys::kMediumSize},
-      {"ppapi_path", ::crash_keys::kMediumSize},
       {"subresource_url", ::crash_keys::kLargeSize},
       {"total-discardable-memory-allocated", ::crash_keys::kSmallSize},
-      {"input-event-filter-send-failure", ::crash_keys::kSmallSize},
       {"view-count", ::crash_keys::kSmallSize},
 
       // media/:
@@ -68,10 +63,6 @@
 
       // TODO(sunnyps): Remove after fixing crbug.com/724999.
       {"gl-context-set-current-stack-trace", ::crash_keys::kMediumSize},
-
-      // Accessibility keys. Temporary for http://crbug.com/765490.
-      {"ax_tree_error", ::crash_keys::kSmallSize},
-      {"ax_tree_update", ::crash_keys::kMediumSize},
   };
 
   return base::debug::InitCrashKeys(fixed_keys, arraysize(fixed_keys),
diff --git a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
index ed59766..d2a6d80 100644
--- a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
+++ b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
@@ -939,22 +939,6 @@
 
 // TODO(kmackay) FFmpegDemuxForTest can't handle AC3 or EAC3.
 
-TEST_F(AudioVideoPipelineDeviceTest, OpusPlayback_Optional) {
-  set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
-  ConfigureForAudioOnly("bear-opus.ogg");
-  PauseBeforeEos();
-  Start();
-  base::RunLoop().Run();
-}
-
-TEST_F(AudioVideoPipelineDeviceTest, FlacPlayback_Optional) {
-  set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
-  ConfigureForAudioOnly("bear.flac");
-  PauseBeforeEos();
-  Start();
-  base::RunLoop().Run();
-}
-
 TEST_F(AudioVideoPipelineDeviceTest, H264Playback) {
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForVideoOnly("bear.h264", true /* raw_h264 */);
@@ -1107,24 +1091,6 @@
 
 // TODO(kmackay) FFmpegDemuxForTest can't handle AC3 or EAC3.
 
-TEST_F(AudioVideoPipelineDeviceTest, OpusPlayback_WithEffectsStreams_Optional) {
-  set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
-  ConfigureForAudioOnly("bear-opus.ogg");
-  PauseBeforeEos();
-  AddEffectsStreams();
-  Start();
-  base::RunLoop().Run();
-}
-
-TEST_F(AudioVideoPipelineDeviceTest, FlacPlayback_WithEffectsStreams_Optional) {
-  set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
-  ConfigureForAudioOnly("bear.flac");
-  PauseBeforeEos();
-  AddEffectsStreams();
-  Start();
-  base::RunLoop().Run();
-}
-
 TEST_F(AudioVideoPipelineDeviceTest, H264Playback_WithEffectsStreams) {
   set_sync_type(MediaPipelineDeviceParams::kModeSyncPts);
   ConfigureForVideoOnly("bear.h264", true /* raw_h264 */);
diff --git a/chromecast/media/cma/backend/filter_group.cc b/chromecast/media/cma/backend/filter_group.cc
index b7b00b5d..e725576 100644
--- a/chromecast/media/cma/backend/filter_group.cc
+++ b/chromecast/media/cma/backend/filter_group.cc
@@ -35,7 +35,7 @@
       frames_zeroed_(0),
       last_volume_(0.0),
       delay_frames_(0),
-      loudest_content_type_(AudioContentType::kMedia),
+      content_type_(AudioContentType::kMedia),
       post_processing_pipeline_(std::move(pipeline)) {
   for (auto* const m : mixed_inputs) {
     DCHECK_EQ(m->GetOutputChannelCount(), num_channels);
@@ -51,7 +51,7 @@
 void FilterGroup::Initialize(int output_samples_per_second) {
   output_samples_per_second_ = output_samples_per_second;
   CHECK(post_processing_pipeline_->SetSampleRate(output_samples_per_second));
-  post_processing_pipeline_->SetContentType(loudest_content_type_);
+  post_processing_pipeline_->SetContentType(content_type_);
 }
 
 bool FilterGroup::CanProcessInput(StreamMixer::InputQueue* input) {
@@ -68,15 +68,12 @@
   ResizeBuffersIfNecessary(chunk_size);
 
   float volume = 0.0f;
-  AudioContentType loudest_content_type = loudest_content_type_;
+  AudioContentType content_type = static_cast<AudioContentType>(-1);
 
   // Recursively mix inputs.
   for (auto* filter_group : mixed_inputs_) {
-    float tmp = filter_group->MixAndFilter(chunk_size);
-    if (tmp > volume) {
-      volume = tmp;
-      loudest_content_type = filter_group->loudest_content_type();
-    }
+    volume = std::max(volume, filter_group->MixAndFilter(chunk_size));
+    content_type = std::max(content_type, filter_group->content_type());
   }
 
   // |volume| can only be 0 if no |mixed_inputs_| have data.
@@ -106,11 +103,8 @@
       input->VolumeScaleAccumulate(c != 0, temp_->channel(c), chunk_size,
                                    mixed_->channel(c));
     }
-    float tmp = input->InstantaneousVolume();
-    if (tmp > volume) {
-      volume = tmp;
-      loudest_content_type = input->content_type();
-    }
+    volume = std::max(volume, input->InstantaneousVolume());
+    content_type = std::max(content_type, input->content_type());
   }
 
   mixed_->ToInterleaved<::media::FloatSampleTypeTraits<float>>(chunk_size,
@@ -143,9 +137,11 @@
   bool is_silence = (volume == 0.0f);
   if (!is_silence) {
     last_volume_ = volume;
-    if (loudest_content_type != loudest_content_type_) {
-      loudest_content_type_ = loudest_content_type;
-      post_processing_pipeline_->SetContentType(loudest_content_type_);
+    DCHECK_NE(-1, static_cast<int>(content_type))
+        << "Got frames without content type.";
+    if (content_type != content_type_) {
+      content_type_ = content_type;
+      post_processing_pipeline_->SetContentType(content_type_);
     }
   }
 
diff --git a/chromecast/media/cma/backend/filter_group.h b/chromecast/media/cma/backend/filter_group.h
index 066d3cd..c6caed2cf 100644
--- a/chromecast/media/cma/backend/filter_group.h
+++ b/chromecast/media/cma/backend/filter_group.h
@@ -110,10 +110,8 @@
   // Sets the active channel.
   void UpdatePlayoutChannel(int playout_channel);
 
-  // Get loudest content type
-  AudioContentType loudest_content_type() const {
-    return loudest_content_type_;
-  }
+  // Get content type
+  AudioContentType content_type() const { return content_type_; }
 
  private:
   void ResizeBuffersIfNecessary(int chunk_size);
@@ -131,7 +129,7 @@
   int frames_zeroed_;
   float last_volume_;
   int64_t delay_frames_;
-  AudioContentType loudest_content_type_;
+  AudioContentType content_type_;
 
   // Buffers that hold audio data while it is mixed.
   // These are kept as members of this class to minimize copies and
diff --git a/chromecast/media/cma/backend/filter_group_unittest.cc b/chromecast/media/cma/backend/filter_group_unittest.cc
index 849d54695..09706c77 100644
--- a/chromecast/media/cma/backend/filter_group_unittest.cc
+++ b/chromecast/media/cma/backend/filter_group_unittest.cc
@@ -139,7 +139,8 @@
   MockInputQueue(AudioContentType content_type, float volume)
       : content_type_(content_type),
         instantaneous_volume_(volume),
-        data_(GetTestData()) {
+        data_(GetTestData()),
+        primary_(true) {
     ON_CALL(*this, TargetVolume())
         .WillByDefault(testing::Return(kTargetVolume));
     ON_CALL(*this, InstantaneousVolume())
@@ -148,15 +149,16 @@
   ~MockInputQueue() override = default;
 
   const ::media::AudioBus* data() const { return data_.get(); }
+  AudioContentType content_type() const override { return content_type_; }
+
   MOCK_METHOD0(TargetVolume, float());
   MOCK_METHOD0(InstantaneousVolume, float());
 
  private:
   // StreamMixer::InputQueue implementation.
   int input_samples_per_second() const override { return kInputSampleRate; }
-  bool primary() const override { return true; }
+  bool primary() const override { return primary_; }
   std::string device_id() const override { return "test"; }
-  AudioContentType content_type() const override { return content_type_; }
   bool IsDeleting() const override { return false; }
   void Initialize(const MediaPipelineBackend::AudioDecoder::RenderingDelay&
                       mixer_rendering_delay) override {}
@@ -191,13 +193,14 @@
   float instantaneous_volume_;
   FilterGroup* filter_group_ = nullptr;
   std::unique_ptr<::media::AudioBus> data_;
+  bool primary_;
 
   DISALLOW_COPY_AND_ASSIGN(MockInputQueue);
 };
 
 class FilterGroupTest : public testing::Test {
  protected:
-  FilterGroupTest() : input_(std::make_unique<MockInputQueue>()) {}
+  FilterGroupTest() {}
   ~FilterGroupTest() override {}
 
   void MakeFilterGroup(
@@ -213,14 +216,14 @@
         std::unordered_set<std::string>() /* device_ids */,
         std::vector<FilterGroup*>());
     filter_group_->Initialize(kInputSampleRate);
-    filter_group_->AddActiveInput(input_.get());
+    filter_group_->AddActiveInput(&input_);
     filter_group_->UpdatePlayoutChannel(kChannelAll);
   }
 
   float Input(int channel, int frame) {
-    DCHECK_LE(channel, input_->data()->channels());
-    DCHECK_LE(frame, input_->data()->frames());
-    return input_->data()->channel(channel)[frame];
+    DCHECK_LE(channel, input_.data()->channels());
+    DCHECK_LE(frame, input_.data()->frames());
+    return input_.data()->channel(channel)[frame];
   }
 
   void AssertPassthrough() {
@@ -237,7 +240,7 @@
 
   float RightInput(int frame) { return Input(1, frame); }
 
-  std::unique_ptr<MockInputQueue> input_;
+  MockInputQueue input_;
   std::unique_ptr<FilterGroup> filter_group_;
   MockPostProcessingPipeline* post_processor_ = nullptr;
 
@@ -248,7 +251,7 @@
 TEST_F(FilterGroupTest, Passthrough) {
   MakeFilterGroup(FilterGroup::GroupType::kFinalMix, false /* mix to mono */,
                   std::make_unique<MockPostProcessingPipeline>());
-  EXPECT_CALL(*input_.get(), TargetVolume()).Times(0);
+  EXPECT_CALL(input_, TargetVolume()).Times(0);
   EXPECT_CALL(*post_processor_,
               ProcessFrames(_, kInputFrames, kInstantaneousVolume, false));
 
@@ -259,7 +262,7 @@
 TEST_F(FilterGroupTest, StreamGroupsDoNotMonoMix) {
   MakeFilterGroup(FilterGroup::GroupType::kStream, true /* mix to mono */,
                   std::make_unique<MockPostProcessingPipeline>());
-  EXPECT_CALL(*input_.get(), TargetVolume()).Times(0);
+  EXPECT_CALL(input_, TargetVolume()).Times(0);
   EXPECT_CALL(*post_processor_,
               ProcessFrames(_, kInputFrames, kInstantaneousVolume, false));
 
@@ -270,7 +273,7 @@
 TEST_F(FilterGroupTest, LinearizeGroupsDoNotMonoMix) {
   MakeFilterGroup(FilterGroup::GroupType::kLinearize, true /* mix to mono */,
                   std::make_unique<MockPostProcessingPipeline>());
-  EXPECT_CALL(*input_.get(), TargetVolume()).Times(0);
+  EXPECT_CALL(input_, TargetVolume()).Times(0);
   EXPECT_CALL(*post_processor_,
               ProcessFrames(_, kInputFrames, kInstantaneousVolume, false));
 
@@ -395,20 +398,38 @@
   }
 }
 
-TEST_F(FilterGroupTest, ChecksLoudestContentType) {
+TEST_F(FilterGroupTest, ChecksContentType) {
   MakeFilterGroup(FilterGroup::GroupType::kStream, false,
                   std::make_unique<MockPostProcessingPipeline>());
-  AudioContentType type = AudioContentType::kCommunication;
-  MockInputQueue tts_loud_input(type, kInstantaneousVolume + .001);
-  filter_group_->AddActiveInput(&tts_loud_input);
-  EXPECT_CALL(*post_processor_, SetContentType(type));
+
+  MockInputQueue tts_input(AudioContentType::kCommunication,
+                           kInstantaneousVolume);
+  MockInputQueue alarm_input(AudioContentType::kAlarm, kInstantaneousVolume);
+
+  // Media input stream + tts input stream -> tts content type.
+  filter_group_->AddActiveInput(&tts_input);
+  EXPECT_CALL(*post_processor_,
+              SetContentType(AudioContentType::kCommunication));
   filter_group_->MixAndFilter(kInputFrames);
 
+  // Media input + tts input + alarm input -> tts content type (no update).
+  filter_group_->AddActiveInput(&alarm_input);
+  EXPECT_CALL(*post_processor_,
+              SetContentType(AudioContentType::kCommunication))
+      .Times(0);
+  filter_group_->MixAndFilter(kInputFrames);
+
+  // Media input + alarm input -> alarm content type.
   filter_group_->ClearActiveInputs();
-  MockInputQueue tts_quiet_input(type, kInstantaneousVolume - .001);
-  filter_group_->AddActiveInput(&tts_quiet_input);
-  filter_group_->AddActiveInput(input_.get());
-  EXPECT_CALL(*post_processor_, SetContentType(kDefaultContentType));
+  filter_group_->AddActiveInput(&input_);
+  filter_group_->AddActiveInput(&alarm_input);
+  EXPECT_CALL(*post_processor_, SetContentType(AudioContentType::kAlarm));
+  filter_group_->MixAndFilter(kInputFrames);
+
+  // Media input stream -> media input
+  EXPECT_CALL(*post_processor_, SetContentType(AudioContentType::kMedia));
+  filter_group_->ClearActiveInputs();
+  filter_group_->AddActiveInput(&input_);
   filter_group_->MixAndFilter(kInputFrames);
 }
 
diff --git a/chromecast/tracing/tracing_service_main.cc b/chromecast/tracing/tracing_service_main.cc
index 7a754b0..13c3e1e3 100644
--- a/chromecast/tracing/tracing_service_main.cc
+++ b/chromecast/tracing/tracing_service_main.cc
@@ -93,7 +93,7 @@
         out_fd_(std::move(out_fd)),
         out_watcher_(FROM_HERE),
         callback_(std::move(callback)) {}
-  virtual ~TraceCopyTask() {}
+  ~TraceCopyTask() override {}
 
   void Start() {
     base::MessageLoopForIO::current()->WatchFileDescriptor(
@@ -178,7 +178,7 @@
         connection_watcher_(FROM_HERE),
         callback_(std::move(callback)),
         weak_ptr_factory_(this) {}
-  virtual ~TraceConnection() {}
+  ~TraceConnection() override {}
 
   void Init() {
     base::MessageLoopForIO::current()->WatchFileDescriptor(
@@ -336,7 +336,7 @@
  public:
   TracingService()
       : server_socket_watcher_(FROM_HERE), weak_ptr_factory_(this) {}
-  virtual ~TracingService() {}
+  ~TracingService() override {}
 
   bool Init() {
     server_socket_ = CreateServerSocket();
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index d2f02e7..2fa53076 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-10190.0.0
\ No newline at end of file
+10193.0.0
\ No newline at end of file
diff --git a/chromeos/components/tether/host_connection_metrics_logger.cc b/chromeos/components/tether/host_connection_metrics_logger.cc
index 4bbc6f0c..2b4c4ebc 100644
--- a/chromeos/components/tether/host_connection_metrics_logger.cc
+++ b/chromeos/components/tether/host_connection_metrics_logger.cc
@@ -59,6 +59,15 @@
           ConnectionToHostResult_FailureTetheringTimeoutEventType::
               FIRST_TIME_SETUP_WAS_NOT_REQUIRED);
       break;
+    case ConnectionToHostResult::
+        CONNECTION_RESULT_FAILURE_TETHERING_UNSUPPORTED:
+      RecordConnectionResultFailure(
+          ConnectionToHostResult_FailureEventType::TETHERING_UNSUPPORTED);
+      break;
+    case ConnectionToHostResult::CONNECTION_RESULT_FAILURE_NO_CELL_DATA:
+      RecordConnectionResultFailure(
+          ConnectionToHostResult_FailureEventType::NO_CELL_DATA);
+      break;
     default:
       NOTREACHED();
   };
diff --git a/chromeos/components/tether/host_connection_metrics_logger.h b/chromeos/components/tether/host_connection_metrics_logger.h
index dfa0b72..06bb8e78 100644
--- a/chromeos/components/tether/host_connection_metrics_logger.h
+++ b/chromeos/components/tether/host_connection_metrics_logger.h
@@ -25,7 +25,9 @@
     CONNECTION_RESULT_FAILURE_CLIENT_CONNECTION_CANCELED_BY_USER,
     CONNECTION_RESULT_FAILURE_CLIENT_CONNECTION_INTERNAL_ERROR,
     CONNECTION_RESULT_FAILURE_TETHERING_TIMED_OUT_FIRST_TIME_SETUP_WAS_REQUIRED,
-    CONNECTION_RESULT_FAILURE_TETHERING_TIMED_OUT_FIRST_TIME_SETUP_WAS_NOT_REQUIRED
+    CONNECTION_RESULT_FAILURE_TETHERING_TIMED_OUT_FIRST_TIME_SETUP_WAS_NOT_REQUIRED,
+    CONNECTION_RESULT_FAILURE_TETHERING_UNSUPPORTED,
+    CONNECTION_RESULT_FAILURE_NO_CELL_DATA
   };
 
   // Record the result of an attempted host connection.
@@ -57,6 +59,10 @@
   FRIEND_TEST_ALL_PREFIXES(
       HostConnectionMetricsLoggerTest,
       RecordConnectionResultFailureTetheringTimeout_SetupNotRequired);
+  FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
+                           RecordConnectionResultFailureTetheringUnsupported);
+  FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
+                           RecordConnectionResultFailureNoCellData);
 
   // An Instant Tethering connection can fail for several different reasons.
   // Though traditionally success and each failure case would be logged to a
@@ -88,6 +94,8 @@
     UNKNOWN_ERROR = 0,
     TETHERING_TIMED_OUT = 1,
     CLIENT_CONNECTION_ERROR = 2,
+    TETHERING_UNSUPPORTED = 3,
+    NO_CELL_DATA = 4,
     FAILURE_MAX
   };
 
diff --git a/chromeos/components/tether/host_connection_metrics_logger_unittest.cc b/chromeos/components/tether/host_connection_metrics_logger_unittest.cc
index 8cd30397..e4b4acb 100644
--- a/chromeos/components/tether/host_connection_metrics_logger_unittest.cc
+++ b/chromeos/components/tether/host_connection_metrics_logger_unittest.cc
@@ -204,6 +204,31 @@
           ConnectionToHostResult_ProvisioningFailureEventType::OTHER);
 }
 
+TEST_F(HostConnectionMetricsLoggerTest,
+       RecordConnectionResultFailureTetheringUnsupported) {
+  metrics_logger_->RecordConnectionToHostResult(
+      HostConnectionMetricsLogger::ConnectionToHostResult::
+          CONNECTION_RESULT_FAILURE_TETHERING_UNSUPPORTED);
+
+  VerifyFailure(
+      HostConnectionMetricsLogger::ConnectionToHostResult_FailureEventType::
+          TETHERING_UNSUPPORTED);
+  VerifySuccess(HostConnectionMetricsLogger::
+                    ConnectionToHostResult_SuccessEventType::FAILURE);
+}
+
+TEST_F(HostConnectionMetricsLoggerTest,
+       RecordConnectionResultFailureNoCellData) {
+  metrics_logger_->RecordConnectionToHostResult(
+      HostConnectionMetricsLogger::ConnectionToHostResult::
+          CONNECTION_RESULT_FAILURE_NO_CELL_DATA);
+
+  VerifyFailure(HostConnectionMetricsLogger::
+                    ConnectionToHostResult_FailureEventType::NO_CELL_DATA);
+  VerifySuccess(HostConnectionMetricsLogger::
+                    ConnectionToHostResult_SuccessEventType::FAILURE);
+}
+
 }  // namespace tether
 
 }  // namespace chromeos
diff --git a/chromeos/components/tether/proto/tether.proto b/chromeos/components/tether/proto/tether.proto
index 634429c..17e1b813 100644
--- a/chromeos/components/tether/proto/tether.proto
+++ b/chromeos/components/tether/proto/tether.proto
@@ -88,6 +88,8 @@
     SUCCESS = 1;
     PROVISIONING_FAILED = 2;
     TETHERING_TIMEOUT = 3;
+    TETHERING_UNSUPPORTED = 4;
+    NO_CELL_DATA = 5;
   }
 
   optional ResponseCode response_code = 1;
diff --git a/chromeos/components/tether/tether_connector_impl.cc b/chromeos/components/tether/tether_connector_impl.cc
index 5e1d022e..9a53747 100644
--- a/chromeos/components/tether/tether_connector_impl.cc
+++ b/chromeos/components/tether/tether_connector_impl.cc
@@ -384,6 +384,19 @@
         CONNECTION_RESULT_FAILURE_TETHERING_TIMED_OUT_FIRST_TIME_SETUP_WAS_NOT_REQUIRED;
   }
 
+  if (error_code ==
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_TETHERING_UNSUPPORTED) {
+    return HostConnectionMetricsLogger::ConnectionToHostResult::
+        CONNECTION_RESULT_FAILURE_TETHERING_UNSUPPORTED;
+  }
+
+  if (error_code == ConnectTetheringResponse_ResponseCode::
+                        ConnectTetheringResponse_ResponseCode_NO_CELL_DATA) {
+    return HostConnectionMetricsLogger::ConnectionToHostResult::
+        CONNECTION_RESULT_FAILURE_NO_CELL_DATA;
+  }
+
   return HostConnectionMetricsLogger::ConnectionToHostResult::
       CONNECTION_RESULT_FAILURE_UNKNOWN_ERROR;
 }
diff --git a/chromeos/components/tether/tether_connector_impl_unittest.cc b/chromeos/components/tether/tether_connector_impl_unittest.cc
index dbf0f84..234b2f13 100644
--- a/chromeos/components/tether/tether_connector_impl_unittest.cc
+++ b/chromeos/components/tether/tether_connector_impl_unittest.cc
@@ -438,6 +438,25 @@
 }
 
 TEST_F(TetherConnectorImplTest,
+       TestConnectTetheringOperationFails_TetheringUnsupported) {
+  VerifyConnectTetheringOperationFails(
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_TETHERING_UNSUPPORTED,
+      false /* setup_required */,
+      HostConnectionMetricsLogger::ConnectionToHostResult::
+          CONNECTION_RESULT_FAILURE_TETHERING_UNSUPPORTED);
+}
+
+TEST_F(TetherConnectorImplTest, TestConnectTetheringOperationFails_NoCellData) {
+  VerifyConnectTetheringOperationFails(
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_NO_CELL_DATA,
+      false /* setup_required */,
+      HostConnectionMetricsLogger::ConnectionToHostResult::
+          CONNECTION_RESULT_FAILURE_NO_CELL_DATA);
+}
+
+TEST_F(TetherConnectorImplTest,
        ConnectionToHostFailedNotificationRemovedWhenConnectionStarts) {
   // Start with the "connection to host failed" notification showing.
   fake_notification_presenter_->NotifyConnectionToHostFailed();
diff --git a/components/arc/arc_bridge_host_impl.cc b/components/arc/arc_bridge_host_impl.cc
index a0f3b962..17a6f0e 100644
--- a/components/arc/arc_bridge_host_impl.cc
+++ b/components/arc/arc_bridge_host_impl.cc
@@ -38,7 +38,7 @@
     // Delay registration to the ConnectionHolder until the version is ready.
   }
 
-  ~MojoChannelImpl() override { holder_->SetInstance(nullptr, 0); }
+  ~MojoChannelImpl() override { holder_->CloseInstance(ptr_.get()); }
 
   void set_connection_error_handler(base::OnceClosure error_handler) {
     ptr_.set_connection_error_handler(std::move(error_handler));
diff --git a/components/arc/connection_holder.h b/components/arc/connection_holder.h
index 4c6fb0d..5a7daf7 100644
--- a/components/arc/connection_holder.h
+++ b/components/arc/connection_holder.h
@@ -129,19 +129,31 @@
     OnChanged();
   }
 
-  // Sets (or resets if |instance| is nullptr) the instance.
+  // Sets the instance.
   void SetInstance(InstanceType* instance,
                    uint32_t version = InstanceType::version_) {
-    // Note: This can be called with nullptr even if |instance_| is still
-    // nullptr for just in case clean up purpose. No-op in such a case.
-    if (instance == instance_)
-      return;
+    DCHECK(instance);
+    DCHECK(instance_ != instance);
 
     instance_ = instance;
     instance_version_ = version;
     OnChanged();
   }
 
+  // Resets the instance if it matches |instance|.
+  void CloseInstance(InstanceType* instance) {
+    DCHECK(instance);
+
+    if (instance != instance_) {
+      DVLOG(1) << "Dropping request to close a stale instance";
+      return;
+    }
+
+    instance_ = nullptr;
+    instance_version_ = 0;
+    OnChanged();
+  }
+
  private:
   // Called when |instance_| or |host_| are updated.
   void OnChanged() {
@@ -298,24 +310,31 @@
     NOTREACHED();
   }
 
-  // Sets (or resets if |instance| is nullptr) the instance.
+  // Sets the instance.
   void SetInstance(InstanceType* instance,
                    uint32_t version = InstanceType::version_) {
-    DCHECK(instance == nullptr || instance_ == nullptr);
-
-    // Note: This can be called with nullptr even if |instance_| is still
-    // nullptr for just in case clean up purpose. No-op in such a case.
-    if (instance == instance_)
-      return;
+    DCHECK(instance);
+    DCHECK(instance_ != instance);
 
     instance_ = instance;
     instance_version_ = version;
 
     // There is nothing more than setting in this case. Notify observers.
-    if (instance_)
-      connection_notifier_->NotifyConnectionReady();
-    else
-      connection_notifier_->NotifyConnectionClosed();
+    connection_notifier_->NotifyConnectionReady();
+  }
+
+  // Resets the instance if it matches |instance|.
+  void CloseInstance(InstanceType* instance) {
+    DCHECK(instance);
+
+    if (instance != instance_) {
+      DVLOG(1) << "Dropping request to close a stale instance";
+      return;
+    }
+
+    instance_ = nullptr;
+    instance_version_ = 0;
+    connection_notifier_->NotifyConnectionClosed();
   }
 
  private:
@@ -398,14 +417,21 @@
   }
 
   // Sets |instance| with |version|.
-  // This can be called in both case; on ready, and on closed.
-  // Passing nullptr to |instance| means closing.
   void SetInstance(InstanceType* instance,
                    uint32_t version = InstanceType::Version_) {
+    DCHECK(instance);
     DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
     impl_.SetInstance(instance, version);
   }
 
+  // Closes |instance|, if it matches against the current instance. Otherwise,
+  // it is a no-op.
+  void CloseInstance(InstanceType* instance) {
+    DCHECK(instance);
+    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+    impl_.CloseInstance(instance);
+  }
+
  private:
   THREAD_CHECKER(thread_checker_);
   internal::ConnectionNotifier connection_notifier_;
diff --git a/components/arc/metrics/arc_metrics_service.cc b/components/arc/metrics/arc_metrics_service.cc
index a36e4ab..f11ea8f 100644
--- a/components/arc/metrics/arc_metrics_service.cc
+++ b/components/arc/metrics/arc_metrics_service.cc
@@ -194,6 +194,9 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   VLOG(2) << "Mojo native bridge type is " << native_bridge_type;
 
+  // Save value for RecordNativeBridgeUMA instead of recording
+  // immediately since it must appear in every metrics interval
+  // uploaded to UMA.
   switch (native_bridge_type) {
     case mojom::NativeBridgeType::NONE:
       native_bridge_type_ = NativeBridgeType::NONE;
@@ -208,6 +211,11 @@
   NOTREACHED() << native_bridge_type;
 }
 
+void ArcMetricsService::RecordNativeBridgeUMA() {
+  UMA_HISTOGRAM_ENUMERATION("Arc.NativeBridge", native_bridge_type_,
+                            NativeBridgeType::COUNT);
+}
+
 ArcMetricsService::ProcessObserver::ProcessObserver(
     ArcMetricsService* arc_metrics_service)
     : arc_metrics_service_(arc_metrics_service) {}
diff --git a/components/arc/metrics/arc_metrics_service.h b/components/arc/metrics/arc_metrics_service.h
index 05405c2..8fb6256 100644
--- a/components/arc/metrics/arc_metrics_service.h
+++ b/components/arc/metrics/arc_metrics_service.h
@@ -31,7 +31,8 @@
 class ArcMetricsService : public KeyedService,
                           public mojom::MetricsHost {
  public:
-  // This is public for testing only.
+  // These values are persisted to logs, and should therefore never be
+  // renumbered nor reused. They are public for testing only.
   enum class NativeBridgeType {
     // Native bridge value has not been received from the container yet.
     UNKNOWN = 0,
@@ -65,6 +66,10 @@
                           mojom::BootType boot_type) override;
   void ReportNativeBridge(mojom::NativeBridgeType native_bridge_type) override;
 
+  // Records native bridge UMA according to value received from the
+  // container or as UNKNOWN if the value has not been recieved yet.
+  void RecordNativeBridgeUMA();
+
   NativeBridgeType native_bridge_type_for_testing() const {
     return native_bridge_type_;
   }
diff --git a/components/arc/metrics/arc_metrics_service_unittest.cc b/components/arc/metrics/arc_metrics_service_unittest.cc
index 0e2f5bf..7e77083 100644
--- a/components/arc/metrics/arc_metrics_service_unittest.cc
+++ b/components/arc/metrics/arc_metrics_service_unittest.cc
@@ -239,5 +239,35 @@
             ArcMetricsService::NativeBridgeType::NDK_TRANSLATION);
 }
 
+TEST_F(ArcMetricsServiceTest, RecordNativeBridgeUMA) {
+  base::HistogramTester tester;
+  metrics_service()->RecordNativeBridgeUMA();
+  tester.ExpectUniqueSample(
+      "Arc.NativeBridge",
+      static_cast<int>(ArcMetricsService::NativeBridgeType::UNKNOWN), 1);
+  metrics_service()->ReportNativeBridge(mojom::NativeBridgeType::NONE);
+  // Check that ReportNativeBridge doesn't record histograms.
+  tester.ExpectTotalCount("Arc.NativeBridge", 1);
+  metrics_service()->RecordNativeBridgeUMA();
+  tester.ExpectBucketCount(
+      "Arc.NativeBridge",
+      static_cast<int>(ArcMetricsService::NativeBridgeType::NONE), 1);
+  metrics_service()->ReportNativeBridge(mojom::NativeBridgeType::HOUDINI);
+  tester.ExpectTotalCount("Arc.NativeBridge", 2);
+  metrics_service()->RecordNativeBridgeUMA();
+  tester.ExpectBucketCount(
+      "Arc.NativeBridge",
+      static_cast<int>(ArcMetricsService::NativeBridgeType::HOUDINI), 1);
+  metrics_service()->ReportNativeBridge(
+      mojom::NativeBridgeType::NDK_TRANSLATION);
+  tester.ExpectTotalCount("Arc.NativeBridge", 3);
+  metrics_service()->RecordNativeBridgeUMA();
+  tester.ExpectBucketCount(
+      "Arc.NativeBridge",
+      static_cast<int>(ArcMetricsService::NativeBridgeType::NDK_TRANSLATION),
+      1);
+  tester.ExpectTotalCount("Arc.NativeBridge", 4);
+}
+
 }  // namespace
 }  // namespace arc
diff --git a/components/arc/power/arc_power_bridge_unittest.cc b/components/arc/power/arc_power_bridge_unittest.cc
index e9f02f9..5e683b2c 100644
--- a/components/arc/power/arc_power_bridge_unittest.cc
+++ b/components/arc/power/arc_power_bridge_unittest.cc
@@ -69,7 +69,9 @@
   // Destroys the FakePowerInstance. This results in
   // ArcPowerBridge::OnInstanceClosed() being called.
   void DestroyPowerInstance() {
-    bridge_service_->power()->SetInstance(nullptr, 0);
+    if (!power_instance_)
+      return;
+    bridge_service_->power()->CloseInstance(power_instance_.get());
     power_instance_.reset();
   }
 
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index 528e12e2..5168ecf 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -824,9 +824,20 @@
     return;
   }
 
-  FormData form_data;
-  if (GetSubmittedForm(&form_data)) {
-    FireHostSubmitEvents(form_data, /*known_success=*/true);
+  if (source == SubmissionSource::FRAME_DETACHED) {
+    // Should not access the frame because it is now detached. Instead, use
+    // |constructed_form_| or |last_interacted_form_| depending on whether the
+    // form is formless or not.
+    if (!last_interacted_form_.IsNull()) {
+      FireHostSubmitEvents(last_interacted_form_, /*known_success=*/true);
+    } else if (constructed_form_) {
+      FireHostSubmitEvents(*constructed_form_, /*known_success=*/true);
+    }
+  } else {
+    FormData form_data;
+    if (GetSubmittedForm(&form_data)) {
+      FireHostSubmitEvents(form_data, /*known_success=*/true);
+    }
   }
   ResetLastInteractedElements();
 }
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index 9db53e72..e5bac64 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -791,12 +791,19 @@
     const WebInputElement* input_element = ToWebInputElement(element);
     CR_DEFINE_STATIC_LOCAL(WebString, kValue, ("value"));
     CR_DEFINE_STATIC_LOCAL(WebString, kPlaceholder, ("placeholder"));
+
     if (!force_override && !is_initiating_element &&
         // A text field, with a non-empty value that is NOT the value of the
         // input field's "value" or "placeholder" attribute, is skipped.
+        // Some sites fill the fields with formatting string. To tell the
+        // difference between the values entered by the user and the site, we'll
+        // sanitize the value. If the sanitized value is empty, it means that
+        // the site has filled the field, in this case, the field is not
+        // skipped.
         (IsAutofillableInputElement(input_element) ||
          IsTextAreaElement(*element)) &&
         !element->Value().IsEmpty() &&
+        !SanitizedFieldIsEmpty(element->Value().Utf16()) &&
         (!element->HasAttribute(kValue) ||
          element->GetAttribute(kValue) != element->Value()) &&
         (!element->HasAttribute(kPlaceholder) ||
@@ -1142,8 +1149,12 @@
     FormData* form,
     FormFieldData* field) {
   form->origin = GetCanonicalOriginForDocument(document);
-  DCHECK(document.GetFrame()->Top());
-  form->main_frame_origin = document.GetFrame()->Top()->GetSecurityOrigin();
+  if (document.GetFrame()) {
+    form->main_frame_origin = document.GetFrame()->Top()->GetSecurityOrigin();
+  } else {
+    form->main_frame_origin = url::Origin();
+    NOTREACHED();
+  }
 
   form->is_form_tag = false;
 
@@ -1470,8 +1481,12 @@
   form->name = GetFormIdentifier(form_element);
   form->origin = GetCanonicalOriginForDocument(frame->GetDocument());
   form->action = frame->GetDocument().CompleteURL(form_element.Action());
-  DCHECK(frame->Top());
-  form->main_frame_origin = frame->Top()->GetSecurityOrigin();
+  if (frame->Top()) {
+    form->main_frame_origin = frame->Top()->GetSecurityOrigin();
+  } else {
+    form->main_frame_origin = url::Origin();
+    NOTREACHED();
+  }
   // If the completed URL is not valid, just use the action we get from
   // WebKit.
   if (!form->action.is_valid())
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index d218556..9a831e0 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -122,8 +122,7 @@
                    &sanitized);
   // Some sites have ____-____-____-____ in their credit card number fields, for
   // example.
-  base::ReplaceChars(sanitized, base::ASCIIToUTF16("-_"),
-                     base::ASCIIToUTF16(""), &sanitized);
+  base::RemoveChars(sanitized, base::ASCIIToUTF16("-_"), &sanitized);
   return sanitized;
 }
 
diff --git a/components/autofill/core/browser/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/credit_card_save_manager_unittest.cc
index 17927a00..abfbf1f 100644
--- a/components/autofill/core/browser/credit_card_save_manager_unittest.cc
+++ b/components/autofill/core/browser/credit_card_save_manager_unittest.cc
@@ -2459,8 +2459,8 @@
   // Add a masked credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
   CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
-  test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11", "2017",
-                          "1");
+  test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
+                          NextYear().c_str(), "1");
   credit_card.SetNetworkForMaskedCard(kVisaCard);
   personal_data_.AddServerCreditCard(credit_card);
 
@@ -2498,8 +2498,8 @@
   // Add a masked credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
   CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
-  test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11", "2017",
-                          "1");
+  test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
+                          NextYear().c_str(), "1");
   credit_card.SetNetworkForMaskedCard(kVisaCard);
   personal_data_.AddServerCreditCard(credit_card);
 
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index 69f21fd..2d072c8 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -37,7 +37,6 @@
 
 namespace autofill {
 class AutofillInteractiveTest;
-class AutofillTest;
 class PersonalDataManagerObserver;
 class PersonalDataManagerFactory;
 }  // namespace autofill
@@ -293,6 +292,11 @@
  protected:
   // Only PersonalDataManagerFactory and certain tests can create instances of
   // PersonalDataManager.
+  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, AddProfile_CrazyCharacters);
+  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, AddProfile_Invalid);
+  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
+                           AddCreditCard_CrazyCharacters);
+  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, AddCreditCard_Invalid);
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, FirstMiddleLast);
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AutofillIsEnabledAtStartup);
   FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
@@ -352,7 +356,6 @@
                            GetCreditCardSuggestions_NoCardsLoadedIfDisabled);
 
   friend class autofill::AutofillInteractiveTest;
-  friend class autofill::AutofillTest;
   friend class autofill::PersonalDataManagerFactory;
   friend class FormDataImporterTest;
   friend class PersonalDataManagerTest;
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 9d9a05f..b6a909f 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -390,6 +390,156 @@
   EXPECT_EQ(kArbitraryTime, results[0]->modification_date());
 }
 
+// Test filling profiles with unicode strings and crazy characters.
+TEST_F(PersonalDataManagerTest, AddProfile_CrazyCharacters) {
+  std::vector<AutofillProfile> profiles;
+  AutofillProfile profile1;
+  profile1.SetRawInfo(
+      NAME_FIRST,
+      base::WideToUTF16(L"\u0623\u0648\u0628\u0627\u0645\u0627 "
+                        L"\u064a\u0639\u062a\u0630\u0631 "
+                        L"\u0647\u0627\u062a\u0641\u064a\u0627 "
+                        L"\u0644\u0645\u0648\u0638\u0641\u0629 "
+                        L"\u0633\u0648\u062f\u0627\u0621 "
+                        L"\u0627\u0633\u062a\u0642\u0627\u0644\u062a "
+                        L"\u0628\u0633\u0628\u0628 "
+                        L"\u062a\u0635\u0631\u064a\u062d\u0627\u062a "
+                        L"\u0645\u062c\u062a\u0632\u0623\u0629"));
+  profile1.SetRawInfo(NAME_MIDDLE, base::WideToUTF16(L"BANK\xcBERF\xc4LLE"));
+  profile1.SetRawInfo(EMAIL_ADDRESS,
+                      base::WideToUTF16(L"\uacbd\uc81c \ub274\uc2a4 "
+                                        L"\ub354\ubcf4\uae30@google.com"));
+  profile1.SetRawInfo(
+      ADDRESS_HOME_LINE1,
+      base::WideToUTF16(L"\uad6d\uc815\uc6d0\xb7\uac80\ucc30, "
+                        L"\ub178\ubb34\ud604\uc815\ubd80 "
+                        L"\ub300\ubd81\uc811\ucd09 \ub2f4\ub2f9 "
+                        L"\uc778\uc0ac\ub4e4 \uc870\uc0ac"));
+  profile1.SetRawInfo(
+      ADDRESS_HOME_CITY,
+      base::WideToUTF16(L"\u653f\u5e9c\u4e0d\u6392\u9664\u7acb\u6cd5"
+                        L"\u898f\u7ba1\u5c0e\u904a"));
+  profile1.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"YOHO_54676"));
+  profile1.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
+                      base::WideToUTF16(L"861088828000"));
+  profile1.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
+                   base::WideToUTF16(L"India"), "en-US");
+  profiles.push_back(profile1);
+
+  AutofillProfile profile2;
+  profile2.SetRawInfo(NAME_FIRST,
+                      base::WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a "
+                                        L"\u677e\u9690\u9547\u4ead\u67ab\u516c"
+                                        L"\u8def1915\u53f7"));
+  profile2.SetRawInfo(NAME_LAST, base::WideToUTF16(L"aguantó"));
+  profile2.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"HOME 94043"));
+  profiles.push_back(profile2);
+
+  AutofillProfile profile3;
+  profile3.SetRawInfo(EMAIL_ADDRESS, base::WideToUTF16(L"sue@example.com"));
+  profile3.SetRawInfo(COMPANY_NAME, base::WideToUTF16(L"Company X"));
+  profiles.push_back(profile3);
+
+  AutofillProfile profile4;
+  profile4.SetRawInfo(NAME_FIRST, base::WideToUTF16(L"Joe 3254"));
+  profile4.SetRawInfo(NAME_LAST,
+                      base::WideToUTF16(L"\u8bb0\u8d262\u5e74\u591a"));
+  profile4.SetRawInfo(
+      ADDRESS_HOME_ZIP,
+      base::WideToUTF16(L"\uff08\u90ae\u7f16\uff1a201504\uff09"));
+  profile4.SetRawInfo(EMAIL_ADDRESS,
+                      base::WideToUTF16(L"télévision@example.com"));
+  profile4.SetRawInfo(
+      COMPANY_NAME,
+      base::WideToUTF16(L"\u0907\u0932\u0947\u0915\u093f\u091f\u094d"
+                        L"\u0930\u0928\u093f\u0915\u094d\u0938, "
+                        L"\u0905\u092a\u094b\u0932\u094b "
+                        L"\u091f\u093e\u092f\u0930\u094d\u0938 "
+                        L"\u0906\u0926\u093f"));
+  profiles.push_back(profile4);
+
+  AutofillProfile profile5;
+  profile5.SetRawInfo(NAME_FIRST, base::WideToUTF16(L"Larry"));
+  profile5.SetRawInfo(
+      NAME_LAST, base::WideToUTF16(L"\u0938\u094d\u091f\u093e\u0902\u092a "
+                                   L"\u0921\u094d\u092f\u0942\u091f\u0940"));
+  profile5.SetRawInfo(ADDRESS_HOME_ZIP,
+                      base::WideToUTF16(L"111111111111110000GOOGLE"));
+  profile5.SetRawInfo(EMAIL_ADDRESS, base::WideToUTF16(L"page@000000.com"));
+  profile5.SetRawInfo(COMPANY_NAME, base::WideToUTF16(L"Google"));
+  profiles.push_back(profile5);
+
+  AutofillProfile profile6;
+  profile6.SetRawInfo(NAME_FIRST,
+                      base::WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a "
+                                        L"\u677e\u9690\u9547\u4ead\u67ab\u516c"
+                                        L"\u8def1915\u53f7"));
+  profile6.SetRawInfo(
+      NAME_LAST,
+      base::WideToUTF16(L"\u0646\u062c\u0627\u0645\u064a\u0646\u0627 "
+                        L"\u062f\u0639\u0645\u0647\u0627 "
+                        L"\u0644\u0644\u0631\u0626\u064a\u0633 "
+                        L"\u0627\u0644\u0633\u0648\u062f\u0627\u0646"
+                        L"\u064a \u0639\u0645\u0631 "
+                        L"\u0627\u0644\u0628\u0634\u064a\u0631"));
+  profile6.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"HOME 94043"));
+  profiles.push_back(profile6);
+
+  AutofillProfile profile7;
+  profile7.SetRawInfo(NAME_FIRST,
+                      base::WideToUTF16(L"&$%$$$ TESTO *&*&^&^& MOKO"));
+  profile7.SetRawInfo(NAME_MIDDLE, base::WideToUTF16(L"WOHOOOO$$$$$$$$****"));
+  profile7.SetRawInfo(EMAIL_ADDRESS, base::WideToUTF16(L"yuvu@example.com"));
+  profile7.SetRawInfo(ADDRESS_HOME_LINE1,
+                      base::WideToUTF16(L"34544, anderson ST.(120230)"));
+  profile7.SetRawInfo(ADDRESS_HOME_CITY, base::WideToUTF16(L"Sunnyvale"));
+  profile7.SetRawInfo(ADDRESS_HOME_STATE, base::WideToUTF16(L"CA"));
+  profile7.SetRawInfo(ADDRESS_HOME_ZIP, base::WideToUTF16(L"94086"));
+  profile7.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
+                      base::WideToUTF16(L"15466784565"));
+  profile7.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
+                   base::WideToUTF16(L"United States"), "en-US");
+  profiles.push_back(profile7);
+
+  personal_data_->SetProfiles(&profiles);
+
+  WaitForOnPersonalDataChanged();
+
+  ASSERT_EQ(profiles.size(), personal_data_->GetProfiles().size());
+  for (size_t i = 0; i < profiles.size(); ++i) {
+    EXPECT_TRUE(
+        base::ContainsValue(profiles, *personal_data_->GetProfiles()[i]));
+  }
+}
+
+// Test filling in invalid values for profiles are saved as-is. Phone
+// information entered into the settings UI is not validated or rejected except
+// for duplicates.
+TEST_F(PersonalDataManagerTest, AddProfile_Invalid) {
+  // First try profiles with invalid ZIP input.
+  AutofillProfile without_invalid;
+  without_invalid.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Will"));
+  without_invalid.SetRawInfo(ADDRESS_HOME_CITY,
+                             base::ASCIIToUTF16("Sunnyvale"));
+  without_invalid.SetRawInfo(ADDRESS_HOME_STATE, base::ASCIIToUTF16("CA"));
+  without_invalid.SetRawInfo(ADDRESS_HOME_ZIP, base::ASCIIToUTF16("my_zip"));
+  without_invalid.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
+                          base::ASCIIToUTF16("United States"), "en-US");
+
+  AutofillProfile with_invalid = without_invalid;
+  with_invalid.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
+                          base::ASCIIToUTF16("Invalid_Phone_Number"));
+
+  std::vector<AutofillProfile> profiles;
+  profiles.push_back(with_invalid);
+  personal_data_->SetProfiles(&profiles);
+
+  ASSERT_EQ(1u, personal_data_->GetProfiles().size());
+  AutofillProfile profile = *personal_data_->GetProfiles()[0];
+  ASSERT_NE(without_invalid.GetRawInfo(PHONE_HOME_WHOLE_NUMBER),
+            profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+}
+
 // Tests that SaveImportedProfile sets the modification date on new profiles.
 TEST_F(PersonalDataManagerTest, SaveImportedProfileSetModificationDate) {
   AutofillProfile profile(test::GetFullProfile());
@@ -564,6 +714,82 @@
   EXPECT_EQ(kArbitraryTime, results[0]->modification_date());
 }
 
+// Test filling credit cards with unicode strings and crazy characters.
+TEST_F(PersonalDataManagerTest, AddCreditCard_CrazyCharacters) {
+  std::vector<CreditCard> cards;
+  CreditCard card1;
+  card1.SetRawInfo(CREDIT_CARD_NAME_FULL,
+                   base::WideToUTF16(L"\u751f\u6d3b\u5f88\u6709\u89c4\u5f8b "
+                                     L"\u4ee5\u73a9\u4e3a\u4e3b"));
+  card1.SetRawInfo(CREDIT_CARD_NUMBER, base::WideToUTF16(L"6011111111111117"));
+  card1.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"12"));
+  card1.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2011"));
+  cards.push_back(card1);
+
+  CreditCard card2;
+  card2.SetRawInfo(CREDIT_CARD_NAME_FULL, base::WideToUTF16(L"John Williams"));
+  card2.SetRawInfo(CREDIT_CARD_NUMBER, base::WideToUTF16(L"WokoAwesome12345"));
+  card2.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"10"));
+  card2.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2015"));
+  cards.push_back(card2);
+
+  CreditCard card3;
+  card3.SetRawInfo(
+      CREDIT_CARD_NAME_FULL,
+      base::WideToUTF16(L"\u0623\u062d\u0645\u062f\u064a "
+                        L"\u0646\u062c\u0627\u062f "
+                        L"\u0644\u0645\u062d\u0627\u0648\u0644\u0647 "
+                        L"\u0627\u063a\u062a\u064a\u0627\u0644 "
+                        L"\u0641\u064a \u0645\u062f\u064a\u0646\u0629 "
+                        L"\u0647\u0645\u062f\u0627\u0646 "));
+  card3.SetRawInfo(
+      CREDIT_CARD_NUMBER,
+      base::WideToUTF16(L"\u092a\u0941\u0928\u0930\u094d\u091c\u0940"
+                        L"\u0935\u093f\u0924 \u0939\u094b\u0917\u093e "
+                        L"\u0928\u093e\u0932\u0902\u0926\u093e"));
+  card3.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"10"));
+  card3.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2015"));
+  cards.push_back(card3);
+
+  CreditCard card4;
+  card4.SetRawInfo(
+      CREDIT_CARD_NAME_FULL,
+      base::WideToUTF16(L"\u039d\u03ad\u03b5\u03c2 "
+                        L"\u03c3\u03c5\u03b3\u03c7\u03c9\u03bd\u03b5"
+                        L"\u03cd\u03c3\u03b5\u03b9\u03c2 "
+                        L"\u03ba\u03b1\u03b9 "
+                        L"\u03ba\u03b1\u03c4\u03b1\u03c1\u03b3\u03ae"
+                        L"\u03c3\u03b5\u03b9\u03c2"));
+  card4.SetRawInfo(CREDIT_CARD_NUMBER,
+                   base::WideToUTF16(L"00000000000000000000000"));
+  card4.SetRawInfo(CREDIT_CARD_EXP_MONTH, base::WideToUTF16(L"01"));
+  card4.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, base::WideToUTF16(L"2016"));
+  cards.push_back(card4);
+
+  personal_data_->SetCreditCards(&cards);
+
+  WaitForOnPersonalDataChanged();
+
+  ASSERT_EQ(cards.size(), personal_data_->GetCreditCards().size());
+  for (size_t i = 0; i < cards.size(); ++i) {
+    EXPECT_TRUE(
+        base::ContainsValue(cards, *personal_data_->GetCreditCards()[i]));
+  }
+}
+
+// Test invalid credit card numbers typed in settings UI should be saved as-is.
+TEST_F(PersonalDataManagerTest, AddCreditCard_Invalid) {
+  CreditCard card;
+  card.SetRawInfo(CREDIT_CARD_NUMBER, base::ASCIIToUTF16("Not_0123-5Checked"));
+
+  std::vector<CreditCard> cards;
+  cards.push_back(card);
+  personal_data_->SetCreditCards(&cards);
+
+  ASSERT_EQ(1u, personal_data_->GetCreditCards().size());
+  ASSERT_EQ(card, *personal_data_->GetCreditCards()[0]);
+}
+
 TEST_F(PersonalDataManagerTest, UpdateUnverifiedProfilesAndCreditCards) {
   // Start with unverified data.
   AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
diff --git a/components/autofill/core/common/autofill_util.cc b/components/autofill/core/common/autofill_util.cc
index 718f9221..b19f35b 100644
--- a/components/autofill/core/common/autofill_util.cc
+++ b/components/autofill/core/common/autofill_util.cc
@@ -188,4 +188,17 @@
                            base::SPLIT_WANT_NONEMPTY);
 }
 
+bool SanitizedFieldIsEmpty(const base::string16& value) {
+  // Some sites enter values such as ____-____-____-____ or (___)-___-____ in
+  // their fields. Check if the field value is empty after the removal of the
+  // formatting characters.
+  static base::string16 formatting =
+      (base::ASCIIToUTF16("-_()/") +
+       base::char16(base::i18n::kRightToLeftMark) +
+       base::char16(base::i18n::kLeftToRightMark))
+          .append(base::kWhitespaceUTF16);
+
+  return (value.find_first_not_of(formatting) == base::StringPiece::npos);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/common/autofill_util.h b/components/autofill/core/common/autofill_util.h
index e51d7bd..533945e 100644
--- a/components/autofill/core/common/autofill_util.h
+++ b/components/autofill/core/common/autofill_util.h
@@ -89,6 +89,11 @@
 std::vector<std::string> LowercaseAndTokenizeAttributeString(
     const std::string& attribute);
 
+// Returns true if and only if the field value has no character except the
+// formatting characters. This means that the field value is a formatting string
+// entered by the website and not a real value entered by the user.
+bool SanitizedFieldIsEmpty(const base::string16& value);
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_COMMON_AUTOFILL_UTIL_H_
diff --git a/components/autofill/ios/browser/BUILD.gn b/components/autofill/ios/browser/BUILD.gn
index 6be8ae6..e9624ae 100644
--- a/components/autofill/ios/browser/BUILD.gn
+++ b/components/autofill/ios/browser/BUILD.gn
@@ -9,12 +9,12 @@
   sources = [
     "autofill_agent.h",
     "autofill_agent.mm",
-    "autofill_client_ios.h",
-    "autofill_client_ios.mm",
     "autofill_client_ios_bridge.h",
     "autofill_driver_ios.h",
     "autofill_driver_ios.mm",
     "autofill_driver_ios_bridge.h",
+    "autofill_util.h",
+    "autofill_util.mm",
     "credit_card_util.h",
     "credit_card_util.mm",
     "form_suggestion.h",
diff --git a/components/autofill/ios/browser/autofill_client_ios.mm b/components/autofill/ios/browser/autofill_client_ios.mm
deleted file mode 100644
index 88e705b..0000000
--- a/components/autofill/ios/browser/autofill_client_ios.mm
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "components/autofill/ios/browser/autofill_client_ios.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h"
-#include "components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h"
-#include "components/autofill/core/browser/autofill_save_card_infobar_mobile.h"
-#include "components/autofill/core/browser/ui/card_unmask_prompt_view.h"
-#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
-#include "components/autofill/core/common/autofill_pref_names.h"
-#include "components/prefs/pref_service.h"
-#include "google_apis/gaia/identity_provider.h"
-#import "ios/web/public/navigation_item.h"
-#import "ios/web/public/navigation_manager.h"
-#include "ios/web/public/ssl_status.h"
-#import "ios/web/public/web_state/web_state.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace autofill {
-
-AutofillClientIOS::AutofillClientIOS(
-    PrefService* pref_service,
-    PersonalDataManager* personal_data_manager,
-    web::WebState* web_state,
-    id<AutofillClientIOSBridge> bridge,
-    std::unique_ptr<IdentityProvider> identity_provider,
-    scoped_refptr<AutofillWebDataService> autofill_web_data_service)
-    : pref_service_(pref_service),
-      personal_data_manager_(personal_data_manager),
-      web_state_(web_state),
-      bridge_(bridge),
-      identity_provider_(std::move(identity_provider)),
-      autofill_web_data_service_(autofill_web_data_service) {}
-
-AutofillClientIOS::~AutofillClientIOS() {
-  HideAutofillPopup();
-}
-
-PersonalDataManager* AutofillClientIOS::GetPersonalDataManager() {
-  return personal_data_manager_;
-}
-
-PrefService* AutofillClientIOS::GetPrefs() {
-  return pref_service_;
-}
-
-// TODO(crbug.com/535784): Implement this when adding credit card upload.
-syncer::SyncService* AutofillClientIOS::GetSyncService() {
-  return nullptr;
-}
-
-IdentityProvider* AutofillClientIOS::GetIdentityProvider() {
-  return identity_provider_.get();
-}
-
-ukm::UkmRecorder* AutofillClientIOS::GetUkmRecorder() {
-  return nullptr;
-}
-
-AddressNormalizer* AutofillClientIOS::GetAddressNormalizer() {
-  return nullptr;
-}
-
-SaveCardBubbleController* AutofillClientIOS::GetSaveCardBubbleController() {
-  return nullptr;
-}
-
-void AutofillClientIOS::ShowAutofillSettings() {
-  NOTREACHED();
-}
-
-void AutofillClientIOS::ShowUnmaskPrompt(
-    const CreditCard& card,
-    UnmaskCardReason reason,
-    base::WeakPtr<CardUnmaskDelegate> delegate) {}
-
-void AutofillClientIOS::OnUnmaskVerificationResult(PaymentsRpcResult result) {}
-
-void AutofillClientIOS::ConfirmSaveCreditCardLocally(
-    const CreditCard& card,
-    const base::Closure& callback) {}
-
-void AutofillClientIOS::ConfirmSaveCreditCardToCloud(
-    const CreditCard& card,
-    std::unique_ptr<base::DictionaryValue> legal_message,
-    bool should_cvc_be_requested,
-    const base::Closure& callback) {}
-
-void AutofillClientIOS::ConfirmCreditCardFillAssist(
-    const CreditCard& card,
-    const base::Closure& callback) {}
-
-void AutofillClientIOS::LoadRiskData(
-    const base::Callback<void(const std::string&)>& callback) {}
-
-bool AutofillClientIOS::HasCreditCardScanFeature() {
-  return false;
-}
-
-void AutofillClientIOS::ScanCreditCard(const CreditCardScanCallback& callback) {
-  NOTREACHED();
-}
-
-void AutofillClientIOS::ShowAutofillPopup(
-    const gfx::RectF& element_bounds,
-    base::i18n::TextDirection text_direction,
-    const std::vector<Suggestion>& suggestions,
-    base::WeakPtr<AutofillPopupDelegate> delegate) {
-  [bridge_ showAutofillPopup:suggestions popupDelegate:delegate];
-}
-
-void AutofillClientIOS::HideAutofillPopup() {
-  [bridge_ hideAutofillPopup];
-}
-
-bool AutofillClientIOS::IsAutocompleteEnabled() {
-  // For browser, Autocomplete is always enabled as part of Autofill.
-  return GetPrefs()->GetBoolean(prefs::kAutofillEnabled);
-}
-
-void AutofillClientIOS::UpdateAutofillPopupDataListValues(
-    const std::vector<base::string16>& values,
-    const std::vector<base::string16>& labels) {
-  NOTREACHED();
-}
-
-void AutofillClientIOS::PropagateAutofillPredictions(
-    content::RenderFrameHost* rfh,
-    const std::vector<FormStructure*>& forms) {}
-
-void AutofillClientIOS::DidFillOrPreviewField(
-    const base::string16& autofilled_value,
-    const base::string16& profile_full_name) {}
-
-scoped_refptr<AutofillWebDataService> AutofillClientIOS::GetDatabase() {
-  return autofill_web_data_service_;
-}
-
-void AutofillClientIOS::DidInteractWithNonsecureCreditCardInput() {}
-
-bool AutofillClientIOS::IsContextSecure() {
-  // This implementation differs slightly from other platforms. Other platforms'
-  // implementations check for the presence of active mixed content, but because
-  // the iOS web view blocks active mixed content without an option to run it,
-  // there is no need to check for active mixed conent here.
-  web::NavigationManager* manager = web_state_->GetNavigationManager();
-  web::NavigationItem* nav_item = manager->GetLastCommittedItem();
-  if (!nav_item)
-    return false;
-
-  const web::SSLStatus& ssl = nav_item->GetSSL();
-  return nav_item->GetURL().SchemeIsCryptographic() && ssl.certificate &&
-         (!net::IsCertStatusError(ssl.cert_status) ||
-          net::IsCertStatusMinorError(ssl.cert_status));
-}
-
-bool AutofillClientIOS::ShouldShowSigninPromo() {
-  return false;
-}
-
-void AutofillClientIOS::ExecuteCommand(int id) {
-  NOTIMPLEMENTED();
-}
-
-bool AutofillClientIOS::IsAutofillSupported() {
-  return true;
-}
-
-}  // namespace autofill
diff --git a/components/autofill/ios/browser/autofill_util.h b/components/autofill/ios/browser/autofill_util.h
new file mode 100644
index 0000000..828c811
--- /dev/null
+++ b/components/autofill/ios/browser/autofill_util.h
@@ -0,0 +1,17 @@
+// 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_AUTOFILL_IOS_BROWSER_AUTOFILL_UTIL_H_
+#define COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_UTIL_H_
+
+#import "ios/web/public/web_state/web_state.h"
+
+namespace autofill {
+
+// Checks if current context is secure from an autofill standpoint.
+bool IsContextSecureForWebState(web::WebState* web_state);
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_UTIL_H_
diff --git a/components/autofill/ios/browser/autofill_util.mm b/components/autofill/ios/browser/autofill_util.mm
new file mode 100644
index 0000000..1fa0772
--- /dev/null
+++ b/components/autofill/ios/browser/autofill_util.mm
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/ios/browser/autofill_util.h"
+
+#import "ios/web/public/navigation_item.h"
+#import "ios/web/public/navigation_manager.h"
+#include "ios/web/public/ssl_status.h"
+
+namespace autofill {
+
+bool IsContextSecureForWebState(web::WebState* web_state) {
+  // This implementation differs slightly from other platforms. Other platforms'
+  // implementations check for the presence of active mixed content, but because
+  // the iOS web view blocks active mixed content without an option to run it,
+  // there is no need to check for active mixed content here.
+  web::NavigationManager* manager = web_state->GetNavigationManager();
+  web::NavigationItem* nav_item = manager->GetLastCommittedItem();
+  if (!nav_item)
+    return false;
+
+  const web::SSLStatus& ssl = nav_item->GetSSL();
+  return nav_item->GetURL().SchemeIsCryptographic() && ssl.certificate &&
+         (!net::IsCertStatusError(ssl.cert_status) ||
+          net::IsCertStatusMinorError(ssl.cert_status));
+}
+
+}  // namespace autofill
diff --git a/components/cast_channel/cast_auth_util_unittest.cc b/components/cast_channel/cast_auth_util_unittest.cc
index d7e28972..d1493f2 100644
--- a/components/cast_channel/cast_auth_util_unittest.cc
+++ b/components/cast_channel/cast_auth_util_unittest.cc
@@ -74,7 +74,8 @@
       auth_response, signed_data, cast_certificate::CRLPolicy::CRL_OPTIONAL,
       nullptr, nullptr, now);
   EXPECT_TRUE(result.success());
-  EXPECT_EQ(AuthResult::POLICY_NONE, result.channel_policies);
+  EXPECT_EQ(static_cast<unsigned>(AuthResult::POLICY_NONE),
+            result.channel_policies);
 }
 
 TEST_F(CastAuthUtilTest, VerifyBadCA) {
diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc
index 3a33c9b..a234fa9 100644
--- a/components/crash/content/app/crashpad_win.cc
+++ b/components/crash/content/app/crashpad_win.cc
@@ -172,8 +172,10 @@
   if (crash_keys_str && base::SplitStringIntoKeyValuePairs(
                             reinterpret_cast<const char*>(crash_keys_str), ':',
                             ',', &crash_keys)) {
+    auto* simple_annotations =
+        crashpad::CrashpadInfo::GetCrashpadInfo()->simple_annotations();
     for (const auto& crash_key : crash_keys) {
-      base::debug::SetCrashKeyValue(crash_key.first, crash_key.second);
+      simple_annotations->SetKeyValue(crash_key.first, crash_key.second);
     }
   }
   DumpWithoutCrashing();
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java b/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java
index 28e88aa..9086f857 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java
@@ -23,6 +23,7 @@
 
 import org.chromium.base.Log;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MetricsUtils.HistogramDelta;
 import org.chromium.net.CronetTestRule.OnlyRunNativeCronet;
@@ -163,6 +164,7 @@
     @SmallTest
     @Feature({"Cronet"})
     @OnlyRunNativeCronet
+    @DisabledTest(message = "crbug.com/793154")
     public void testQuicDisabled() throws Exception {
         ExperimentalCronetEngine.Builder cronetEngineBuilder =
                 new ExperimentalCronetEngine.Builder(getContext());
@@ -257,6 +259,7 @@
     @SmallTest
     @OnlyRunNativeCronet
     @Feature({"Cronet"})
+    @DisabledTest(message = "crbug.com/793154")
     public void testPrefsWriteRead() throws Exception {
         // When the loop is run for the first time, network quality is written to the disk. The
         // test verifies that in the next loop, the network quality is read back.
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
index 6788cbe..f1f1ec6d 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
@@ -22,6 +22,7 @@
 
 import org.chromium.base.Log;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.net.CronetTestRule.OnlyRunNativeCronet;
 import org.chromium.net.MetricsTestUtil.TestRequestFinishedListener;
@@ -167,6 +168,7 @@
     @Feature({"Cronet"})
     @OnlyRunNativeCronet
     @SuppressWarnings("deprecation")
+    @DisabledTest(message = "crbug.com/793154")
     public void testNQEWithQuic() throws Exception {
         ExperimentalCronetEngine cronetEngine = mBuilder.build();
         String quicURL = QuicTestServer.getServerURL() + "/simple.txt";
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index 522ef9e..d2ce9a1d 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -702,22 +702,6 @@
   return base::TimeTicks::Now();
 }
 
-void DataReductionProxyConfig::OnInsecureProxyWarmupURLProbeStatusChange(
-    bool insecure_proxies_allowed,
-    bool is_core_proxy) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  bool old_status =
-      network_properties_manager_->IsInsecureProxyAllowed(is_core_proxy);
-  network_properties_manager_->SetHasWarmupURLProbeFailed(
-      false, is_core_proxy, !insecure_proxies_allowed);
-
-  if (old_status ==
-      network_properties_manager_->IsInsecureProxyAllowed(is_core_proxy)) {
-    return;
-  }
-  ReloadConfig();
-}
-
 net::ProxyConfig DataReductionProxyConfig::ProxyConfigIgnoringHoldback() const {
   if (!enabled_by_user_ || config_values_->proxies_for_http().empty())
     return net::ProxyConfig::CreateDirect();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
index 3a06b6b..f9e518f 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -202,13 +202,6 @@
   const NetworkPropertiesManager& GetNetworkPropertiesManager() const;
 
  protected:
-  // Should be called when there is a change in the status of the availability
-  // of the insecure data saver proxies triggered due to fetching of the warmup
-  // URL. |is_core_proxy| indicates if the warmup URL was fetched over a core
-  // data saver proxy or not.
-  void OnInsecureProxyWarmupURLProbeStatusChange(bool insecure_proxies_allowed,
-                                                 bool is_core_proxy);
-
   virtual base::TimeTicks GetTicksNow() const;
 
   // Updates the Data Reduction Proxy configurator with the current config.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
index 7855fe8..046df80 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
@@ -107,7 +107,6 @@
   void SetCurrentNetworkID(const std::string& network_id);
 
   using DataReductionProxyConfig::UpdateConfigForTesting;
-  using DataReductionProxyConfig::OnInsecureProxyWarmupURLProbeStatusChange;
   using DataReductionProxyConfig::HandleWarmupFetcherResponse;
 
  private:
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index 354e539..2e614778 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -274,56 +274,6 @@
   EXPECT_EQ(std::vector<net::ProxyServer>(), GetConfiguredProxiesForHttp());
 }
 
-TEST_F(DataReductionProxyConfigTest,
-       TestOnInsecureProxyWarmupURLProbeStatusChange) {
-  base::FieldTrialList field_trial_list(nullptr);
-
-  const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI(
-      "https://secure_origin.net:443", net::ProxyServer::SCHEME_HTTP);
-  const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI(
-      "insecure_origin.net:80", net::ProxyServer::SCHEME_HTTP);
-  SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy});
-
-  ResetSettings();
-
-  test_config()->UpdateConfigForTesting(true /* enabled */,
-                                        false /* secure_proxies_allowed */,
-                                        true /* insecure_proxies_allowed */);
-  test_config()->OnNewClientConfigFetched();
-  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}),
-            GetConfiguredProxiesForHttp());
-
-  test_config()->UpdateConfigForTesting(true, true, false);
-  test_config()->OnNewClientConfigFetched();
-  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy}),
-            GetConfiguredProxiesForHttp());
-
-  test_config()->UpdateConfigForTesting(true, false, false);
-  test_config()->OnNewClientConfigFetched();
-  EXPECT_EQ(std::vector<net::ProxyServer>(), GetConfiguredProxiesForHttp());
-
-  test_config()->UpdateConfigForTesting(true, true, true);
-  test_config()->OnNewClientConfigFetched();
-  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
-            GetConfiguredProxiesForHttp());
-
-  // Calling OnInsecureProxyWarmupURLProbeStatusChange should reload the config.
-  test_config()->OnInsecureProxyWarmupURLProbeStatusChange(
-      false /* insecure_proxies_allowed */, false /* is_core_proxy */);
-  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy}),
-            GetConfiguredProxiesForHttp());
-
-  // Calling OnInsecureProxyWarmupURLProbeStatusChange again with the same
-  // status has no effect.
-  test_config()->OnInsecureProxyWarmupURLProbeStatusChange(false, false);
-  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy}),
-            GetConfiguredProxiesForHttp());
-
-  test_config()->OnInsecureProxyWarmupURLProbeStatusChange(true, false);
-  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
-            GetConfiguredProxiesForHttp());
-}
-
 TEST_F(DataReductionProxyConfigTest, TestOnConnectionChangePersistedData) {
   base::FieldTrialList field_trial_list(nullptr);
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h
index 5672c33..63eb1be 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h
@@ -32,18 +32,17 @@
   DataReductionProxyConfigurator(net::NetLog* net_log,
                                  DataReductionProxyEventCreator* event_creator);
 
-  virtual ~DataReductionProxyConfigurator();
+  ~DataReductionProxyConfigurator();
 
   // Enables data reduction using the proxy servers in |proxies_for_http|.
   // TODO: crbug.com/675764: Pass a vector of DataReductionProxyServer
   // instead of net::ProxyServer.
-  virtual void Enable(
-      const NetworkPropertiesManager& network_properties_manager,
-      const std::vector<DataReductionProxyServer>& proxies_for_http);
+  void Enable(const NetworkPropertiesManager& network_properties_manager,
+              const std::vector<DataReductionProxyServer>& proxies_for_http);
 
   // Constructs a proxy configuration suitable for disabling the Data Reduction
   // proxy.
-  virtual void Disable();
+  void Disable();
 
   // Sets the host patterns to bypass.
   //
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h
index 008d019..320b6fe 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h
@@ -15,7 +15,9 @@
  public:
   virtual ~DataReductionProxyConfigValues() {}
 
-  // Returns the HTTP proxy servers to be used.
+  // Returns the HTTP proxy servers to be used. Proxies that cannot be used
+  // because they are temporarily or permanently marked as bad are also
+  // included.
   virtual const std::vector<DataReductionProxyServer>& proxies_for_http()
       const = 0;
 };
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc
index e8634a5..ddf472a 100644
--- a/components/error_page/common/localized_error.cc
+++ b/components/error_page/common/localized_error.cc
@@ -37,10 +37,6 @@
 #include "base/win/windows_version.h"
 #endif
 
-#if defined(OS_ANDROID)
-#include "components/offline_pages/core/offline_page_feature.h"
-#endif
-
 namespace error_page {
 
 namespace {
@@ -1062,8 +1058,7 @@
   if (!is_post && !reload_visible && !show_saved_copy_visible &&
       !is_incognito && failed_url.is_valid() &&
       failed_url.SchemeIsHTTPOrHTTPS() &&
-      IsSuggested(options.suggestions, SUGGEST_OFFLINE_CHECKS) &&
-      offline_pages::IsOfflinePagesAsyncDownloadEnabled()) {
+      IsSuggested(options.suggestions, SUGGEST_OFFLINE_CHECKS)) {
     std::unique_ptr<base::DictionaryValue> download_button =
         base::MakeUnique<base::DictionaryValue>();
     download_button->SetString(
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc
index ab18586..a9a33b7 100644
--- a/components/exo/client_controlled_shell_surface.cc
+++ b/components/exo/client_controlled_shell_surface.cc
@@ -71,7 +71,6 @@
                                                            bool can_minimize,
                                                            int container)
     : ShellSurface(surface,
-                   BoundsMode::CLIENT,
                    gfx::Point(),
                    true,
                    can_minimize,
@@ -158,28 +157,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// ShellSurface overrides:
-
-void ClientControlledShellSurface::Move() {
-  TRACE_EVENT0("exo", "ClientControlledShellSurface::Move");
-
-  if (!widget_)
-    return;
-
-  AttemptToStartDrag(HTCAPTION);
-}
-
-void ClientControlledShellSurface::Resize(int component) {
-  TRACE_EVENT1("exo", "ClientControlledShellSurface::Resize", "component",
-               component);
-  // TODO(oshima): Implement this.
-}
-
-float ClientControlledShellSurface::GetScale() const {
-  return scale_;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // SurfaceDelegate overrides:
 
 void ClientControlledShellSurface::OnSurfaceCommit() {
@@ -220,6 +197,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 // views::WidgetDelegate overrides:
 
+bool ClientControlledShellSurface::CanResize() const {
+  return false;
+}
+
 void ClientControlledShellSurface::SaveWindowPlacement(
     const gfx::Rect& bounds,
     ui::WindowShowState show_state) {}
@@ -295,7 +276,31 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// ShellSurface, private:
+// ShellSurface overrides:
+
+void ClientControlledShellSurface::SetWidgetBounds(const gfx::Rect& bounds) {
+  if (!resizer_) {
+    ShellSurface::SetWidgetBounds(bounds);
+    return;
+  }
+
+  // TODO(domlaskowski): Synchronize window state transitions with the client,
+  // and abort client-side dragging on transition to fullscreen.
+  // See crbug.com/699746.
+  DLOG_IF(ERROR, widget_->GetWindowBoundsInScreen().size() != bounds.size())
+      << "Window size changed during client-driven drag";
+
+  // Convert from screen to display coordinates.
+  gfx::Point origin = bounds.origin();
+  wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin);
+
+  // Move the window relative to the current display.
+  widget_->GetNativeWindow()->SetBounds(gfx::Rect(origin, bounds.size()));
+  UpdateSurfaceBounds();
+
+  // Render phantom windows when beyond the current display.
+  resizer_->Drag(GetMouseLocation(), 0);
+}
 
 void ClientControlledShellSurface::InitializeWindowState(
     ash::wm::WindowState* window_state) {
@@ -306,17 +311,30 @@
   window_state->set_ignore_keyboard_bounds_change(true);
 }
 
-void ClientControlledShellSurface::AttemptToStartDrag(int component) {
-  DCHECK(widget_);
+void ClientControlledShellSurface::UpdateBackdrop() {
+  aura::Window* window = widget_->GetNativeWindow();
+  bool enable_backdrop = widget_->IsFullscreen() || widget_->IsMaximized();
+  if (window->GetProperty(aura::client::kHasBackdrop) != enable_backdrop)
+    window->SetProperty(aura::client::kHasBackdrop, enable_backdrop);
+}
 
-  // Cannot start another drag if one is already taking place.
-  if (resizer_)
-    return;
+float ClientControlledShellSurface::GetScale() const {
+  return scale_;
+}
 
-  aura::Window* window = GetDragWindow();
-  if (!window || window->HasCapture())
-    return;
+bool ClientControlledShellSurface::CanAnimateWindowStateTransitions() const {
+  // TODO(domlaskowski): The configure callback does not yet support window
+  // state changes. See crbug.com/699746.
+  return false;
+}
 
+aura::Window* ClientControlledShellSurface::GetDragWindow() {
+  return root_surface() ? root_surface()->window() : nullptr;
+}
+
+std::unique_ptr<ash::WindowResizer>
+ClientControlledShellSurface::CreateWindowResizer(aura::Window* window,
+                                                  int component) {
   ash::wm::WindowState* window_state =
       ash::wm::GetWindowState(widget_->GetNativeWindow());
   DCHECK(!window_state->drag_details());
@@ -327,30 +345,30 @@
   // Chained with a CustomWindowResizer, DragWindowResizer does not handle
   // dragging. It only renders phantom windows and moves the window to the
   // target root window when dragging ends.
-  resizer_.reset(ash::DragWindowResizer::Create(
+  return std::unique_ptr<ash::WindowResizer>(ash::DragWindowResizer::Create(
       new CustomWindowResizer(window_state), window_state));
-
-  WMHelper::GetInstance()->AddPreTargetHandler(this);
-  window->SetCapture();
-
-  // Notify client that resizing state has changed.
-  if (IsResizing())
-    Configure();
 }
 
-void ClientControlledShellSurface::UpdateBackdrop() {
-  aura::Window* window = widget_->GetNativeWindow();
-  // Enable the black backdrop layer behind the window if the window
-  // is in immersive fullscreen, maximized, yet the window can control
-  // the bounds of the window in fullscreen/tablet mode (thus the
-  // background can be visible).
-  bool enable_backdrop =
-      (widget_->IsFullscreen() || widget_->IsMaximized()) &&
-      ash::wm::GetWindowState(window)->allow_set_bounds_direct();
-  if (window->GetProperty(aura::client::kHasBackdrop) != enable_backdrop)
-    window->SetProperty(aura::client::kHasBackdrop, enable_backdrop);
+bool ClientControlledShellSurface::OnMouseDragged(const ui::MouseEvent&) {
+  // TODO(domlaskowski): When VKEY_ESCAPE is pressed during dragging, the client
+  // destroys the window, but should instead revert the drag to be consistent
+  // with ShellSurface::OnKeyEvent. See crbug.com/699746.
+  return false;
 }
 
+gfx::Point ClientControlledShellSurface::GetWidgetOrigin() const {
+  return origin_ - GetSurfaceOrigin().OffsetFromOrigin();
+}
+
+gfx::Point ClientControlledShellSurface::GetSurfaceOrigin() const {
+  DCHECK(resize_component_ == HTCAPTION);
+  gfx::Rect visible_bounds = GetVisibleBounds();
+  return origin_ + origin_offset_ - visible_bounds.OffsetFromOrigin();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ClientControlledShellSurface, private:
+
 void ClientControlledShellSurface::
     EnsureCompositorIsLockedForOrientationChange() {
   if (!orientation_compositor_lock_) {
diff --git a/components/exo/client_controlled_shell_surface.h b/components/exo/client_controlled_shell_surface.h
index 5636ce8..2ea7dda 100644
--- a/components/exo/client_controlled_shell_surface.h
+++ b/components/exo/client_controlled_shell_surface.h
@@ -26,9 +26,10 @@
 
 enum class Orientation { PORTRAIT, LANDSCAPE };
 
-// This class implements shell surface for remote shell protocol. It's
-// window state, bounds are controlled by the client rather than window
-// manager.
+// This class implements a ShellSurface whose window state and bounds are
+// controlled by a remote shell client rather than the window manager. The
+// position specified as part of the geometry is relative to the origin of
+// the screen coordinate system.
 class ClientControlledShellSurface
     : public ShellSurface,
       public display::DisplayObserver,
@@ -40,11 +41,6 @@
                                int container);
   ~ClientControlledShellSurface() override;
 
-  // Overridden from ShellSurface:
-  void InitializeWindowState(ash::wm::WindowState* window_state) override;
-  void AttemptToStartDrag(int component) override;
-  void UpdateBackdrop() override;
-
   // Pin/unpin the surface. Pinned surface cannot be switched to
   // other windows unless its explicitly unpinned.
   void SetPinned(ash::mojom::WindowPinType type);
@@ -66,15 +62,11 @@
   // Set top inset for surface.
   void SetTopInset(int height);
 
-  // Overridden from ShellSurface:
-  void Move() override;
-  void Resize(int component) override;
-  float GetScale() const override;
-
   // Overridden from SurfaceDelegate:
   void OnSurfaceCommit() override;
 
   // Overridden from views::WidgetDelegate:
+  bool CanResize() const override;
   void SaveWindowPlacement(const gfx::Rect& bounds,
                            ui::WindowShowState show_state) override;
   bool GetSavedWindowPlacement(const views::Widget* widget,
@@ -98,6 +90,20 @@
   void CompositorLockTimedOut() override;
 
  private:
+  // Overridden from ShellSurface:
+  void SetWidgetBounds(const gfx::Rect& bounds) override;
+  void InitializeWindowState(ash::wm::WindowState* window_state) override;
+  void UpdateBackdrop() override;
+  float GetScale() const override;
+  bool CanAnimateWindowStateTransitions() const override;
+  aura::Window* GetDragWindow() override;
+  std::unique_ptr<ash::WindowResizer> CreateWindowResizer(
+      aura::Window* window,
+      int component) override;
+  bool OnMouseDragged(const ui::MouseEvent& event) override;
+  gfx::Point GetWidgetOrigin() const override;
+  gfx::Point GetSurfaceOrigin() const override;
+
   // Lock the compositor if it's not already locked, or extends the
   // lock timeout if it's already locked.
   // TODO(reveman): Remove this when using configure callbacks for orientation.
diff --git a/components/exo/display.cc b/components/exo/display.cc
index 074c46a..abb41bd 100644
--- a/components/exo/display.cc
+++ b/components/exo/display.cc
@@ -146,8 +146,7 @@
   }
 
   return std::make_unique<ShellSurface>(
-      surface, ShellSurface::BoundsMode::SHELL, gfx::Point(),
-      true /* activatable */, false /* can_minimize */,
+      surface, gfx::Point(), true /* activatable */, false /* can_minimize */,
       ash::kShellWindowId_DefaultContainer);
 }
 
@@ -161,8 +160,7 @@
   }
 
   return std::make_unique<XdgShellSurface>(
-      surface, ShellSurface::BoundsMode::SHELL, gfx::Point(),
-      true /* activatable */, false /* can_minimize */,
+      surface, gfx::Point(), true /* activatable */, false /* can_minimize */,
       ash::kShellWindowId_DefaultContainer);
 }
 
diff --git a/components/exo/pointer_unittest.cc b/components/exo/pointer_unittest.cc
index 89e7c830..67a896f 100644
--- a/components/exo/pointer_unittest.cc
+++ b/components/exo/pointer_unittest.cc
@@ -200,9 +200,10 @@
                         gfx::Vector2d(1, 1));
 
   std::unique_ptr<Surface> child_surface(new Surface);
-  std::unique_ptr<ShellSurface> child_shell_surface(new ShellSurface(
-      child_surface.get(), ShellSurface::BoundsMode::FIXED, gfx::Point(9, 9),
-      true, false, ash::kShellWindowId_DefaultContainer));
+  std::unique_ptr<ShellSurface> child_shell_surface(
+      new ShellSurface(child_surface.get(), gfx::Point(9, 9), true, false,
+                       ash::kShellWindowId_DefaultContainer));
+  child_shell_surface->DisableMovement();
   child_shell_surface->SetParent(shell_surface.get());
   gfx::Size child_buffer_size(15, 15);
   std::unique_ptr<Buffer> child_buffer(
@@ -333,9 +334,10 @@
 
   // Create surface for modal window.
   std::unique_ptr<Surface> surface2(new Surface);
-  std::unique_ptr<ShellSurface> shell_surface2(new ShellSurface(
-      surface2.get(), ShellSurface::BoundsMode::FIXED, gfx::Point(), true,
-      false, ash::kShellWindowId_SystemModalContainer));
+  std::unique_ptr<ShellSurface> shell_surface2(
+      new ShellSurface(surface2.get(), gfx::Point(), true, false,
+                       ash::kShellWindowId_SystemModalContainer));
+  shell_surface2->DisableMovement();
   std::unique_ptr<Buffer> buffer2(
       new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5))));
   surface2->Attach(buffer2.get());
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index d22728a..52e09a7f 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -321,13 +321,11 @@
 // ShellSurface, public:
 
 ShellSurface::ShellSurface(Surface* surface,
-                           BoundsMode bounds_mode,
                            const gfx::Point& origin,
                            bool activatable,
                            bool can_minimize,
                            int container)
     : SurfaceTreeHost("ExoShellSurfaceHost"),
-      bounds_mode_(bounds_mode),
       origin_(origin),
       container_(container),
       activatable_(activatable),
@@ -341,7 +339,6 @@
 
 ShellSurface::ShellSurface(Surface* surface)
     : ShellSurface(surface,
-                   BoundsMode::SHELL,
                    gfx::Point(),
                    true,
                    true,
@@ -511,6 +508,13 @@
   non_system_modal_window_was_active_ = non_system_modal_window_was_active;
 }
 
+void ShellSurface::DisableMovement() {
+  movement_disabled_ = true;
+
+  if (widget_)
+    widget_->set_movement_disabled(true);
+}
+
 void ShellSurface::UpdateSystemModal() {
   DCHECK(widget_);
   DCHECK_EQ(container_, ash::kShellWindowId_SystemModalContainer);
@@ -519,10 +523,6 @@
       system_modal_ ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_NONE);
 }
 
-float ShellSurface::GetScale() const {
-  return 1.f;
-}
-
 // static
 void ShellSurface::SetApplicationId(aura::Window* window,
                                     const std::string& id) {
@@ -548,17 +548,7 @@
   if (!widget_)
     return;
 
-  switch (bounds_mode_) {
-    case BoundsMode::SHELL:
-      AttemptToStartDrag(HTCAPTION);
-      return;
-    case BoundsMode::FIXED:
-      return;
-    case BoundsMode::CLIENT:
-      break;
-  }
-
-  NOTREACHED();
+  AttemptToStartDrag(HTCAPTION);
 }
 
 void ShellSurface::Resize(int component) {
@@ -567,16 +557,7 @@
   if (!widget_)
     return;
 
-  switch (bounds_mode_) {
-    case BoundsMode::SHELL:
-      AttemptToStartDrag(component);
-      return;
-    case BoundsMode::CLIENT:
-    case BoundsMode::FIXED:
-      return;
-  }
-
-  NOTREACHED();
+  AttemptToStartDrag(component);
 }
 
 void ShellSurface::Close() {
@@ -824,7 +805,7 @@
 // views::WidgetDelegate overrides:
 
 bool ShellSurface::CanResize() const {
-  return bounds_mode_ == BoundsMode::SHELL;
+  return !movement_disabled_;
 }
 
 bool ShellSurface::CanMaximize() const {
@@ -927,16 +908,9 @@
 
   if (ash::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
       ash::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
-    // When transitioning in/out of maximized or fullscreen mode we need to
-    // make sure we have a configure callback before we allow the default
-    // cross-fade animations. The configure callback provides a mechanism for
-    // the client to inform us that a frame has taken the state change into
-    // account and without this cross-fade animations are unreliable.
-    // TODO(domlaskowski): For BoundsMode::CLIENT, the configure callback does
-    // not yet support window state changes. See crbug.com/699746.
-    if (configure_callback_.is_null() || bounds_mode_ == BoundsMode::CLIENT) {
-      scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this));
-    } else if (widget_) {
+    if (CanAnimateWindowStateTransitions()) {
+      if (!widget_)
+        return;
       // Give client a chance to produce a frame that takes state change into
       // account by acquiring a compositor lock.
       ui::Compositor* compositor =
@@ -944,6 +918,8 @@
       configure_compositor_lock_ = compositor->GetCompositorLock(
           nullptr, base::TimeDelta::FromMilliseconds(
                        kMaximizedOrFullscreenOrPinnedLockTimeoutMs));
+    } else {
+      scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this));
     }
   }
 }
@@ -976,7 +952,6 @@
                                          const gfx::Rect& old_bounds,
                                          const gfx::Rect& new_bounds,
                                          ui::PropertyChangeReason reason) {
-  DCHECK_NE(bounds_mode_, BoundsMode::CLIENT);
   if (!widget_ || !root_surface() || ignore_window_bounds_changes_)
     return;
 
@@ -1037,9 +1012,6 @@
     return;
   }
 
-  // TODO(domlaskowski): For BoundsMode::CLIENT, synchronize the revert with the
-  // client, instead of having the client destroy the window on VKEY_ESCAPE. See
-  // crbug.com/699746.
   if (event->type() == ui::ET_KEY_PRESSED &&
       event->key_code() == ui::VKEY_ESCAPE) {
     EndDrag(true /* revert */);
@@ -1072,16 +1044,8 @@
 
   switch (event->type()) {
     case ui::ET_MOUSE_DRAGGED: {
-      if (bounds_mode_ == BoundsMode::CLIENT)
-        break;
-
-      gfx::Point location(event->location());
-      aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(),
-                                         widget_->GetNativeWindow()->parent(),
-                                         &location);
-      ScopedConfigure scoped_configure(this, false);
-      resizer_->Drag(location, event->flags());
-      event->StopPropagation();
+      if (OnMouseDragged(*event))
+        event->StopPropagation();
       break;
     }
     case ui::ET_MOUSE_RELEASED: {
@@ -1111,8 +1075,7 @@
   if (event->handled())
     return;
 
-  // TODO(domlaskowski): Handle touch dragging/resizing for BoundsMode::SHELL.
-  // See crbug.com/738606.
+  // TODO(domlaskowski): Handle touch dragging/resizing. See crbug.com/738606.
   switch (event->type()) {
     case ui::ET_GESTURE_END: {
       ScopedConfigure scoped_configure(this, false);
@@ -1289,121 +1252,6 @@
       << pending_configs_.size();
 }
 
-aura::Window* ShellSurface::GetDragWindow() {
-  switch (bounds_mode_) {
-    case BoundsMode::SHELL:
-      return widget_->GetNativeWindow();
-
-    case BoundsMode::CLIENT:
-      return root_surface() ? root_surface()->window() : nullptr;
-
-    case BoundsMode::FIXED:
-      return nullptr;
-  }
-
-  NOTREACHED();
-  return nullptr;
-}
-
-void ShellSurface::AttemptToStartDrag(int component) {
-  DCHECK(widget_);
-
-  // Cannot start another drag if one is already taking place.
-  if (resizer_)
-    return;
-
-  aura::Window* window = GetDragWindow();
-  if (!window || window->HasCapture())
-    return;
-
-  DCHECK_EQ(bounds_mode_, BoundsMode::SHELL);
-
-  // Set the cursor before calling CreateWindowResizer(), as that will
-  // eventually call LockCursor() and prevent the cursor from changing.
-  aura::client::CursorClient* cursor_client =
-      aura::client::GetCursorClient(window->GetRootWindow());
-  if (!cursor_client)
-    return;
-
-  switch (component) {
-    case HTCAPTION:
-      cursor_client->SetCursor(ui::CursorType::kPointer);
-      break;
-    case HTTOP:
-      cursor_client->SetCursor(ui::CursorType::kNorthResize);
-      break;
-    case HTTOPRIGHT:
-      cursor_client->SetCursor(ui::CursorType::kNorthEastResize);
-      break;
-    case HTRIGHT:
-      cursor_client->SetCursor(ui::CursorType::kEastResize);
-      break;
-    case HTBOTTOMRIGHT:
-      cursor_client->SetCursor(ui::CursorType::kSouthEastResize);
-      break;
-    case HTBOTTOM:
-      cursor_client->SetCursor(ui::CursorType::kSouthResize);
-      break;
-    case HTBOTTOMLEFT:
-      cursor_client->SetCursor(ui::CursorType::kSouthWestResize);
-      break;
-    case HTLEFT:
-      cursor_client->SetCursor(ui::CursorType::kWestResize);
-      break;
-    case HTTOPLEFT:
-      cursor_client->SetCursor(ui::CursorType::kNorthWestResize);
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  resizer_ = ash::CreateWindowResizer(window, GetMouseLocation(), component,
-                                      wm::WINDOW_MOVE_SOURCE_MOUSE);
-  if (!resizer_)
-    return;
-
-  // Apply pending origin offsets and resize direction before starting a
-  // new resize operation. These can still be pending if the client has
-  // acknowledged the configure request but not yet called Commit().
-  origin_offset_ += pending_origin_offset_;
-  pending_origin_offset_ = gfx::Vector2d();
-  resize_component_ = pending_resize_component_;
-
-  WMHelper::GetInstance()->AddPreTargetHandler(this);
-  window->SetCapture();
-
-  // Notify client that resizing state has changed.
-  if (IsResizing())
-    Configure();
-}
-
-void ShellSurface::EndDrag(bool revert) {
-  DCHECK(widget_);
-  DCHECK(resizer_);
-
-  aura::Window* window = GetDragWindow();
-  DCHECK(window);
-  DCHECK(window->HasCapture());
-
-  bool was_resizing = IsResizing();
-
-  if (revert)
-    resizer_->RevertDrag();
-  else
-    resizer_->CompleteDrag();
-
-  WMHelper::GetInstance()->RemovePreTargetHandler(this);
-  window->ReleaseCapture();
-  resizer_.reset();
-
-  // Notify client that resizing state has changed.
-  if (was_resizing)
-    Configure();
-
-  UpdateWidgetBounds();
-}
-
 bool ShellSurface::IsResizing() const {
   ash::wm::WindowState* window_state =
       ash::wm::GetWindowState(widget_->GetNativeWindow());
@@ -1439,65 +1287,22 @@
   gfx::Rect new_widget_bounds =
       widget_->non_client_view()->GetWindowBoundsForClientBounds(
           visible_bounds);
-
-  switch (bounds_mode_) {
-    case BoundsMode::FIXED:
-      new_widget_bounds.set_origin(origin_);
-      break;
-    case BoundsMode::CLIENT:
-      new_widget_bounds.set_origin(origin_ -
-                                   GetSurfaceOrigin().OffsetFromOrigin());
-      break;
-    case BoundsMode::SHELL:
-      // Update widget origin using the surface origin if the current location
-      // of surface is being anchored to one side of the widget as a result of a
-      // resize operation.
-      if (resize_component_ != HTCAPTION) {
-        gfx::Point widget_origin =
-            GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
-        wm::ConvertPointToScreen(widget_->GetNativeWindow(), &widget_origin);
-        new_widget_bounds.set_origin(widget_origin);
-      } else {
-        // Preserve widget position.
-        new_widget_bounds.set_origin(
-            widget_->GetWindowBoundsInScreen().origin());
-      }
-      break;
-  }
+  new_widget_bounds.set_origin(GetWidgetOrigin());
 
   // Set |ignore_window_bounds_changes_| as this change to window bounds
   // should not result in a configure request.
   DCHECK(!ignore_window_bounds_changes_);
   ignore_window_bounds_changes_ = true;
-  const gfx::Rect widget_bounds = widget_->GetWindowBoundsInScreen();
-  if (widget_bounds != new_widget_bounds) {
-    if (bounds_mode_ != BoundsMode::CLIENT || !resizer_) {
-      widget_->SetBounds(new_widget_bounds);
-      UpdateSurfaceBounds();
-    } else {
-      // TODO(domlaskowski): Synchronize window state transitions with the
-      // client, and abort client-side dragging on transition to fullscreen. See
-      // crbug.com/699746.
-      DLOG_IF(ERROR, widget_bounds.size() != new_widget_bounds.size())
-          << "Window size changed during client-driven drag";
-
-      // Convert from screen to display coordinates.
-      gfx::Point origin = new_widget_bounds.origin();
-      wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin);
-      new_widget_bounds.set_origin(origin);
-
-      // Move the window relative to the current display.
-      widget_->GetNativeWindow()->SetBounds(new_widget_bounds);
-      UpdateSurfaceBounds();
-
-      // Render phantom windows when beyond the current display.
-      resizer_->Drag(GetMouseLocation(), 0);
-    }
-  }
-
+  if (new_widget_bounds != widget_->GetWindowBoundsInScreen())
+    SetWidgetBounds(new_widget_bounds);
   ignore_window_bounds_changes_ = false;
 }
 
+void ShellSurface::SetWidgetBounds(const gfx::Rect& bounds) {
+  widget_->SetBounds(bounds);
+  UpdateSurfaceBounds();
+}
+
 void ShellSurface::UpdateSurfaceBounds() {
   gfx::Rect client_view_bounds =
       widget_->non_client_view()->frame_view()->GetBoundsForClientView();
@@ -1553,7 +1358,14 @@
   }
 }
 
-void ShellSurface::UpdateBackdrop() {}
+gfx::Rect ShellSurface::GetVisibleBounds() const {
+  // Use |geometry_| if set, otherwise use the visual bounds of the surface.
+  if (!geometry_.IsEmpty())
+    return geometry_;
+
+  return root_surface() ? gfx::Rect(root_surface()->content_size())
+                        : gfx::Rect();
+}
 
 gfx::Point ShellSurface::GetMouseLocation() const {
   aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow();
@@ -1564,39 +1376,177 @@
   return location;
 }
 
-void ShellSurface::InitializeWindowState(ash::wm::WindowState* window_state) {
-  // Allow the client to request bounds that do not fill the entire work area
-  // when maximized, or the entire display when fullscreen.
-  window_state->set_allow_set_bounds_direct(false);
-  // Disable movement if bounds are controlled by the client or fixed.
-  bool movement_disabled = bounds_mode_ != BoundsMode::SHELL;
-  widget_->set_movement_disabled(movement_disabled);
-  window_state->set_ignore_keyboard_bounds_change(movement_disabled);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // ShellSurface, private:
 
-gfx::Rect ShellSurface::GetVisibleBounds() const {
-  // Use |geometry_| if set, otherwise use the visual bounds of the surface.
-  if (!geometry_.IsEmpty())
-    return geometry_;
+void ShellSurface::InitializeWindowState(ash::wm::WindowState* window_state) {
+  window_state->set_allow_set_bounds_direct(false);
+  widget_->set_movement_disabled(movement_disabled_);
+  window_state->set_ignore_keyboard_bounds_change(movement_disabled_);
+}
 
-  return root_surface() ? gfx::Rect(root_surface()->content_size())
-                        : gfx::Rect();
+void ShellSurface::UpdateBackdrop() {}
+
+float ShellSurface::GetScale() const {
+  return 1.f;
+}
+
+bool ShellSurface::CanAnimateWindowStateTransitions() const {
+  // When transitioning in/out of maximized or fullscreen mode, we need to
+  // make sure we have a configure callback before we allow the default
+  // cross-fade animations. The configure callback provides a mechanism for
+  // the client to inform us that a frame has taken the state change into
+  // account, and without this cross-fade animations are unreliable.
+  return !configure_callback_.is_null();
+}
+
+aura::Window* ShellSurface::GetDragWindow() {
+  return movement_disabled_ ? nullptr : widget_->GetNativeWindow();
+}
+
+std::unique_ptr<ash::WindowResizer> ShellSurface::CreateWindowResizer(
+    aura::Window* window,
+    int component) {
+  // Set the cursor before calling CreateWindowResizer, as that will
+  // eventually call LockCursor and prevent the cursor from changing.
+  aura::client::CursorClient* cursor_client =
+      aura::client::GetCursorClient(window->GetRootWindow());
+  if (!cursor_client)
+    return nullptr;
+
+  switch (component) {
+    case HTCAPTION:
+      cursor_client->SetCursor(ui::CursorType::kPointer);
+      break;
+    case HTTOP:
+      cursor_client->SetCursor(ui::CursorType::kNorthResize);
+      break;
+    case HTTOPRIGHT:
+      cursor_client->SetCursor(ui::CursorType::kNorthEastResize);
+      break;
+    case HTRIGHT:
+      cursor_client->SetCursor(ui::CursorType::kEastResize);
+      break;
+    case HTBOTTOMRIGHT:
+      cursor_client->SetCursor(ui::CursorType::kSouthEastResize);
+      break;
+    case HTBOTTOM:
+      cursor_client->SetCursor(ui::CursorType::kSouthResize);
+      break;
+    case HTBOTTOMLEFT:
+      cursor_client->SetCursor(ui::CursorType::kSouthWestResize);
+      break;
+    case HTLEFT:
+      cursor_client->SetCursor(ui::CursorType::kWestResize);
+      break;
+    case HTTOPLEFT:
+      cursor_client->SetCursor(ui::CursorType::kNorthWestResize);
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+
+  std::unique_ptr<ash::WindowResizer> resizer = ash::CreateWindowResizer(
+      window, GetMouseLocation(), component, wm::WINDOW_MOVE_SOURCE_MOUSE);
+
+  if (!resizer)
+    return nullptr;
+
+  // Apply pending origin offsets and resize direction before starting a
+  // new resize operation. These can still be pending if the client has
+  // acknowledged the configure request but has not yet committed.
+  origin_offset_ += pending_origin_offset_;
+  pending_origin_offset_ = gfx::Vector2d();
+  resize_component_ = pending_resize_component_;
+
+  return resizer;
+}
+
+bool ShellSurface::OnMouseDragged(const ui::MouseEvent& event) {
+  gfx::Point location(event.location());
+  aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(),
+                                     widget_->GetNativeWindow()->parent(),
+                                     &location);
+  ScopedConfigure scoped_configure(this, false);
+  resizer_->Drag(location, event.flags());
+  return true;
+}
+
+void ShellSurface::AttemptToStartDrag(int component) {
+  DCHECK(widget_);
+
+  // Cannot start another drag if one is already taking place.
+  if (resizer_)
+    return;
+
+  aura::Window* window = GetDragWindow();
+  if (!window || window->HasCapture())
+    return;
+
+  resizer_ = CreateWindowResizer(window, component);
+  if (!resizer_)
+    return;
+
+  WMHelper::GetInstance()->AddPreTargetHandler(this);
+  window->SetCapture();
+
+  // Notify client that resizing state has changed.
+  if (IsResizing())
+    Configure();
+}
+
+void ShellSurface::EndDrag(bool revert) {
+  DCHECK(widget_);
+  DCHECK(resizer_);
+
+  aura::Window* window = GetDragWindow();
+  DCHECK(window);
+  DCHECK(window->HasCapture());
+
+  bool was_resizing = IsResizing();
+
+  if (revert)
+    resizer_->RevertDrag();
+  else
+    resizer_->CompleteDrag();
+
+  WMHelper::GetInstance()->RemovePreTargetHandler(this);
+  window->ReleaseCapture();
+  resizer_.reset();
+
+  // Notify client that resizing state has changed.
+  if (was_resizing)
+    Configure();
+
+  UpdateWidgetBounds();
+}
+
+gfx::Point ShellSurface::GetWidgetOrigin() const {
+  if (movement_disabled_)
+    return origin_;
+
+  // Preserve widget position.
+  if (resize_component_ == HTCAPTION)
+    return widget_->GetWindowBoundsInScreen().origin();
+
+  // Compute widget origin using surface origin if the current location of
+  // surface is being anchored to one side of the widget as a result of a
+  // resize operation.
+  gfx::Rect visible_bounds = GetVisibleBounds();
+  gfx::Point origin = GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
+  wm::ConvertPointToScreen(widget_->GetNativeWindow(), &origin);
+  return origin;
 }
 
 gfx::Point ShellSurface::GetSurfaceOrigin() const {
-  DCHECK(bounds_mode_ == BoundsMode::SHELL || resize_component_ == HTCAPTION);
+  DCHECK(!movement_disabled_ || resize_component_ == HTCAPTION);
 
   gfx::Rect visible_bounds = GetVisibleBounds();
   gfx::Rect client_bounds =
       widget_->non_client_view()->frame_view()->GetBoundsForClientView();
   switch (resize_component_) {
     case HTCAPTION:
-      if (bounds_mode_ == BoundsMode::CLIENT)
-        return origin_ + origin_offset_ - visible_bounds.OffsetFromOrigin();
-
       return gfx::Point() + origin_offset_ - visible_bounds.OffsetFromOrigin();
     case HTBOTTOM:
     case HTRIGHT:
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h
index 613b747..dc89f8933 100644
--- a/components/exo/shell_surface.h
+++ b/components/exo/shell_surface.h
@@ -56,20 +56,14 @@
                      public ash::wm::WindowStateObserver,
                      public wm::ActivationChangeObserver {
  public:
-  enum class BoundsMode { SHELL, CLIENT, FIXED };
-
-  // The |origin| is in screen coordinates. When bounds are controlled by the
-  // shell or fixed, it determines the initial position of the shell surface.
-  // In that case, the position specified as part of the geometry is relative
-  // to the shell surface.
-  // TODO(reveman|oshima): Remove bounds_mode.
+  // The |origin| is the initial position in screen coordinates. The position
+  // specified as part of the geometry is relative to the shell surface.
   ShellSurface(Surface* surface,
-               BoundsMode bounds_mode,
                const gfx::Point& origin,
                bool activatable,
                bool can_minimize,
                int container);
-  ShellSurface(Surface* surface);
+  explicit ShellSurface(Surface* surface);
   ~ShellSurface() override;
 
   // Set the callback to run when the user wants the shell surface to be closed.
@@ -132,12 +126,12 @@
   void SetFullscreen(bool fullscreen);
 
   // Start an interactive move of surface.
-  virtual void Move();
+  void Move();
 
   // Start an interactive resize of surface. |component| is one of the windows
   // HT constants (see ui/base/hit_test.h) and describes in what direction the
   // surface should be resized.
-  virtual void Resize(int component);
+  void Resize(int component);
 
   // Set title for the surface.
   void SetTitle(const base::string16& title);
@@ -148,6 +142,9 @@
   // Sets the system modality.
   void SetSystemModal(bool system_modal);
 
+  // Prevents shell surface from being moved.
+  void DisableMovement();
+
   // Sets the application ID for the window. The application ID identifies the
   // general class of applications to which the window belongs.
   static void SetApplicationId(aura::Window* window, const std::string& id);
@@ -278,18 +275,15 @@
   // Asks the client to configure its surface.
   void Configure();
 
-  // Returns the window that has capture during dragging.
-  aura::Window* GetDragWindow();
-
-  // End current drag operation.
-  void EndDrag(bool revert);
-
   // Returns true if surface is currently being resized.
   bool IsResizing() const;
 
   // Updates the bounds of widget to match the current surface bounds.
   void UpdateWidgetBounds();
 
+  // Called by UpdateWidgetBounds to set widget bounds.
+  virtual void SetWidgetBounds(const gfx::Rect& bounds);
+
   // Updates the bounds of surface to match the current widget bounds.
   void UpdateSurfaceBounds();
 
@@ -300,25 +294,15 @@
   // Applies |system_modal_| to |widget_|.
   void UpdateSystemModal();
 
+  // Returns the "visible bounds" for the surface from the user's perspective.
+  gfx::Rect GetVisibleBounds() const;
+
   // In the coordinate system of the parent root window.
   gfx::Point GetMouseLocation() const;
 
-  virtual void InitializeWindowState(ash::wm::WindowState* window_state);
-
-  // Attempt to start a drag operation. The type of drag operation to start is
-  // determined by |component|.
-  virtual void AttemptToStartDrag(int component);
-
-  virtual float GetScale() const;
-
-  // Updates the backdrop state of the shell surface based on the
-  // bounds mode and window state.
-  virtual void UpdateBackdrop();
-
   views::Widget* widget_ = nullptr;
   aura::Window* parent_ = nullptr;
-  // TODO(oshima): Move to xdg private or internal.
-  BoundsMode bounds_mode_ = BoundsMode::SHELL;
+  bool movement_disabled_ = false;
   gfx::Point origin_;
 
   // Container Window Id (see ash/public/cpp/shell_window_ids.h)
@@ -338,12 +322,40 @@
 
   class ScopedAnimationsDisabled;
 
-  // Returns the "visible bounds" for the surface from the user's perspective.
-  gfx::Rect GetVisibleBounds() const;
+  // Called on widget creation to initialize its window state.
+  virtual void InitializeWindowState(ash::wm::WindowState* window_state);
 
-  // Returns the origin for the surface taking visible bounds and current
+  // Updates the backdrop of the shell surface based on the window state.
+  virtual void UpdateBackdrop();
+
+  // Returns the scale of the surface tree relative to the shell surface.
+  virtual float GetScale() const;
+
+  // Returns whether window state transitions should be animated.
+  virtual bool CanAnimateWindowStateTransitions() const;
+
+  // Returns the window that has capture during dragging.
+  virtual aura::Window* GetDragWindow();
+
+  // Creates the resizer for a dragging/resizing operation.
+  virtual std::unique_ptr<ash::WindowResizer> CreateWindowResizer(
+      aura::Window* window,
+      int component);
+
+  // Called on mouse motion during a drag operation.
+  bool OnMouseDragged(const ui::MouseEvent& event) override;
+
+  // Attempt to start a drag operation. The type of drag operation to start is
+  // determined by |component|.
+  void AttemptToStartDrag(int component);
+
+  // End current drag operation.
+  void EndDrag(bool revert);
+
+  // Return the origin of the widget/surface taking visible bounds and current
   // resize direction into account.
-  gfx::Point GetSurfaceOrigin() const;
+  virtual gfx::Point GetWidgetOrigin() const;
+  virtual gfx::Point GetSurfaceOrigin() const;
 
   // Set the parent window of this surface.
   void SetParentWindow(aura::Window* parent);
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc
index 0c2ea6b..0b99b38 100644
--- a/components/exo/shell_surface_unittest.cc
+++ b/components/exo/shell_surface_unittest.cc
@@ -53,16 +53,13 @@
   return serial;
 }
 
-class ShellSurfaceBoundsModeTest
+class ShellSurfaceTestWithClientControlledParam
     : public ShellSurfaceTest,
-      public testing::WithParamInterface<ShellSurface::BoundsMode> {
+      public testing::WithParamInterface<bool> {
  public:
-  ShellSurfaceBoundsModeTest() {}
-  ~ShellSurfaceBoundsModeTest() override {}
+  ShellSurfaceTestWithClientControlledParam() = default;
 
-  bool IsClientBoundsMode() const {
-    return GetParam() == ShellSurface::BoundsMode::CLIENT;
-  }
+  bool IsClientControlled() const { return GetParam(); }
 
   bool HasBackdrop() {
     ash::WorkspaceController* wc =
@@ -71,20 +68,18 @@
   }
 
   std::unique_ptr<ShellSurface> CreateDefaultShellSurface(Surface* surface) {
-    if (IsClientBoundsMode())
-      return exo_test_helper()->CreateClientControlledShellSurface(surface);
-    else
-      return Display().CreateShellSurface(surface);
+    return IsClientControlled()
+               ? exo_test_helper()->CreateClientControlledShellSurface(surface)
+               : Display().CreateShellSurface(surface);
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(ShellSurfaceBoundsModeTest);
+  DISALLOW_COPY_AND_ASSIGN(ShellSurfaceTestWithClientControlledParam);
 };
 
 INSTANTIATE_TEST_CASE_P(,
-                        ShellSurfaceBoundsModeTest,
-                        testing::Values(ShellSurface::BoundsMode::CLIENT,
-                                        ShellSurface::BoundsMode::SHELL));
+                        ShellSurfaceTestWithClientControlledParam,
+                        testing::Values(true, false));
 
 TEST_F(ShellSurfaceTest, AcknowledgeConfigure) {
   gfx::Size buffer_size(32, 32);
@@ -160,7 +155,7 @@
             shell_surface->GetWidget()->GetWindowBoundsInScreen());
 }
 
-TEST_P(ShellSurfaceBoundsModeTest, Maximize) {
+TEST_P(ShellSurfaceTestWithClientControlledParam, Maximize) {
   gfx::Size buffer_size(256, 256);
   std::unique_ptr<Buffer> buffer(
       new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
@@ -172,10 +167,10 @@
   surface->Commit();
   EXPECT_FALSE(HasBackdrop());
   shell_surface->Maximize();
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
   surface->Commit();
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
-  if (!IsClientBoundsMode()) {
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
+  if (!IsClientControlled()) {
     EXPECT_EQ(CurrentContext()->bounds().width(),
               shell_surface->GetWidget()->GetWindowBoundsInScreen().width());
   }
@@ -191,7 +186,7 @@
 
   ash::wm::GetWindowState(window)->OnWMEvent(&maximize_event);
   EXPECT_TRUE(shell_surface->GetWidget()->IsMaximized());
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
 }
 
 TEST_F(ShellSurfaceTest, Minimize) {
@@ -217,7 +212,7 @@
   EXPECT_TRUE(shell_surface->GetWidget()->IsMinimized());
 }
 
-TEST_P(ShellSurfaceBoundsModeTest, Restore) {
+TEST_P(ShellSurfaceTestWithClientControlledParam, Restore) {
   gfx::Size buffer_size(256, 256);
   std::unique_ptr<Buffer> buffer(
       new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
@@ -230,10 +225,10 @@
   EXPECT_FALSE(HasBackdrop());
   // Note: Remove contents to avoid issues with maximize animations in tests.
   shell_surface->Maximize();
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
   shell_surface->Restore();
   EXPECT_FALSE(HasBackdrop());
-  if (!IsClientBoundsMode()) {
+  if (!IsClientControlled()) {
     EXPECT_EQ(buffer_size.ToString(), shell_surface->GetWidget()
                                           ->GetWindowBoundsInScreen()
                                           .size()
@@ -241,7 +236,7 @@
   }
 }
 
-TEST_P(ShellSurfaceBoundsModeTest, SetFullscreen) {
+TEST_P(ShellSurfaceTestWithClientControlledParam, SetFullscreen) {
   gfx::Size buffer_size(256, 256);
   std::unique_ptr<Buffer> buffer(
       new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
@@ -252,8 +247,8 @@
   shell_surface->SetFullscreen(true);
   surface->Attach(buffer.get());
   surface->Commit();
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
-  if (!IsClientBoundsMode()) {
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
+  if (!IsClientControlled()) {
     EXPECT_EQ(CurrentContext()->bounds().ToString(),
               shell_surface->GetWidget()->GetWindowBoundsInScreen().ToString());
   }
@@ -366,7 +361,8 @@
   EXPECT_EQ(size, shell_surface->GetMaximumSize());
 }
 
-TEST_P(ShellSurfaceBoundsModeTest, DefaultDeviceScaleFactorForcedScaleFactor) {
+TEST_P(ShellSurfaceTestWithClientControlledParam,
+       DefaultDeviceScaleFactorForcedScaleFactor) {
   double scale = 1.5;
   display::Display::SetForceDeviceScaleFactor(scale);
 
@@ -382,7 +378,7 @@
   surface->Attach(buffer.get());
   surface->Commit();
   gfx::Transform transform;
-  if (IsClientBoundsMode())
+  if (IsClientControlled())
     transform.Scale(1.0 / scale, 1.0 / scale);
 
   EXPECT_EQ(
@@ -390,7 +386,8 @@
       shell_surface->host_window()->layer()->GetTargetTransform().ToString());
 }
 
-TEST_P(ShellSurfaceBoundsModeTest, DefaultDeviceScaleFactorFromDisplayManager) {
+TEST_P(ShellSurfaceTestWithClientControlledParam,
+       DefaultDeviceScaleFactorFromDisplayManager) {
   int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   display::Display::SetInternalDisplayId(display_id);
   gfx::Size size(1920, 1080);
@@ -429,7 +426,7 @@
   surface->Commit();
 
   gfx::Transform transform;
-  if (IsClientBoundsMode())
+  if (IsClientControlled())
     transform.Scale(1.0 / scale, 1.0 / scale);
 
   EXPECT_EQ(
@@ -545,7 +542,7 @@
   EXPECT_TRUE(is_resizing);
 }
 
-TEST_P(ShellSurfaceBoundsModeTest, ToggleFullscreen) {
+TEST_P(ShellSurfaceTestWithClientControlledParam, ToggleFullscreen) {
   gfx::Size buffer_size(256, 256);
   std::unique_ptr<Buffer> buffer(
       new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
@@ -556,15 +553,15 @@
   surface->Attach(buffer.get());
   surface->Commit();
   EXPECT_FALSE(HasBackdrop());
-  if (!IsClientBoundsMode()) {
+  if (!IsClientControlled()) {
     EXPECT_EQ(buffer_size.ToString(), shell_surface->GetWidget()
                                           ->GetWindowBoundsInScreen()
                                           .size()
                                           .ToString());
   }
   shell_surface->Maximize();
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
-  if (!IsClientBoundsMode()) {
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
+  if (!IsClientControlled()) {
     EXPECT_EQ(CurrentContext()->bounds().width(),
               shell_surface->GetWidget()->GetWindowBoundsInScreen().width());
   }
@@ -575,18 +572,18 @@
   // Enter fullscreen mode.
   ash::wm::GetWindowState(window)->OnWMEvent(&event);
 
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
-  if (!IsClientBoundsMode()) {
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
+  if (!IsClientControlled()) {
     EXPECT_EQ(CurrentContext()->bounds().ToString(),
               shell_surface->GetWidget()->GetWindowBoundsInScreen().ToString());
   }
 
   // Leave fullscreen mode.
   ash::wm::GetWindowState(window)->OnWMEvent(&event);
-  EXPECT_EQ(IsClientBoundsMode(), HasBackdrop());
+  EXPECT_EQ(IsClientControlled(), HasBackdrop());
 
   // Check that shell surface is maximized.
-  if (!IsClientBoundsMode()) {
+  if (!IsClientControlled()) {
     EXPECT_EQ(CurrentContext()->bounds().width(),
               shell_surface->GetWidget()->GetWindowBoundsInScreen().width());
   }
diff --git a/components/exo/test/exo_test_helper.cc b/components/exo/test/exo_test_helper.cc
index 3be9fdc..c99278c 100644
--- a/components/exo/test/exo_test_helper.cc
+++ b/components/exo/test/exo_test_helper.cc
@@ -31,9 +31,8 @@
   surface_.reset(new Surface());
   int container = is_modal ? ash::kShellWindowId_SystemModalContainer
                            : ash::kShellWindowId_DefaultContainer;
-  shell_surface_ = std::make_unique<ShellSurface>(
-      surface_.get(), ShellSurface::BoundsMode::SHELL, gfx::Point(), true,
-      false, container);
+  shell_surface_ = std::make_unique<ShellSurface>(surface_.get(), gfx::Point(),
+                                                  true, false, container);
 
   buffer_.reset(new Buffer(std::move(gpu_buffer)));
   surface_->Attach(buffer_.get());
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index a7ea2de..c6620e3 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -1764,7 +1764,7 @@
       parent->GetWidget()->widget_delegate()->GetContentsView(), &origin);
   shell_surface->SetOrigin(origin);
   shell_surface->SetContainer(ash::kShellWindowId_MenuContainer);
-  shell_surface->SetBoundsMode(ShellSurface::BoundsMode::FIXED);
+  shell_surface->DisableMovement();
   shell_surface->SetActivatable(false);
   shell_surface->SetCanMinimize(false);
   shell_surface->SetEnabled(true);
diff --git a/components/exo/xdg_shell_surface.cc b/components/exo/xdg_shell_surface.cc
index 9bdecdd..c0e48e7 100644
--- a/components/exo/xdg_shell_surface.cc
+++ b/components/exo/xdg_shell_surface.cc
@@ -10,13 +10,11 @@
 // XdgShellSurface, public:
 
 XdgShellSurface::XdgShellSurface(Surface* surface,
-                                 BoundsMode bounds_mode,
                                  const gfx::Point& origin,
                                  bool activatable,
                                  bool can_minimize,
                                  int container)
     : ShellSurface(surface,
-                   bounds_mode,
                    origin,
                    activatable,
                    can_minimize,
@@ -24,11 +22,4 @@
 
 XdgShellSurface::~XdgShellSurface() {}
 
-void XdgShellSurface::SetBoundsMode(BoundsMode mode) {
-  TRACE_EVENT1("exo", "XdgShellSurface::SetBoundsMode", "mode",
-               static_cast<int>(mode));
-
-  bounds_mode_ = mode;
-}
-
 }  // namespace exo
diff --git a/components/exo/xdg_shell_surface.h b/components/exo/xdg_shell_surface.h
index d34160b71..9a031f5 100644
--- a/components/exo/xdg_shell_surface.h
+++ b/components/exo/xdg_shell_surface.h
@@ -41,22 +41,15 @@
 // This class implements shell surface for XDG protocol.
 class XdgShellSurface : public ShellSurface {
  public:
-  // The |origin| is in screen coordinates. When bounds are controlled by the
-  // shell or fixed, it determines the initial position of the shell surface.
-  // In that case, the position specified as part of the geometry is relative
-  // to the shell surface.
-  // TODO(reveman|oshima): Remove bounds_mode.
+  // The |origin| is the initial position in screen coordinates. The position
+  // specified as part of the geometry is relative to the shell surface.
   XdgShellSurface(Surface* surface,
-                  BoundsMode bounds_mode,
                   const gfx::Point& origin,
                   bool activatable,
                   bool can_minimize,
                   int container);
   ~XdgShellSurface() override;
 
-  // Set bounds mode for surface.
-  void SetBoundsMode(BoundsMode mode);
-
  private:
   DISALLOW_COPY_AND_ASSIGN(XdgShellSurface);
 };
diff --git a/components/feedback/anonymizer_tool.cc b/components/feedback/anonymizer_tool.cc
index 8fa555b7..cd4ce51 100644
--- a/components/feedback/anonymizer_tool.cc
+++ b/components/feedback/anonymizer_tool.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "content/public/browser/browser_thread.h"
 #include "third_party/re2/src/re2/re2.h"
 
 using re2::RE2;
@@ -229,11 +230,19 @@
 AnonymizerTool::AnonymizerTool()
     : custom_patterns_with_context_(arraysize(kCustomPatternsWithContext)),
       custom_patterns_without_context_(
-          arraysize(kCustomPatternsWithoutContext)) {}
+          arraysize(kCustomPatternsWithoutContext)) {
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+}
 
-AnonymizerTool::~AnonymizerTool() {}
+AnonymizerTool::~AnonymizerTool() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
 
 std::string AnonymizerTool::Anonymize(const std::string& input) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!::content::BrowserThread::CurrentlyOn(::content::BrowserThread::UI))
+      << "This is an expensive operation. Do not execute this on the UI "
+         "thread.";
   std::string anonymized = AnonymizeMACAddresses(input);
   anonymized = AnonymizeCustomPatterns(std::move(anonymized));
   return anonymized;
@@ -375,4 +384,17 @@
   return result;
 }
 
+AnonymizerToolContainer::AnonymizerToolContainer(
+    scoped_refptr<base::SequencedTaskRunner> task_runner)
+    : anonymizer_(new AnonymizerTool), task_runner_(task_runner) {}
+
+AnonymizerToolContainer::~AnonymizerToolContainer() {
+  task_runner_->DeleteSoon(FROM_HERE, std::move(anonymizer_));
+}
+
+AnonymizerTool* AnonymizerToolContainer::Get() {
+  DCHECK(task_runner_->RunsTasksInCurrentSequence());
+  return anonymizer_.get();
+}
+
 }  // namespace feedback
diff --git a/components/feedback/anonymizer_tool.h b/components/feedback/anonymizer_tool.h
index e6e889e..a4e2d3a 100644
--- a/components/feedback/anonymizer_tool.h
+++ b/components/feedback/anonymizer_tool.h
@@ -11,6 +11,9 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
+#include "base/sequenced_task_runner.h"
 
 namespace re2 {
 class RE2;
@@ -34,6 +37,8 @@
 
   // Returns an anonymized version of |input|. PII-sensitive data (such as MAC
   // addresses) in |input| is replaced with unique identifiers.
+  // This is an expensive operation. Make sure not to execute this on the UI
+  // thread.
   std::string Anonymize(const std::string& input);
 
  private:
@@ -70,9 +75,33 @@
   // pattern. Key is the string representation of the RegEx.
   std::map<std::string, std::unique_ptr<re2::RE2>> regexp_cache_;
 
+  SEQUENCE_CHECKER(sequence_checker_);
+
   DISALLOW_COPY_AND_ASSIGN(AnonymizerTool);
 };
 
+// A container for a AnonymizerTool that is thread-safely ref-countable.
+// This is useful for a class that wants to post an async anonymization task
+// to a background sequence runner and not deal with its own life-cycle ending
+// while the AnonymizerTool is busy on another sequence.
+class AnonymizerToolContainer
+    : public base::RefCountedThreadSafe<AnonymizerToolContainer> {
+ public:
+  explicit AnonymizerToolContainer(
+      scoped_refptr<base::SequencedTaskRunner> task_runner);
+
+  // Returns a pointer to the instance of this anonymier. May only be called
+  // on |task_runner_|.
+  AnonymizerTool* Get();
+
+ private:
+  friend class base::RefCountedThreadSafe<AnonymizerToolContainer>;
+  ~AnonymizerToolContainer();
+
+  std::unique_ptr<AnonymizerTool> anonymizer_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+};
+
 }  // namespace feedback
 
 #endif  // COMPONENTS_FEEDBACK_ANONYMIZER_TOOL_H_
diff --git a/components/feedback/anonymizer_tool_unittest.cc b/components/feedback/anonymizer_tool_unittest.cc
index c0b8754..524a5ab4 100644
--- a/components/feedback/anonymizer_tool_unittest.cc
+++ b/components/feedback/anonymizer_tool_unittest.cc
@@ -201,4 +201,30 @@
                                                  &space));
 }
 
+TEST_F(AnonymizerToolTest, AnonymizeChunk) {
+  std::string data =
+      "aaaaaaaa [SSID=123aaaaaa]aaaaa\n"  // SSID.
+      "aaaaaaaahttp://tets.comaaaaaaa\n"  // URL.
+      "aaaaaemail@example.comaaa\n"       // Email address.
+      "example@@1234\n"           // No PII, it is not valid email address.
+      "255.255.155.255\n"         // IP address.
+      "aaaa123.123.45.4aaa\n"     // IP address.
+      "11:11;11::11\n"            // IP address.
+      "11::11\n"                  // IP address.
+      "11:11:abcdef:0:0:0:0:0\n"  // No PII.
+      "aa:aa:aa:aa:aa:aa";        // MAC address (BSSID).
+  std::string result =
+      "aaaaaaaa [SSID=1]aaaaa\n"
+      "aaaaaaaa<URL: 1>\n"
+      "<email: 1>\n"
+      "example@@1234\n"
+      "<IPv4: 1>55\n"
+      "aaaa<IPv4: 2>aaa\n"
+      "11:11;<IPv6: 1>\n"
+      "<IPv6: 1>\n"
+      "11:11:abcdef:0:0:0:0:0\n"
+      "aa:aa:aa:00:00:01";
+  EXPECT_EQ(result, anonymizer_.Anonymize(data));
+}
+
 }  // namespace feedback
diff --git a/components/feedback/system_logs/system_logs_fetcher.cc b/components/feedback/system_logs/system_logs_fetcher.cc
index 82909f28..74fb95ad 100644
--- a/components/feedback/system_logs/system_logs_fetcher.cc
+++ b/components/feedback/system_logs/system_logs_fetcher.cc
@@ -9,6 +9,8 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/memory/ptr_util.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.h"
 #include "content/public/browser/browser_thread.h"
 
 using content::BrowserThread;
@@ -34,17 +36,35 @@
   return false;
 }
 
+// Runs the Anonymizer tool over the entris of |response|.
+void Anonymize(feedback::AnonymizerTool* anonymizer,
+               SystemLogsResponse* response) {
+  for (auto& element : *response) {
+    if (!IsKeyWhitelisted(element.first))
+      element.second = anonymizer->Anonymize(element.second);
+  }
+}
+
 }  // namespace
 
 SystemLogsFetcher::SystemLogsFetcher(bool scrub_data)
     : response_(base::MakeUnique<SystemLogsResponse>()),
       num_pending_requests_(0),
+      task_runner_for_anonymizer_(base::CreateSequencedTaskRunnerWithTraits(
+          {// User visible because this is called when the user is looking at
+           // the send feedback dialog, watching a spinner.
+           base::TaskPriority::USER_VISIBLE,
+           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
       weak_ptr_factory_(this) {
   if (scrub_data)
     anonymizer_ = base::MakeUnique<feedback::AnonymizerTool>();
 }
 
-SystemLogsFetcher::~SystemLogsFetcher() {}
+SystemLogsFetcher::~SystemLogsFetcher() {
+  // Ensure that destruction happens on same sequence where the object is being
+  // accessed.
+  task_runner_for_anonymizer_->DeleteSoon(FROM_HERE, std::move(anonymizer_));
+}
 
 void SystemLogsFetcher::AddSource(std::unique_ptr<SystemLogsSource> source) {
   data_sources_.emplace_back(std::move(source));
@@ -73,12 +93,20 @@
   VLOG(1) << "Received SystemLogSource: " << source_name;
 
   if (anonymizer_) {
-    for (auto& element : *response) {
-      if (!IsKeyWhitelisted(element.first))
-        element.second = anonymizer_->Anonymize(element.second);
-    }
+    // It is safe to pass the unretained anonymizer_ instance here because
+    // the anonymizer_ is owned by |this| and |this| only deletes itself
+    // once all responses have been collected and added (see AddResponse()).
+    SystemLogsResponse* response_ptr = response.get();
+    task_runner_for_anonymizer_->PostTaskAndReply(
+        FROM_HERE,
+        base::BindOnce(Anonymize, base::Unretained(anonymizer_.get()),
+                       base::Unretained(response_ptr)),
+        base::BindOnce(&SystemLogsFetcher::AddResponse,
+                       weak_ptr_factory_.GetWeakPtr(), source_name,
+                       std::move(response)));
+  } else {
+    AddResponse(source_name, std::move(response));
   }
-  AddResponse(source_name, std::move(response));
 }
 
 void SystemLogsFetcher::AddResponse(
diff --git a/components/feedback/system_logs/system_logs_fetcher.h b/components/feedback/system_logs/system_logs_fetcher.h
index 60b9d17..18ad0b3 100644
--- a/components/feedback/system_logs/system_logs_fetcher.h
+++ b/components/feedback/system_logs/system_logs_fetcher.h
@@ -15,6 +15,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
 #include "components/feedback/anonymizer_tool.h"
 #include "components/feedback/feedback_common.h"
 #include "components/feedback/system_logs/system_logs_source.h"
@@ -72,6 +73,7 @@
   size_t num_pending_requests_;  // The number of callbacks it should get.
 
   std::unique_ptr<feedback::AnonymizerTool> anonymizer_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_for_anonymizer_;
 
   base::WeakPtrFactory<SystemLogsFetcher> weak_ptr_factory_;
 
diff --git a/components/navigation_interception/intercept_navigation_throttle.cc b/components/navigation_interception/intercept_navigation_throttle.cc
index 81acec4..76209a6 100644
--- a/components/navigation_interception/intercept_navigation_throttle.cc
+++ b/components/navigation_interception/intercept_navigation_throttle.cc
@@ -29,8 +29,13 @@
   base::ElapsedTimer timer;
 
   auto result = CheckIfShouldIgnoreNavigation(false);
-  UMA_HISTOGRAM_COUNTS_10M("Navigation.Intercept.WillStart",
-                           timer.Elapsed().InMicroseconds());
+  if (navigation_handle()->IsInMainFrame()) {
+    UMA_HISTOGRAM_COUNTS_10M("Navigation.Intercept.WillStart.Mainframe",
+                             timer.Elapsed().InMicroseconds());
+  } else {
+    UMA_HISTOGRAM_COUNTS_10M("Navigation.Intercept.WillStart.Subframe",
+                             timer.Elapsed().InMicroseconds());
+  }
   return result;
 }
 
diff --git a/components/offline_pages/core/offline_page_feature.cc b/components/offline_pages/core/offline_page_feature.cc
index d08e000..5c59bef 100644
--- a/components/offline_pages/core/offline_page_feature.cc
+++ b/components/offline_pages/core/offline_page_feature.cc
@@ -48,9 +48,6 @@
 const base::Feature kBackgroundLoaderForDownloadsFeature{
     "BackgroundLoadingForDownloads", base::FEATURE_ENABLED_BY_DEFAULT};
 
-const base::Feature kOfflinePagesAsyncDownloadFeature{
-    "OfflinePagesAsyncDownload", base::FEATURE_DISABLED_BY_DEFAULT};
-
 const base::Feature kPrefetchingOfflinePagesFeature{
     "OfflinePagesPrefetching", base::FEATURE_DISABLED_BY_DEFAULT};
 
@@ -87,10 +84,6 @@
   return base::FeatureList::IsEnabled(kBackgroundLoaderForDownloadsFeature);
 }
 
-bool IsOfflinePagesAsyncDownloadEnabled() {
-  return base::FeatureList::IsEnabled(kOfflinePagesAsyncDownloadFeature);
-}
-
 bool IsPrefetchingOfflinePagesEnabled() {
   return base::FeatureList::IsEnabled(kPrefetchingOfflinePagesFeature);
 }
diff --git a/components/offline_pages/core/offline_page_feature.h b/components/offline_pages/core/offline_page_feature.h
index c86c8ae0..f29cd06 100644
--- a/components/offline_pages/core/offline_page_feature.h
+++ b/components/offline_pages/core/offline_page_feature.h
@@ -16,7 +16,6 @@
 extern const base::Feature kOfflinePagesCTFeature;
 extern const base::Feature kOfflinePagesSharingFeature;
 extern const base::Feature kBackgroundLoaderForDownloadsFeature;
-extern const base::Feature kOfflinePagesAsyncDownloadFeature;
 extern const base::Feature kPrefetchingOfflinePagesFeature;
 extern const base::Feature kOfflinePagesLoadSignalCollectingFeature;
 extern const base::Feature kOfflinePagesCTV2Feature;
@@ -47,9 +46,6 @@
 // Returns true if concurrent background loading is enabled for svelte.
 bool IsOfflinePagesSvelteConcurrentLoadingEnabled();
 
-// Returns true if downloading a page asynchonously is enabled.
-bool IsOfflinePagesAsyncDownloadEnabled();
-
 // Returns true if prefetching offline pages is enabled.
 bool IsPrefetchingOfflinePagesEnabled();
 
diff --git a/components/offline_pages/core/offline_page_metadata_store_sql.cc b/components/offline_pages/core/offline_page_metadata_store_sql.cc
index 28648612..391bb00d 100644
--- a/components/offline_pages/core/offline_page_metadata_store_sql.cc
+++ b/components/offline_pages/core/offline_page_metadata_store_sql.cc
@@ -14,6 +14,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/offline_pages/core/offline_page_item.h"
+#include "components/offline_pages/core/offline_store_types.h"
 #include "components/offline_pages/core/offline_store_utils.h"
 #include "sql/connection.h"
 #include "sql/statement.h"
@@ -22,19 +23,6 @@
 namespace offline_pages {
 namespace {
 
-// This enum is backed by a UMA histogram therefore its entries should not be
-// deleted or re-ordered and new ones should only be appended.
-// See enum definition with the same name in tools/metrics/histograms/enum.xml.
-enum OfflinePagesStoreEvent {
-  STORE_OPENED_FIRST_TIME = 0,
-  STORE_REOPENED = 1,
-  STORE_CLOSED = 2,
-  STORE_CLOSE_SKIPPED = 3,
-
-  // NOTE: always keep this entry at the end.
-  STORE_EVENT_COUNT
-};
-
 // This is a macro instead of a const so that
 // it can be used inline in other SQL statements below.
 #define OFFLINE_PAGES_TABLE_NAME "offlinepages_v1"
diff --git a/components/offline_pages/core/offline_pages_ukm_reporter.cc b/components/offline_pages/core/offline_pages_ukm_reporter.cc
index e6e01bb..355320d 100644
--- a/components/offline_pages/core/offline_pages_ukm_reporter.cc
+++ b/components/offline_pages/core/offline_pages_ukm_reporter.cc
@@ -10,11 +10,6 @@
 
 namespace offline_pages {
 
-const char OfflinePagesUkmReporter::kRequestUkmEventName[] =
-    "OfflinePages.SavePageRequested";
-const char OfflinePagesUkmReporter::kForegroundUkmMetricName[] =
-    "RequestedFromForeground";
-
 void OfflinePagesUkmReporter::ReportUrlOfflineRequest(const GURL& gurl,
                                                       bool foreground) {
   ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
@@ -25,20 +20,11 @@
   int32_t source_id = ukm::UkmRecorder::GetNewSourceID();
 
   // Associate the URL with this navigation.
-  ukm_recorder->UpdateSourceURL(source_id, gurl);
+  // TODO(petewil): re-enable once crbug/792197 is addressed.
+  // ukm_recorder->UpdateSourceURL(source_id, gurl);
 
   // Tag this metric as an offline page request for the URL.  This is a private
   // member of UkmRecorder, so we need to be friends to use it.
-  // std::unique_ptr<ukm::UkmEntryBuilder> builder =
-  // ukm_recorder->GetEntryBuilder(
-  //     source_id, OfflinePagesUkmReporter::kRequestUkmEventName);
-  // int metric_value = 0;
-  // if (foreground)
-  //   metric_value = 1;
-  // builder->AddMetric(OfflinePagesUkmReporter::kForegroundUkmMetricName,
-  //                    metric_value);
-
-  // TODO: Change to the new way:
   ukm::builders::OfflinePages_SavePageRequested(source_id)
       .SetRequestedFromForeground(foreground ? 1 : 0)
       .Record(ukm_recorder);
diff --git a/components/offline_pages/core/offline_pages_ukm_reporter.h b/components/offline_pages/core/offline_pages_ukm_reporter.h
index c644ebf..362d588 100644
--- a/components/offline_pages/core/offline_pages_ukm_reporter.h
+++ b/components/offline_pages/core/offline_pages_ukm_reporter.h
@@ -13,9 +13,6 @@
 // needs to be in BROWSER code, but the interface is used from COMPONENTS code.
 class OfflinePagesUkmReporter {
  public:
-  static const char kRequestUkmEventName[];
-  static const char kForegroundUkmMetricName[];
-
   virtual ~OfflinePagesUkmReporter() = default;
 
   // Report that an offline copy has been made of this URL.
diff --git a/components/offline_pages/core/offline_pages_ukm_reporter_unittest.cc b/components/offline_pages/core/offline_pages_ukm_reporter_unittest.cc
index 76834bd..3cefc13e 100644
--- a/components/offline_pages/core/offline_pages_ukm_reporter_unittest.cc
+++ b/components/offline_pages/core/offline_pages_ukm_reporter_unittest.cc
@@ -33,7 +33,8 @@
       ukm::builders::OfflinePages_SavePageRequested::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* entry : entries) {
-    test_recorder()->ExpectEntrySourceHasUrl(entry, gurl);
+    // TODO(petewil): re-enable once crbug/792197 is addressed.
+    // test_recorder()->ExpectEntrySourceHasUrl(entry, gurl);
     test_recorder()->ExpectEntryMetric(
         entry,
         ukm::builders::OfflinePages_SavePageRequested::
diff --git a/components/offline_pages/core/offline_store_types.h b/components/offline_pages/core/offline_store_types.h
index 65d1e4bd..dd98e17 100644
--- a/components/offline_pages/core/offline_store_types.h
+++ b/components/offline_pages/core/offline_store_types.h
@@ -55,6 +55,19 @@
   StoreState store_state;
 };
 
+// This enum is backed by a UMA histogram therefore its entries should not be
+// deleted or re-ordered and new ones should only be appended.
+// See enum definition with the same name in tools/metrics/histograms/enum.xml.
+enum OfflinePagesStoreEvent {
+  STORE_OPENED_FIRST_TIME = 0,
+  STORE_REOPENED = 1,
+  STORE_CLOSED = 2,
+  STORE_CLOSE_SKIPPED = 3,
+
+  // NOTE: always keep this entry at the end.
+  STORE_EVENT_COUNT
+};
+
 }  // namespace offline_pages
 
 #endif  // COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_STORE_TYPES_H_
diff --git a/components/offline_pages/core/prefetch/download_completed_task_unittest.cc b/components/offline_pages/core/prefetch/download_completed_task_unittest.cc
index 4674286..317cc1fe 100644
--- a/components/offline_pages/core/prefetch/download_completed_task_unittest.cc
+++ b/components/offline_pages/core/prefetch/download_completed_task_unittest.cc
@@ -8,7 +8,7 @@
 #include <vector>
 
 #include "base/test/histogram_tester.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "components/offline_pages/core/prefetch/prefetch_item.h"
@@ -50,7 +50,7 @@
   base::HistogramTester* histogram_tester() { return histogram_tester_.get(); }
 
  private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::ThreadTaskRunnerHandle task_runner_handle_;
   TestPrefetchDispatcher dispatcher_;
   PrefetchStoreTestUtil store_test_util_;
@@ -58,7 +58,7 @@
 };
 
 DownloadCompletedTaskTest::DownloadCompletedTaskTest()
-    : task_runner_(new base::TestSimpleTaskRunner),
+    : task_runner_(new base::TestMockTimeTaskRunner),
       task_runner_handle_(task_runner_),
       store_test_util_(task_runner_) {}
 
diff --git a/components/offline_pages/core/prefetch/import_archives_task_unittest.cc b/components/offline_pages/core/prefetch/import_archives_task_unittest.cc
index bacc75e0..405fb15 100644
--- a/components/offline_pages/core/prefetch/import_archives_task_unittest.cc
+++ b/components/offline_pages/core/prefetch/import_archives_task_unittest.cc
@@ -8,7 +8,7 @@
 #include <vector>
 
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "components/offline_pages/core/prefetch/prefetch_importer.h"
@@ -81,14 +81,14 @@
   TestPrefetchImporter* importer() { return &test_importer_; }
 
  private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::ThreadTaskRunnerHandle task_runner_handle_;
   PrefetchStoreTestUtil store_test_util_;
   TestPrefetchImporter test_importer_;
 };
 
 ImportArchivesTaskTest::ImportArchivesTaskTest()
-    : task_runner_(new base::TestSimpleTaskRunner),
+    : task_runner_(new base::TestMockTimeTaskRunner),
       task_runner_handle_(task_runner_),
       store_test_util_(task_runner_) {}
 
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc
index ec97b51..5fc63a6 100644
--- a/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc
@@ -64,7 +64,7 @@
   void TearDown() override {
     prefetch_service_taco_.reset();
     PrefetchRequestTestBase::TearDown();
-    RunUntilIdle();
+    FastForwardUntilNoTasksRemain();
   }
 
   void StartDownload(const std::string& download_id,
diff --git a/components/offline_pages/core/prefetch/prefetch_request_test_base.cc b/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
index 00e4d7c72..1afcf048 100644
--- a/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
+++ b/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
@@ -18,7 +18,7 @@
     "Test Experiment";
 
 PrefetchRequestTestBase::PrefetchRequestTestBase()
-    : task_runner_(new base::TestSimpleTaskRunner),
+    : task_runner_(new base::TestMockTimeTaskRunner),
       task_runner_handle_(task_runner_),
       request_context_(new net::TestURLRequestContextGetter(
           base::ThreadTaskRunnerHandle::Get())) {}
@@ -95,4 +95,8 @@
   task_runner_->RunUntilIdle();
 }
 
+void PrefetchRequestTestBase::FastForwardUntilNoTasksRemain() {
+  task_runner_->FastForwardUntilNoTasksRemain();
+}
+
 }  // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_request_test_base.h b/components/offline_pages/core/prefetch/prefetch_request_test_base.h
index 401ea27..68b4d87a 100644
--- a/components/offline_pages/core/prefetch/prefetch_request_test_base.h
+++ b/components/offline_pages/core/prefetch/prefetch_request_test_base.h
@@ -8,7 +8,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/metrics/field_trial.h"
 #include "base/test/scoped_feature_list.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_request_test_util.h"
@@ -39,15 +39,16 @@
   }
 
   void RunUntilIdle();
+  void FastForwardUntilNoTasksRemain();
 
  protected:
   // Derived classes may need these to construct other members.
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner() {
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner() {
     return task_runner_;
   }
 
  private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::ThreadTaskRunnerHandle task_runner_handle_;
   net::TestURLFetcherFactory url_fetcher_factory_;
   scoped_refptr<net::TestURLRequestContextGetter> request_context_;
diff --git a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota_unittest.cc b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota_unittest.cc
index f4be155b..d87ab9f 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota_unittest.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "components/offline_pages/core/prefetch/store/prefetch_downloader_quota.h"
 
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/offline_page_feature.h"
 #include "components/offline_pages/core/prefetch/store/prefetch_store_test_util.h"
@@ -37,14 +37,14 @@
   void SetTestingMaxDailyQuotaBytes(const std::string& max_config);
 
  private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::ThreadTaskRunnerHandle task_runner_handle_;
   PrefetchStoreTestUtil store_test_util_;
   variations::testing::VariationParamsManager params_manager_;
 };
 
 PrefetchDownloaderQuotaTest::PrefetchDownloaderQuotaTest()
-    : task_runner_(new base::TestSimpleTaskRunner),
+    : task_runner_(new base::TestMockTimeTaskRunner),
       task_runner_handle_(task_runner_),
       store_test_util_(task_runner_) {}
 
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store.cc b/components/offline_pages/core/prefetch/store/prefetch_store.cc
index 0ba3ff26..6aa51cf 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_store.cc
@@ -9,6 +9,7 @@
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/sequenced_task_runner.h"
 #include "base/task_runner_util.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -68,16 +69,33 @@
   return PrefetchStoreSchema::CreateOrUpgradeIfNeeded(db);
 }
 
+void CloseDatabaseSync(
+    sql::Connection* db,
+    scoped_refptr<base::SingleThreadTaskRunner> callback_runner,
+    base::OnceClosure callback) {
+  if (db)
+    db->Close();
+  callback_runner->PostTask(FROM_HERE, std::move(callback));
+}
+
+void ReportStoreEvent(OfflinePagesStoreEvent event) {
+  UMA_HISTOGRAM_ENUMERATION("OfflinePages.PrefetchStore.StoreEvent", event,
+                            OfflinePagesStoreEvent::STORE_EVENT_COUNT);
+}
+
 }  // namespace
 
+// static
+constexpr base::TimeDelta PrefetchStore::kClosingDelay;
+
 PrefetchStore::PrefetchStore(
     scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
     : blocking_task_runner_(std::move(blocking_task_runner)),
       in_memory_(true),
-      db_(new sql::Connection,
-          base::OnTaskRunnerDeleter(blocking_task_runner_)),
+      db_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner_)),
       initialization_status_(InitializationStatus::NOT_INITIALIZED),
-      weak_ptr_factory_(this) {}
+      weak_ptr_factory_(this),
+      closing_weak_ptr_factory_(this) {}
 
 PrefetchStore::PrefetchStore(
     scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
@@ -85,17 +103,33 @@
     : blocking_task_runner_(std::move(blocking_task_runner)),
       db_file_path_(path.AppendASCII(kPrefetchStoreFileName)),
       in_memory_(false),
-      db_(new sql::Connection,
-          base::OnTaskRunnerDeleter(blocking_task_runner_)),
+      db_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner_)),
       initialization_status_(InitializationStatus::NOT_INITIALIZED),
-      weak_ptr_factory_(this) {}
+      weak_ptr_factory_(this),
+      closing_weak_ptr_factory_(this) {}
 
 PrefetchStore::~PrefetchStore() {}
 
 void PrefetchStore::Initialize(base::OnceClosure pending_command) {
   DCHECK_EQ(initialization_status_, InitializationStatus::NOT_INITIALIZED);
-
   initialization_status_ = InitializationStatus::INITIALIZING;
+
+  if (!last_closing_time_.is_null()) {
+    ReportStoreEvent(OfflinePagesStoreEvent::STORE_REOPENED);
+    UMA_HISTOGRAM_CUSTOM_TIMES("OfflinePages.PrefetchStore.TimeFromCloseToOpen",
+                               base::Time::Now() - last_closing_time_,
+                               base::TimeDelta::FromMilliseconds(10),
+                               base::TimeDelta::FromMinutes(10),
+                               50 /* buckets */);
+  } else {
+    ReportStoreEvent(OfflinePagesStoreEvent::STORE_OPENED_FIRST_TIME);
+  }
+
+  // This is how we reset a pointer and provide deleter. This is necessary to
+  // ensure that we can close the store more than once.
+  db_ = std::unique_ptr<sql::Connection, base::OnTaskRunnerDeleter>(
+      new sql::Connection, base::OnTaskRunnerDeleter(blocking_task_runner_));
+
   base::PostTaskAndReplyWithResult(
       blocking_task_runner_.get(), FROM_HERE,
       base::BindOnce(&InitializeSync, db_.get(), db_file_path_, in_memory_),
@@ -110,6 +144,8 @@
   DCHECK_EQ(initialization_status_, InitializationStatus::INITIALIZING);
   initialization_status_ =
       success ? InitializationStatus::SUCCESS : InitializationStatus::FAILURE;
+  if (initialization_status_ != InitializationStatus::SUCCESS)
+    db_.reset();
 
   CHECK(!pending_command.is_null());
   std::move(pending_command).Run();
@@ -121,4 +157,27 @@
     initialization_status_ = InitializationStatus::NOT_INITIALIZED;
 }
 
+void PrefetchStore::CloseInternal() {
+  if (initialization_status_ != InitializationStatus::SUCCESS) {
+    ReportStoreEvent(OfflinePagesStoreEvent::STORE_CLOSE_SKIPPED);
+    return;
+  }
+
+  last_closing_time_ = base::Time::Now();
+  ReportStoreEvent(OfflinePagesStoreEvent::STORE_CLOSED);
+
+  initialization_status_ = InitializationStatus::NOT_INITIALIZED;
+  blocking_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          &CloseDatabaseSync, db_.get(), base::ThreadTaskRunnerHandle::Get(),
+          base::BindOnce(&PrefetchStore::CloseInternalDone,
+                         weak_ptr_factory_.GetWeakPtr(), std::move(db_))));
+}
+
+void PrefetchStore::CloseInternalDone(
+    std::unique_ptr<sql::Connection, base::OnTaskRunnerDeleter> db) {
+  db.reset();
+}
+
 }  // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store.h b/components/offline_pages/core/prefetch/store/prefetch_store.h
index d93a23f..327346d078 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store.h
+++ b/components/offline_pages/core/prefetch/store/prefetch_store.h
@@ -14,6 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/sequenced_task_runner.h"
 #include "base/task_runner_util.h"
+#include "base/threading/thread_task_runner_handle.h"
 
 namespace sql {
 class Connection;
@@ -49,6 +50,11 @@
   template <typename T>
   using ResultCallback = base::OnceCallback<void(T)>;
 
+  // Defines inactivity time of DB after which it is going to be closed.
+  // TODO(fgorski): Derive appropriate value in a scientific way.
+  static constexpr base::TimeDelta kClosingDelay =
+      base::TimeDelta::FromSeconds(20);
+
   // Creates an instance of |PrefetchStore| with an in-memory SQLite database.
   explicit PrefetchStore(
       scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
@@ -78,13 +84,18 @@
       return;
     }
 
+    // Ensure that any scheduled close operations are canceled.
+    closing_weak_ptr_factory_.InvalidateWeakPtrs();
+
     sql::Connection* db =
         initialization_status_ == InitializationStatus::SUCCESS ? db_.get()
                                                                 : nullptr;
     base::PostTaskAndReplyWithResult(
         blocking_task_runner_.get(), FROM_HERE,
         base::BindOnce(std::move(run_callback), db),
-        std::move(result_callback));
+        base::BindOnce(&PrefetchStore::RescheduleClosing<T>,
+                       weak_ptr_factory_.GetWeakPtr(),
+                       std::move(result_callback)));
   }
 
   // Gets the initialization status of the store.
@@ -103,6 +114,26 @@
   // Used to conclude opening/resetting DB connection.
   void OnInitializeDone(base::OnceClosure pending_command, bool success);
 
+  // Reschedules the closing with a delay. Ensures that |result_callback| is
+  // called.
+  template <typename T>
+  void RescheduleClosing(ResultCallback<T> result_callback, T result) {
+    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&PrefetchStore::CloseInternal,
+                       closing_weak_ptr_factory_.GetWeakPtr()),
+        kClosingDelay);
+
+    std::move(result_callback).Run(std::move(result));
+  }
+
+  // Internal function initiating the closing.
+  void CloseInternal();
+
+  // Completes the closing. Main purpose is to destroy the db pointer.
+  void CloseInternalDone(
+      std::unique_ptr<sql::Connection, base::OnTaskRunnerDeleter> db);
+
   // Background thread where all SQL access should be run.
   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
 
@@ -118,8 +149,13 @@
   // Initialization status of the store.
   InitializationStatus initialization_status_;
 
+  // Time of the last time the store was closed. Kept for metrics reporting.
+  base::Time last_closing_time_;
+
   // Weak pointer to control the callback.
   base::WeakPtrFactory<PrefetchStore> weak_ptr_factory_;
+  // Weak pointer to cancel closing of the store.
+  base::WeakPtrFactory<PrefetchStore> closing_weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(PrefetchStore);
 };
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
index 550d281..4c37ad3 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
@@ -181,7 +181,7 @@
 }  // namespace
 
 PrefetchStoreTestUtil::PrefetchStoreTestUtil(
-    scoped_refptr<base::TestSimpleTaskRunner> task_runner)
+    scoped_refptr<base::TestMockTimeTaskRunner> task_runner)
     : task_runner_(task_runner) {}
 
 PrefetchStoreTestUtil::~PrefetchStoreTestUtil() = default;
@@ -210,7 +210,7 @@
     if (!temp_directory_.Delete())
       DVLOG(1) << "temp_directory_ not created";
   }
-  task_runner_->RunUntilIdle();
+  task_runner_->FastForwardUntilNoTasksRemain();
 }
 
 bool PrefetchStoreTestUtil::InsertPrefetchItem(const PrefetchItem& item) {
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.h b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.h
index 2e27a6e0..d335a967 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.h
+++ b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.h
@@ -14,7 +14,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "base/test/simple_test_clock.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "components/offline_pages/core/prefetch/store/prefetch_store.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -35,7 +35,7 @@
 class PrefetchStoreTestUtil {
  public:
   explicit PrefetchStoreTestUtil(
-      scoped_refptr<base::TestSimpleTaskRunner> task_runner);
+      scoped_refptr<base::TestMockTimeTaskRunner> task_runner);
   ~PrefetchStoreTestUtil();
 
   // Builds a new store in a temporary directory.
@@ -86,7 +86,7 @@
  private:
   void RunUntilIdle();
 
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::ScopedTempDir temp_directory_;
   // TODO(jianli): Refactor this class to avoid owning the store.
   std::unique_ptr<PrefetchStore> owned_store_;
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc b/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc
index ad85727..15ca98e 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "components/offline_pages/core/prefetch/store/prefetch_store.h"
 
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/offline_store_utils.h"
 #include "components/offline_pages/core/prefetch/mock_prefetch_item_generator.h"
@@ -32,18 +32,18 @@
   PrefetchStore* store() { return store_test_util_.store(); }
 
   PrefetchStoreTestUtil* store_util() { return &store_test_util_; }
-
   MockPrefetchItemGenerator* item_generator() { return &item_generator_; }
+  base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
 
  private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::ThreadTaskRunnerHandle task_runner_handle_;
   PrefetchStoreTestUtil store_test_util_;
   MockPrefetchItemGenerator item_generator_;
 };
 
 PrefetchStoreTest::PrefetchStoreTest()
-    : task_runner_(new base::TestSimpleTaskRunner),
+    : task_runner_(new base::TestMockTimeTaskRunner),
       task_runner_handle_(task_runner_),
       store_test_util_(task_runner_) {}
 
@@ -83,4 +83,53 @@
                                                   item1.url));
 }
 
+TEST_F(PrefetchStoreTest, CloseStore) {
+  // This ensures store is started.
+  PrefetchItem item1(
+      item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
+  EXPECT_TRUE(store_util()->InsertPrefetchItem(item1));
+  EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+
+  task_runner()->FastForwardBy(PrefetchStore::kClosingDelay);
+  EXPECT_EQ(InitializationStatus::NOT_INITIALIZED,
+            store()->initialization_status());
+
+  // Should initialize the store again.
+  PrefetchItem item2(
+      item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
+  EXPECT_TRUE(store_util()->InsertPrefetchItem(item2));
+  EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+}
+
+TEST_F(PrefetchStoreTest, CloseStorePostponed) {
+  // This ensures store is started.
+  PrefetchItem item1(
+      item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
+  EXPECT_TRUE(store_util()->InsertPrefetchItem(item1));
+  EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+
+  task_runner()->FastForwardBy(PrefetchStore::kClosingDelay / 2);
+  EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+
+  // Should postpone closing.
+  PrefetchItem item2(
+      item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
+  EXPECT_TRUE(store_util()->InsertPrefetchItem(item2));
+  EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+
+  // This adds up to more than kClosingDelay after the first call, which means
+  // the closing would trigger, it does not however, since second call caused it
+  // to be postponed.
+  task_runner()->FastForwardBy(2 * PrefetchStore::kClosingDelay / 3);
+  // Store should still be initialized.
+  EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+  // There is still a pending task to close the store.
+  EXPECT_TRUE(task_runner()->HasPendingTask());
+
+  // After this step the store should be closed.
+  task_runner()->FastForwardBy(PrefetchStore::kClosingDelay);
+  EXPECT_EQ(InitializationStatus::NOT_INITIALIZED,
+            store()->initialization_status());
+}
+
 }  // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/task_test_base.cc b/components/offline_pages/core/prefetch/task_test_base.cc
index 5b075ac..a67fcf36e 100644
--- a/components/offline_pages/core/prefetch/task_test_base.cc
+++ b/components/offline_pages/core/prefetch/task_test_base.cc
@@ -44,7 +44,7 @@
 }
 
 TaskTestBase::TaskTestBase()
-    : task_runner_(new base::TestSimpleTaskRunner),
+    : task_runner_(new base::TestMockTimeTaskRunner),
       task_runner_handle_(task_runner_),
       store_test_util_(task_runner_) {}
 
@@ -57,7 +57,7 @@
 
 void TaskTestBase::TearDown() {
   store_test_util_.DeleteStore();
-  RunUntilIdle();
+  task_runner_->FastForwardUntilNoTasksRemain();
   testing::Test::TearDown();
 }
 
diff --git a/components/offline_pages/core/prefetch/task_test_base.h b/components/offline_pages/core/prefetch/task_test_base.h
index 5ca9182..1c38a2c2 100644
--- a/components/offline_pages/core/prefetch/task_test_base.h
+++ b/components/offline_pages/core/prefetch/task_test_base.h
@@ -11,7 +11,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "base/test/mock_callback.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/prefetch/mock_prefetch_item_generator.h"
 #include "components/offline_pages/core/prefetch/prefetch_types.h"
@@ -62,7 +62,7 @@
                                        PrefetchItemState state) const;
 
  private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::ThreadTaskRunnerHandle task_runner_handle_;
   net::TestURLFetcherFactory url_fetcher_factory_;
   TestPrefetchNetworkRequestFactory prefetch_request_factory_;
diff --git a/components/omnibox/browser/autocomplete_match_type.cc b/components/omnibox/browser/autocomplete_match_type.cc
index 5dda20e..810b9e5 100644
--- a/components/omnibox/browser/autocomplete_match_type.cc
+++ b/components/omnibox/browser/autocomplete_match_type.cc
@@ -108,29 +108,40 @@
 
   const base::string16 sentinal =
       base::WideToUTF16(kAccessibilityLabelPrefixEndSentinal);
+  const bool has_description = !additional_descriptive_text.empty();
   switch (message) {
     case IDS_ACC_AUTOCOMPLETE_SEARCH_HISTORY:
     case IDS_ACC_AUTOCOMPLETE_SEARCH:
     case IDS_ACC_AUTOCOMPLETE_SUGGESTED_SEARCH:
-      // Additional descriptive text NOT relevant.
-      if (label_prefix_length)
-        *label_prefix_length = AccessibilityLabelPrefixLength(
-            l10n_util::GetStringFUTF16(message, sentinal));
-      return l10n_util::GetStringFUTF16(message, match_text);
+      // Search match.
+      // If additional descriptive text exists with a search, treat as search
+      // with immediate answer, such as Weather in Boston: 53 degrees.
+      if (has_description)
+        message = IDS_ACC_AUTOCOMPLETE_QUICK_ANSWER;
+      break;
 
     case IDS_ACC_AUTOCOMPLETE_HISTORY:
     case IDS_ACC_AUTOCOMPLETE_BOOKMARK:
     case IDS_ACC_AUTOCOMPLETE_CLIPBOARD:
-      // Additional descriptive text relevant.
-      if (label_prefix_length)
-        *label_prefix_length =
-            AccessibilityLabelPrefixLength(l10n_util::GetStringFUTF16(
-                message, sentinal, additional_descriptive_text));
-      return l10n_util::GetStringFUTF16(message, match_text,
-                                        additional_descriptive_text);
+      // History match.
+      // May have descriptive text for the title of the page.
+      break;
     default:
+      NOTREACHED();
       break;
   }
-  NOTREACHED();
-  return match_text;
+
+  // Get the length of friendly text inserted before the actual suggested match.
+  if (label_prefix_length) {
+    *label_prefix_length =
+        has_description
+            ? AccessibilityLabelPrefixLength(l10n_util::GetStringFUTF16(
+                  message, sentinal, additional_descriptive_text))
+            : AccessibilityLabelPrefixLength(
+                  l10n_util::GetStringFUTF16(message, sentinal));
+  }
+
+  return has_description ? l10n_util::GetStringFUTF16(
+                               message, match_text, additional_descriptive_text)
+                         : l10n_util::GetStringFUTF16(message, match_text);
 }
diff --git a/components/omnibox/browser/omnibox_client.h b/components/omnibox/browser/omnibox_client.h
index c505f73..0868741 100644
--- a/components/omnibox/browser/omnibox_client.h
+++ b/components/omnibox/browser/omnibox_client.h
@@ -67,7 +67,7 @@
   // Returns the favicon of the current page.
   virtual gfx::Image GetFavicon() const;
 
-  // Returns true if the visible entry is a New Tab Page rendered by Instant.
+  // Returns true if the current page is a New Tab Page rendered by Instant.
   virtual bool IsInstantNTP() const;
 
   // Returns true if the committed entry is a search results page.
diff --git a/components/omnibox_strings.grdp b/components/omnibox_strings.grdp
index 1ae33d8..50869ed 100644
--- a/components/omnibox_strings.grdp
+++ b/components/omnibox_strings.grdp
@@ -68,6 +68,9 @@
   <message name="IDS_ACC_AUTOCOMPLETE_SUGGESTED_SEARCH" desc="Text for screenreaders describing a suggested search.">
     <ph name="TEXT">$1<ex>dogs</ex> search suggestion</ph>
   </message>
+  <message name="IDS_ACC_AUTOCOMPLETE_QUICK_ANSWER" desc="Readable text represening a query typed by the user in the omnibox, followed by an indication that an answer to that query will follow, followed by the answer. The commas are significant as they will introduce a pause in the spoken text.">
+    <ph name="QUERY">$1<ex>weather in los angeles</ex></ph>, answer, <ph name="ANSWER">$2<ex>sunny and 84 degrees</ex></ph>
+  </message>
   <message name="IDS_ACC_AUTOCOMPLETE_BOOKMARK" desc="Text for screenreaders describing a URL from a bookmark.">
     <ph name="LOCATION_TITLE">$2<ex>The Chromium Projects</ex></ph> <ph name="SHORT_URL">$1<ex>www.chromium.org</ex> bookmark</ph>
   </message>
diff --git a/components/os_crypt/key_storage_linux.cc b/components/os_crypt/key_storage_linux.cc
index 3a04ce5..c92624e 100644
--- a/components/os_crypt/key_storage_linux.cc
+++ b/components/os_crypt/key_storage_linux.cc
@@ -33,30 +33,6 @@
 const char KeyStorageLinux::kKey[] = "Chromium Safe Storage";
 #endif
 
-namespace {
-
-// Copies the password value from |result| to |password| and notifies on
-// |on_password_received| that the result is ready.
-void OnPasswordReceived(base::WaitableEvent* on_password_received,
-                        std::string* password,
-                        const std::string& result) {
-  *password = result;
-  if (on_password_received)
-    on_password_received->Signal();
-}
-
-// Copies the initialisation result from |result| to |success| and notifies on
-// |on_initialized| that the result is ready.
-void OnInitialized(base::WaitableEvent* on_initialized,
-                   bool* success,
-                   const bool& result) {
-  *success = result;
-  if (on_initialized)
-    on_initialized->Signal();
-}
-
-}  // namespace
-
 // static
 std::unique_ptr<KeyStorageLinux> KeyStorageLinux::CreateService(
     const os_crypt::Config& config) {
@@ -137,10 +113,10 @@
       base::WaitableEvent::ResetPolicy::MANUAL,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
   bool success;
-  PostTaskAndReplyWithResult(
-      task_runner, FROM_HERE,
-      base::BindOnce(&KeyStorageLinux::Init, base::Unretained(this)),
-      base::BindOnce(&OnInitialized, &initialized, &success));
+  task_runner->PostTask(
+      FROM_HERE,
+      base::BindOnce(&KeyStorageLinux::BlockOnInitThenSignal,
+                     base::Unretained(this), &initialized, &success));
   initialized.Wait();
   return success;
 }
@@ -158,10 +134,10 @@
       base::WaitableEvent::ResetPolicy::MANUAL,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
   std::string password;
-  PostTaskAndReplyWithResult(
-      task_runner, FROM_HERE,
-      base::BindOnce(&KeyStorageLinux::GetKeyImpl, base::Unretained(this)),
-      base::BindOnce(&OnPasswordReceived, &password_loaded, &password));
+  task_runner->PostTask(
+      FROM_HERE,
+      base::BindOnce(&KeyStorageLinux::BlockOnGetKeyImplThenSignal,
+                     base::Unretained(this), &password_loaded, &password));
   password_loaded.Wait();
   return password;
 }
@@ -169,3 +145,16 @@
 base::SequencedTaskRunner* KeyStorageLinux::GetTaskRunner() {
   return nullptr;
 }
+
+void KeyStorageLinux::BlockOnGetKeyImplThenSignal(
+    base::WaitableEvent* on_password_received,
+    std::string* password) {
+  *password = GetKeyImpl();
+  on_password_received->Signal();
+}
+
+void KeyStorageLinux::BlockOnInitThenSignal(base::WaitableEvent* on_inited,
+                                            bool* success) {
+  *success = Init();
+  on_inited->Signal();
+}
diff --git a/components/os_crypt/key_storage_linux.h b/components/os_crypt/key_storage_linux.h
index 575ff6514..c8fd4e9 100644
--- a/components/os_crypt/key_storage_linux.h
+++ b/components/os_crypt/key_storage_linux.h
@@ -12,6 +12,7 @@
 
 namespace base {
 class SequencedTaskRunner;
+class WaitableEvent;
 }
 
 namespace os_crypt {
@@ -54,6 +55,15 @@
   // Performs Init() on the backend's preferred thread.
   bool WaitForInitOnTaskRunner();
 
+  // Perform the blocking calls to the backend to get the Key. Store it in
+  // |password| and signal completion on |on_password_received|.
+  void BlockOnGetKeyImplThenSignal(base::WaitableEvent* on_password_received,
+                                   std::string* password);
+
+  // Perform the blocking calls to the backend to initialise. Store the
+  // initialisation result in |success| and signal completion on |on_inited|.
+  void BlockOnInitThenSignal(base::WaitableEvent* on_inited, bool* success);
+
   DISALLOW_COPY_AND_ASSIGN(KeyStorageLinux);
 };
 
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
index 1fa952a..187b77b 100644
--- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -32,6 +32,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/sync/driver/fake_sync_service.h"
 #include "components/ukm/test_ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -55,6 +56,8 @@
 using autofill::SuggestionVectorLabelsAre;
 using testing::_;
 
+using UkmEntry = ukm::builders::PageWithPassword;
+
 namespace autofill {
 class AutofillPopupDelegate;
 }
@@ -1178,17 +1181,18 @@
         kAcceptedContextHistogram,
         metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_PASSWORD, 1);
     // Trigger UKM reporting, which happens at destruction time.
+    ukm::SourceId expected_source_id = client->GetUkmSourceId();
     manager.reset();
     autofill_client.reset();
     client.reset();
 
     const auto& entries =
-        test_ukm_recorder.GetEntriesByName("PageWithPassword");
+        test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
     EXPECT_EQ(1u, entries.size());
     for (const auto* entry : entries) {
-      test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kMainFrameUrl));
+      EXPECT_EQ(expected_source_id, entry->source_id);
       test_ukm_recorder.ExpectEntryMetric(
-          entry, password_manager::kUkmPageLevelUserAction,
+          entry, UkmEntry::kPageLevelUserActionName,
           static_cast<int64_t>(
               password_manager::PasswordManagerMetricsRecorder::
                   PageLevelUserAction::kShowAllPasswordsWhileSomeAreSuggested));
@@ -1267,6 +1271,7 @@
         kAcceptedContextHistogram,
         metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_MANUAL_FALLBACK, 1);
     // Trigger UKM reporting, which happens at destruction time.
+    ukm::SourceId expected_source_id = client->GetUkmSourceId();
     manager.reset();
     autofill_client.reset();
     client.reset();
@@ -1275,9 +1280,9 @@
         test_ukm_recorder.GetEntriesByName("PageWithPassword");
     EXPECT_EQ(1u, entries.size());
     for (const auto* entry : entries) {
-      test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kMainFrameUrl));
+      EXPECT_EQ(expected_source_id, entry->source_id);
       test_ukm_recorder.ExpectEntryMetric(
-          entry, password_manager::kUkmPageLevelUserAction,
+          entry, UkmEntry::kPageLevelUserActionName,
           static_cast<int64_t>(
               password_manager::PasswordManagerMetricsRecorder::
                   PageLevelUserAction::kShowAllPasswordsWhileNoneAreSuggested));
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index ee374a2..957013a 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -261,8 +261,7 @@
   metrics_recorder_ = std::move(metrics_recorder);
   if (!metrics_recorder_) {
     metrics_recorder_ = base::MakeRefCounted<PasswordFormMetricsRecorder>(
-        client_->IsMainFrameSecure(), client_->GetUkmRecorder(),
-        client_->GetUkmSourceId(), client_->GetMainFrameURL());
+        client_->IsMainFrameSecure(), client_->GetUkmSourceId());
   }
 
   if (owned_form_fetcher_)
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 7625fe3..3eb2243 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -3834,11 +3834,6 @@
             form_data->password_value, form_data->manual_or_generated));
       }
 
-      // Bind the UKM SourceId to any URL, it does not matter. The SourceId
-      // needs to be bound, though, for reporting to happen.
-      client()->GetUkmRecorder()->UpdateSourceURL(client()->GetUkmSourceId(),
-                                                  GURL("https://example.com/"));
-
       std::vector<const PasswordForm*> suppressed_forms_ptrs;
       for (const auto& form : suppressed_forms)
         suppressed_forms_ptrs.push_back(&form);
@@ -4053,8 +4048,8 @@
     ukm::TestAutoSetUkmRecorder test_ukm_recorder;
     {
       auto metrics_recorder = base::MakeRefCounted<PasswordFormMetricsRecorder>(
-          form_to_fill.origin.SchemeIsCryptographic(), &test_ukm_recorder,
-          test_ukm_recorder.GetNewSourceID(), form_to_fill.origin);
+          form_to_fill.origin.SchemeIsCryptographic(),
+          client()->GetUkmSourceId());
       FakeFormFetcher fetcher;
       PasswordFormManager form_manager(
           password_manager(), client(),
@@ -4068,7 +4063,7 @@
         ukm::builders::PasswordForm::kEntryName);
     EXPECT_EQ(1u, entries.size());
     for (const auto* const entry : entries) {
-      test_ukm_recorder.ExpectEntrySourceHasUrl(entry, form_to_fill.origin);
+      EXPECT_EQ(client()->GetUkmSourceId(), entry->source_id);
       test_ukm_recorder.ExpectEntryMetric(
           entry, ukm::builders::PasswordForm::kManagerFill_ActionName,
           test.expected_event);
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc
index d69da19..843c05c3 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder.cc
+++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -61,13 +61,9 @@
 
 PasswordFormMetricsRecorder::PasswordFormMetricsRecorder(
     bool is_main_frame_secure,
-    ukm::UkmRecorder* ukm_recorder,
-    ukm::SourceId source_id,
-    const GURL& main_frame_url)
+    ukm::SourceId source_id)
     : is_main_frame_secure_(is_main_frame_secure),
-      ukm_recorder_(ukm_recorder),
       source_id_(source_id),
-      main_frame_url_(main_frame_url),
       ukm_entry_builder_(source_id) {}
 
 PasswordFormMetricsRecorder::~PasswordFormMetricsRecorder() {
@@ -133,12 +129,7 @@
     }
   }
 
-  ukm_entry_builder_.Record(ukm_recorder_);
-
-  // Bind |main_frame_url_| to |source_id_| directly before sending the content
-  // of |ukm_recorder_| to ensure that the binding has not been purged already.
-  if (ukm_recorder_)
-    ukm_recorder_->UpdateSourceURL(source_id_, main_frame_url_);
+  ukm_entry_builder_.Record(ukm::UkmRecorder::Get());
 }
 
 void PasswordFormMetricsRecorder::MarkGenerationAvailable() {
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.h b/components/password_manager/core/browser/password_form_metrics_recorder.h
index 52fab3a..1fbd7811 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder.h
+++ b/components/password_manager/core/browser/password_form_metrics_recorder.h
@@ -41,17 +41,9 @@
     : public base::RefCounted<PasswordFormMetricsRecorder> {
  public:
   // Records UKM metrics and reports them on destruction. The |source_id| is
-  // (re-)bound to |main_frame_url| shortly before reporting. As such it is
-  // crucial that the |source_id| is never bound to a different URL by another
-  // consumer. The reason for this late binding is that metrics can be
-  // collected for a WebContents for a long period of time and by the time the
-  // reporting happens, the binding of |source_id| to |main_frame_url| is
-  // already purged. |ukm_recorder| may be a nullptr, in which case no UKM
-  // metrics are recorded.
+  // the ID of the WebContents document that the forms belong to.
   PasswordFormMetricsRecorder(bool is_main_frame_secure,
-                              ukm::UkmRecorder* ukm_recorder,
-                              ukm::SourceId source_id,
-                              const GURL& main_frame_url);
+                              ukm::SourceId source_id);
 
   // ManagerAction - What does the PasswordFormManager do with this form? Either
   // it fills it, or it doesn't. If it doesn't fill it, that's either
@@ -307,18 +299,9 @@
   // data the user has entered.
   SubmittedFormType submitted_form_type_ = kSubmittedFormTypeUnspecified;
 
-  // Recorder to which metrics are sent. Has to outlive this
-  // PasswordFormMetricsRecorder.
-  ukm::UkmRecorder* ukm_recorder_;
-
-  // A SourceId of |ukm_recorder_|. This id gets bound to |main_frame_url_| on
-  // destruction. It can be shared across multiple metrics recorders as long as
-  // they all bind it to the same URL.
+  // The UKM SourceId of the document the form belongs to.
   ukm::SourceId source_id_;
 
-  // URL for which UKMs are reported.
-  GURL main_frame_url_;
-
   // Holds URL keyed metrics (UKMs) to be recorded on destruction.
   ukm::builders::PasswordForm ukm_entry_builder_;
 
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
index b928e2a6..589c89f 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
+++ b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
@@ -21,17 +21,16 @@
 
 namespace {
 
-constexpr char kTestUrl[] = "https://www.example.com/";
+constexpr ukm::SourceId kTestSourceId = 0x1234;
 
 using UkmEntry = ukm::builders::PasswordForm;
 
-// Create a UkmEntryBuilder with a SourceId that is initialized for kTestUrl.
+// Create a UkmEntryBuilder with kTestSourceId.
 scoped_refptr<PasswordFormMetricsRecorder> CreatePasswordFormMetricsRecorder(
     bool is_main_frame_secure,
     ukm::TestUkmRecorder* test_ukm_recorder) {
-  return base::MakeRefCounted<PasswordFormMetricsRecorder>(
-      is_main_frame_secure, test_ukm_recorder,
-      test_ukm_recorder->GetNewSourceID(), GURL(kTestUrl));
+  return base::MakeRefCounted<PasswordFormMetricsRecorder>(is_main_frame_secure,
+                                                           kTestSourceId);
 }
 
 // TODO(crbug.com/738921) Replace this with generalized infrastructure.
@@ -44,7 +43,7 @@
   auto entries = test_ukm_recorder->GetEntriesByName(UkmEntry::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* const entry : entries) {
-    test_ukm_recorder->ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
+    EXPECT_EQ(kTestSourceId, entry->source_id);
     if (expected_count) {
       test_ukm_recorder->ExpectEntryMetric(entry, metric_name, value);
     } else {
@@ -467,7 +466,7 @@
     auto entries = test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
     EXPECT_EQ(1u, entries.size());
     for (const auto* const entry : entries) {
-      test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
+      EXPECT_EQ(kTestSourceId, entry->source_id);
 
       if (test.credential_source_type !=
           metrics_util::CredentialSourceType::kUnknown) {
@@ -532,7 +531,7 @@
     auto entries = test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
     EXPECT_EQ(1u, entries.size());
     for (const auto* const entry : entries) {
-      test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
+      EXPECT_EQ(kTestSourceId, entry->source_id);
       test_ukm_recorder.ExpectEntryMetric(
           entry, test.expected_trigger_metric,
           static_cast<int64_t>(test.expected_metric_value));
@@ -566,7 +565,7 @@
   auto entries = test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* const entry : entries) {
-    test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
+    EXPECT_EQ(kTestSourceId, entry->source_id);
     test_ukm_recorder.ExpectEntryMetric(
         entry, UkmEntry::kSaving_Prompt_InteractionName,
         static_cast<int64_t>(BubbleDismissalReason::kAccepted));
@@ -603,7 +602,7 @@
   auto entries = test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* const entry : entries) {
-    test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
+    EXPECT_EQ(kTestSourceId, entry->source_id);
     test_ukm_recorder.ExpectEntryMetric(
         entry, UkmEntry::kUser_Action_CorrectedUsernameInFormName, 2u);
     test_ukm_recorder.ExpectEntryMetric(
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index 7d45719b..be7423b7 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -238,12 +238,8 @@
   virtual void LogPasswordReuseDetectedEvent() = 0;
 #endif
 
-  // Gets the UKM service associated with this client (for metrics).
-  virtual ukm::UkmRecorder* GetUkmRecorder() = 0;
-
   // Gets a ukm::SourceId that is associated with the WebContents object
-  // and its last committed main frame navigation. Note that the URL binding
-  // has to happen by the caller at a later point.
+  // and its last committed main frame navigation.
   virtual ukm::SourceId GetUkmSourceId() = 0;
 
   // Gets a metrics recorder for the currently committed navigation.
diff --git a/components/password_manager/core/browser/password_manager_metrics_recorder.cc b/components/password_manager/core/browser/password_manager_metrics_recorder.cc
index b92e79a..4ba9a27e 100644
--- a/components/password_manager/core/browser/password_manager_metrics_recorder.cc
+++ b/components/password_manager/core/browser/password_manager_metrics_recorder.cc
@@ -7,6 +7,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "components/autofill/core/common/save_password_progress_logger.h"
 #include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
 #include "url/gurl.h"
 
 // Shorten the name to spare line breaks. The code provides enough context
@@ -15,34 +16,20 @@
 
 namespace password_manager {
 
-// URL Keyed Metrics.
-const char kUkmUserModifiedPasswordField[] = "UserModifiedPasswordField";
-const char kUkmProvisionalSaveFailure[] = "ProvisionalSaveFailure";
-const char kUkmPageLevelUserAction[] = "PageLevelUserAction";
-
 PasswordManagerMetricsRecorder::PasswordManagerMetricsRecorder(
-    ukm::UkmRecorder* ukm_recorder,
     ukm::SourceId source_id,
     const GURL& main_frame_url)
-    : ukm_recorder_(ukm_recorder),
-      source_id_(source_id),
-      main_frame_url_(main_frame_url),
+    : main_frame_url_(main_frame_url),
       ukm_entry_builder_(
-          ukm_recorder
-              ? ukm_recorder->GetEntryBuilder(source_id, "PageWithPassword")
-              : nullptr) {}
+          base::MakeUnique<ukm::builders::PageWithPassword>(source_id)) {}
 
 PasswordManagerMetricsRecorder::PasswordManagerMetricsRecorder(
     PasswordManagerMetricsRecorder&& that) noexcept = default;
 
 PasswordManagerMetricsRecorder::~PasswordManagerMetricsRecorder() {
   if (user_modified_password_field_)
-    RecordUkmMetric(kUkmUserModifiedPasswordField, 1);
-
-  // Bind |main_frame_url_| to |source_id_| directly before sending the content
-  // of |ukm_recorder_| to ensure that the binding has not been purged already.
-  if (ukm_recorder_)
-    ukm_recorder_->UpdateSourceURL(source_id_, main_frame_url_);
+    ukm_entry_builder_->SetUserModifiedPasswordField(1);
+  ukm_entry_builder_->Record(ukm::UkmRecorder::Get());
 }
 
 PasswordManagerMetricsRecorder& PasswordManagerMetricsRecorder::operator=(
@@ -59,7 +46,7 @@
     BrowserSavePasswordProgressLogger* logger) {
   UMA_HISTOGRAM_ENUMERATION("PasswordManager.ProvisionalSaveFailure", failure,
                             MAX_FAILURE_VALUE);
-  RecordUkmMetric(kUkmProvisionalSaveFailure, static_cast<int64_t>(failure));
+  ukm_entry_builder_->SetProvisionalSaveFailure(static_cast<int64_t>(failure));
 
   if (logger) {
     switch (failure) {
@@ -99,13 +86,7 @@
 
 void PasswordManagerMetricsRecorder::RecordPageLevelUserAction(
     PasswordManagerMetricsRecorder::PageLevelUserAction action) {
-  RecordUkmMetric(kUkmPageLevelUserAction, static_cast<int64_t>(action));
-}
-
-void PasswordManagerMetricsRecorder::RecordUkmMetric(const char* metric_name,
-                                                     int64_t value) {
-  if (ukm_entry_builder_)
-    ukm_entry_builder_->AddMetric(metric_name, value);
+  ukm_entry_builder_->SetPageLevelUserAction(static_cast<int64_t>(action));
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_metrics_recorder.h b/components/password_manager/core/browser/password_manager_metrics_recorder.h
index 551f4ebb..1f348f5 100644
--- a/components/password_manager/core/browser/password_manager_metrics_recorder.h
+++ b/components/password_manager/core/browser/password_manager_metrics_recorder.h
@@ -10,27 +10,19 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
 #include "url/gurl.h"
 
 class GURL;
 
+namespace ukm {
+namespace builders {
+class PageWithPassword;
+}
+}  // namespace ukm
+
 namespace password_manager {
 
-// URL Keyed Metrics.
-
-// Records a 1 for every page on which a user has modified the content of a
-// password field - regardless of how many password fields a page contains or
-// the user modifies.
-extern const char kUkmUserModifiedPasswordField[];
-
-// UKM that records a ProvisionalSaveFailure in case the password manager cannot
-// offer to save a credential.
-extern const char kUkmProvisionalSaveFailure[];
-
-// UKM that records a PasswordManagerMetricsRecorder::PageLevelUserAction.
-extern const char kUkmPageLevelUserAction[];
-
 class BrowserSavePasswordProgressLogger;
 
 // The pupose of this class is to record various types of metrics about the
@@ -75,16 +67,8 @@
     kShowAllPasswordsWhileNoneAreSuggested,
   };
 
-  // Records UKM metrics and reports them on destruction. The |source_id| is
-  // (re-)bound to |main_frame_url| shortly before reporting. As such it is
-  // crucial that the |source_id| is never bound to a different URL by another
-  // consumer.  The reason for this late binding is that metrics can be
-  // collected for a WebContents for a long period of time and by the time the
-  // reporting happens, the binding of |source_id| to |main_frame_url| is
-  // already purged.  |ukm_recorder| may be a nullptr, in which case no UKM
-  // metrics are recorded.
-  PasswordManagerMetricsRecorder(ukm::UkmRecorder* ukm_recorder,
-                                 ukm::SourceId source_id,
+  // Records UKM metrics and reports them on destruction.
+  PasswordManagerMetricsRecorder(ukm::SourceId source_id,
                                  const GURL& main_frame_url);
 
   PasswordManagerMetricsRecorder(
@@ -109,24 +93,11 @@
   void RecordPageLevelUserAction(PageLevelUserAction action);
 
  private:
-  // Records a metric into |ukm_entry_builder_| if it is not nullptr.
-  void RecordUkmMetric(const char* metric_name, int64_t value);
-
-  // Recorder to which metrics are sent. Has to outlive this
-  // PasswordManagerMetircsRecorder.
-  ukm::UkmRecorder* ukm_recorder_;
-
-  // A SourceId of |ukm_recorder_|. This id gets bound to |main_frame_url_| on
-  // destruction. It can be shared across multiple metrics recorders as long as
-  // they all bind it to the same URL.
-  ukm::SourceId source_id_;
-
   // URL for which UKMs are reported.
   GURL main_frame_url_;
 
-  // Records URL keyed metrics (UKMs) and submits them on its destruction. May
-  // be a nullptr in which case no recording is expected.
-  std::unique_ptr<ukm::UkmEntryBuilder> ukm_entry_builder_;
+  // Records URL keyed metrics (UKMs) and submits them on its destruction.
+  std::unique_ptr<ukm::builders::PageWithPassword> ukm_entry_builder_;
 
   bool user_modified_password_field_ = false;
 
diff --git a/components/password_manager/core/browser/password_manager_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_manager_metrics_recorder_unittest.cc
index c0be3964..ace6340 100644
--- a/components/password_manager/core/browser/password_manager_metrics_recorder_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_metrics_recorder_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/test/scoped_task_environment.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "components/ukm/ukm_source.h"
-#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -22,12 +22,13 @@
 namespace {
 
 constexpr char kTestUrl[] = "https://www.example.com/";
+constexpr ukm::SourceId kTestSourceId = 0x1234;
+
+using UkmEntry = ukm::builders::PageWithPassword;
 
 // Creates a PasswordManagerMetricsRecorder that reports metrics for kTestUrl.
-PasswordManagerMetricsRecorder CreateMetricsRecorder(
-    ukm::UkmRecorder* ukm_recorder) {
-  return PasswordManagerMetricsRecorder(
-      ukm_recorder, ukm_recorder->GetNewSourceID(), GURL(kTestUrl));
+PasswordManagerMetricsRecorder CreateMetricsRecorder() {
+  return PasswordManagerMetricsRecorder(kTestSourceId, GURL(kTestUrl));
 }
 
 }  // namespace
@@ -36,17 +37,17 @@
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   ukm::TestAutoSetUkmRecorder test_ukm_recorder;
   {
-    PasswordManagerMetricsRecorder recorder(
-        CreateMetricsRecorder(&test_ukm_recorder));
+    PasswordManagerMetricsRecorder recorder(CreateMetricsRecorder());
     recorder.RecordUserModifiedPasswordField();
   }
 
-  const auto& entries = test_ukm_recorder.GetEntriesByName("PageWithPassword");
+  const auto& entries =
+      test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* entry : entries) {
-    test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
-    test_ukm_recorder.ExpectEntryMetric(entry, kUkmUserModifiedPasswordField,
-                                        1);
+    EXPECT_EQ(kTestSourceId, entry->source_id);
+    test_ukm_recorder.ExpectEntryMetric(
+        entry, UkmEntry::kUserModifiedPasswordFieldName, 1);
   }
 }
 
@@ -54,34 +55,32 @@
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   ukm::TestAutoSetUkmRecorder test_ukm_recorder;
   {
-    PasswordManagerMetricsRecorder recorder(
-        CreateMetricsRecorder(&test_ukm_recorder));
+    PasswordManagerMetricsRecorder recorder(CreateMetricsRecorder());
     // Multiple calls should not create more than one entry.
     recorder.RecordUserModifiedPasswordField();
     recorder.RecordUserModifiedPasswordField();
   }
-  const auto& entries = test_ukm_recorder.GetEntriesByName("PageWithPassword");
+  const auto& entries =
+      test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* entry : entries) {
-    test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
-    test_ukm_recorder.ExpectEntryMetric(entry, kUkmUserModifiedPasswordField,
-                                        1);
+    EXPECT_EQ(kTestSourceId, entry->source_id);
+    test_ukm_recorder.ExpectEntryMetric(
+        entry, UkmEntry::kUserModifiedPasswordFieldName, 1);
   }
 }
 
 TEST(PasswordManagerMetricsRecorder, UserModifiedPasswordFieldNotCalled) {
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   ukm::TestAutoSetUkmRecorder test_ukm_recorder;
-  {
-    PasswordManagerMetricsRecorder recorder(
-        CreateMetricsRecorder(&test_ukm_recorder));
-  }
-  const auto& entries = test_ukm_recorder.GetEntriesByName("PageWithPassword");
+  { PasswordManagerMetricsRecorder recorder(CreateMetricsRecorder()); }
+  const auto& entries =
+      test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName);
   EXPECT_EQ(1u, entries.size());
   for (const auto* entry : entries) {
-    test_ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));
-    EXPECT_FALSE(
-        test_ukm_recorder.EntryHasMetric(entry, kUkmUserModifiedPasswordField));
+    EXPECT_EQ(kTestSourceId, entry->source_id);
+    EXPECT_FALSE(test_ukm_recorder.EntryHasMetric(
+        entry, UkmEntry::kUserModifiedPasswordFieldName));
   }
 }
 
diff --git a/components/password_manager/core/browser/stub_password_manager_client.cc b/components/password_manager/core/browser/stub_password_manager_client.cc
index b24baff2..7654e2bc 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.cc
+++ b/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -12,9 +12,7 @@
 namespace password_manager {
 
 StubPasswordManagerClient::StubPasswordManagerClient()
-    : ukm_source_id_(ukm::UkmRecorder::Get()
-                         ? ukm::UkmRecorder::Get()->GetNewSourceID()
-                         : 0) {}
+    : ukm_source_id_(ukm::UkmRecorder::GetNewSourceID()) {}
 
 StubPasswordManagerClient::~StubPasswordManagerClient() {}
 
@@ -92,10 +90,6 @@
 void StubPasswordManagerClient::LogPasswordReuseDetectedEvent() {}
 #endif
 
-ukm::UkmRecorder* StubPasswordManagerClient::GetUkmRecorder() {
-  return ukm::UkmRecorder::Get();
-}
-
 ukm::SourceId StubPasswordManagerClient::GetUkmSourceId() {
   return ukm_source_id_;
 }
@@ -103,8 +97,7 @@
 PasswordManagerMetricsRecorder&
 StubPasswordManagerClient::GetMetricsRecorder() {
   if (!metrics_recorder_) {
-    metrics_recorder_.emplace(GetUkmRecorder(), GetUkmSourceId(),
-                              GetMainFrameURL());
+    metrics_recorder_.emplace(GetUkmSourceId(), GetMainFrameURL());
   }
   return metrics_recorder_.value();
 }
diff --git a/components/password_manager/core/browser/stub_password_manager_client.h b/components/password_manager/core/browser/stub_password_manager_client.h
index 1578d64..cee51f05 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.h
+++ b/components/password_manager/core/browser/stub_password_manager_client.h
@@ -61,7 +61,6 @@
       bool password_field_exists) override;
   void LogPasswordReuseDetectedEvent() override;
 #endif
-  ukm::UkmRecorder* GetUkmRecorder() override;
   ukm::SourceId GetUkmSourceId() override;
   PasswordManagerMetricsRecorder& GetMetricsRecorder() override;
 
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index b0dcae4..9247639 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -84,7 +84,7 @@
 // Control whether users can view and copy passwords. This is only used for
 // mobile, the desktop version of Chrome always allows users to view
 // passwords.
-const base::Feature kViewPasswords = {"view-passwords",
+const base::Feature kViewPasswords = {"ViewPasswords",
                                       base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables the experiment for the password manager to only fill on account
diff --git a/components/policy/content/BUILD.gn b/components/policy/content/BUILD.gn
deleted file mode 100644
index fda6e2f..0000000
--- a/components/policy/content/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/features.gni")
-
-assert(!is_ios, "Policy Throttle should not be referenced on iOS")
-
-source_set("content") {
-  sources = [
-    "policy_blacklist_navigation_throttle.cc",
-    "policy_blacklist_navigation_throttle.h",
-  ]
-
-  deps = [
-    "//base",
-    "//components/keyed_service/content:content",
-    "//components/policy/core/browser",
-    "//components/prefs",
-    "//components/user_prefs:user_prefs",
-    "//content/public/browser",
-    "//net",
-  ]
-}
diff --git a/components/policy/content/DEPS b/components/policy/content/DEPS
deleted file mode 100644
index 3b9caa8..0000000
--- a/components/policy/content/DEPS
+++ /dev/null
@@ -1,8 +0,0 @@
-include_rules = [
-  "+content/public",
-  "+components/policy",
-  "+components/keyed_service",
-  "+components/prefs",
-  "+components/user_prefs",
-  "+net/base",
-]
diff --git a/components/policy/content/policy_blacklist_navigation_throttle.cc b/components/policy/content/policy_blacklist_navigation_throttle.cc
deleted file mode 100644
index d53091d3..0000000
--- a/components/policy/content/policy_blacklist_navigation_throttle.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/policy/content/policy_blacklist_navigation_throttle.h"
-
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/user_prefs/user_prefs.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/navigation_handle.h"
-
-PolicyBlacklistService::PolicyBlacklistService(
-    std::unique_ptr<policy::URLBlacklistManager> url_blacklist_manager)
-    : url_blacklist_manager_(std::move(url_blacklist_manager)) {}
-
-PolicyBlacklistService::~PolicyBlacklistService() {}
-
-bool PolicyBlacklistService::IsURLBlocked(const GURL& url) const {
-  return url_blacklist_manager_->IsURLBlocked(url);
-}
-
-policy::URLBlacklist::URLBlacklistState
-PolicyBlacklistService::GetURLBlacklistState(const GURL& url) const {
-  return url_blacklist_manager_->GetURLBlacklistState(url);
-}
-
-// static
-PolicyBlacklistFactory* PolicyBlacklistFactory::GetInstance() {
-  return base::Singleton<PolicyBlacklistFactory>::get();
-}
-
-// static
-PolicyBlacklistService* PolicyBlacklistFactory::GetForProfile(
-    content::BrowserContext* context) {
-  return static_cast<PolicyBlacklistService*>(
-      GetInstance()->GetServiceForBrowserContext(context, true));
-}
-
-PolicyBlacklistFactory::PolicyBlacklistFactory()
-    : BrowserContextKeyedServiceFactory(
-          "PolicyBlacklist",
-          BrowserContextDependencyManager::GetInstance()) {}
-
-PolicyBlacklistFactory::~PolicyBlacklistFactory() {}
-
-void PolicyBlacklistFactory::SetBlacklistOverride(
-    policy::URLBlacklistManager::OverrideBlacklistCallback callback) {
-  override_blacklist_ = callback;
-}
-
-KeyedService* PolicyBlacklistFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  PrefService* pref_service = user_prefs::UserPrefs::Get(context);
-  auto url_blacklist_manager = std::make_unique<policy::URLBlacklistManager>(
-      pref_service, override_blacklist_);
-  return new PolicyBlacklistService(std::move(url_blacklist_manager));
-}
-
-PolicyBlacklistNavigationThrottle::PolicyBlacklistNavigationThrottle(
-    content::NavigationHandle* navigation_handle,
-    content::BrowserContext* context)
-    : NavigationThrottle(navigation_handle) {
-  blacklist_service_ = PolicyBlacklistFactory::GetForProfile(context);
-}
-
-PolicyBlacklistNavigationThrottle::~PolicyBlacklistNavigationThrottle() {}
-
-content::NavigationThrottle::ThrottleCheckResult
-PolicyBlacklistNavigationThrottle::WillStartRequest() {
-  if (blacklist_service_ &&
-      blacklist_service_->IsURLBlocked(navigation_handle()->GetURL())) {
-    return ThrottleCheckResult(BLOCK_REQUEST,
-                               net::ERR_BLOCKED_BY_ADMINISTRATOR);
-  }
-  return PROCEED;
-}
-
-const char* PolicyBlacklistNavigationThrottle::GetNameForLogging() {
-  return "PolicyBlacklistNavigationThrottle";
-}
diff --git a/components/policy/content/policy_blacklist_navigation_throttle.h b/components/policy/content/policy_blacklist_navigation_throttle.h
deleted file mode 100644
index 6ff6194b..0000000
--- a/components/policy/content/policy_blacklist_navigation_throttle.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_POLICY_CONTENT_POLICY_BLACKLIST_NAVIGATION_THROTTLE_H_
-#define COMPONENTS_POLICY_CONTENT_POLICY_BLACKLIST_NAVIGATION_THROTTLE_H_
-
-#include "base/memory/singleton.h"
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-#include "components/keyed_service/core/keyed_service.h"
-#include "components/policy/core/browser/url_blacklist_manager.h"
-#include "content/public/browser/navigation_throttle.h"
-
-// PolicyBlacklistService and PolicyBlacklistFactory provide a way for
-// us to access URLBlacklistManager, a policy block list service based on
-// the Preference Service. The URLBlacklistManager responses to permission
-// changes and is per Profile.  From the PolicyBlacklistNavigationThrottle,
-// we access this service to provide information about what we should block.
-class PolicyBlacklistService : public KeyedService {
- public:
-  explicit PolicyBlacklistService(
-      std::unique_ptr<policy::URLBlacklistManager> url_blacklist_manager);
-  ~PolicyBlacklistService() override;
-
-  bool IsURLBlocked(const GURL& url) const;
-  policy::URLBlacklist::URLBlacklistState GetURLBlacklistState(
-      const GURL& url) const;
-
- private:
-  std::unique_ptr<policy::URLBlacklistManager> url_blacklist_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(PolicyBlacklistService);
-};
-
-class PolicyBlacklistFactory : public BrowserContextKeyedServiceFactory {
- public:
-  static PolicyBlacklistFactory* GetInstance();
-  static PolicyBlacklistService* GetForProfile(
-      content::BrowserContext* context);
-
-  // Sets the OverrideBlacklistCallback for the underlying URLBlacklistManager.
-  // Must be called before BuildServiceInstanceFor().
-  void SetBlacklistOverride(
-      policy::URLBlacklistManager::OverrideBlacklistCallback);
-
- private:
-  PolicyBlacklistFactory();
-  ~PolicyBlacklistFactory() override;
-  friend struct base::DefaultSingletonTraits<PolicyBlacklistFactory>;
-
-  // BrowserContextKeyedServiceFactory implementation
-  KeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* context) const override;
-
-  policy::URLBlacklistManager::OverrideBlacklistCallback override_blacklist_;
-
-  DISALLOW_COPY_AND_ASSIGN(PolicyBlacklistFactory);
-};
-
-// PolicyBlacklistNavigationThrottle provides a simple way to block a navigation
-// based on the URLBlacklistManager.
-class PolicyBlacklistNavigationThrottle : public content::NavigationThrottle {
- public:
-  PolicyBlacklistNavigationThrottle(
-      content::NavigationHandle* navigation_handle,
-      content::BrowserContext* context);
-  ~PolicyBlacklistNavigationThrottle() override;
-
-  // NavigationThrottle overrides.
-  ThrottleCheckResult WillStartRequest() override;
-  const char* GetNameForLogging() override;
-
- private:
-  PolicyBlacklistService* blacklist_service_;
-  DISALLOW_COPY_AND_ASSIGN(PolicyBlacklistNavigationThrottle);
-};
-
-#endif  // COMPONENTS_POLICY_CONTENT_POLICY_BLACKLIST_NAVIGATION_THROTTLE_H_
diff --git a/components/policy/core/browser/url_blacklist_manager.cc b/components/policy/core/browser/url_blacklist_manager.cc
index a892193..21a2802 100644
--- a/components/policy/core/browser/url_blacklist_manager.cc
+++ b/components/policy/core/browser/url_blacklist_manager.cc
@@ -19,8 +19,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/task_runner_util.h"
-#include "base/task_scheduler/post_task.h"
-#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/values.h"
 #include "base/values.h"
 #include "components/policy/core/common/policy_pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
@@ -428,17 +428,17 @@
 
 URLBlacklistManager::URLBlacklistManager(
     PrefService* pref_service,
+    const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
     OverrideBlacklistCallback override_blacklist)
     : pref_service_(pref_service),
+      background_task_runner_(background_task_runner),
+      io_task_runner_(io_task_runner),
       override_blacklist_(override_blacklist),
+      ui_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       blacklist_(new URLBlacklist),
-      ui_weak_ptr_factory_(this) {
-  // This class assumes that it is created on the same thread that
-  // |pref_service_| lives on.
-  ui_task_runner_ = base::SequencedTaskRunnerHandle::Get();
-  background_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
-      {base::MayBlock(), base::TaskPriority::BACKGROUND});
-
+      ui_weak_ptr_factory_(this),
+      io_weak_ptr_factory_(this) {
   pref_change_registrar_.Init(pref_service_);
   base::Closure callback = base::Bind(&URLBlacklistManager::ScheduleUpdate,
                                       base::Unretained(this));
@@ -452,11 +452,16 @@
     Update();
 }
 
-URLBlacklistManager::~URLBlacklistManager() {
+void URLBlacklistManager::ShutdownOnUIThread() {
   DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
+  // Cancel any pending updates, and stop listening for pref change updates.
+  ui_weak_ptr_factory_.InvalidateWeakPtrs();
   pref_change_registrar_.RemoveAll();
 }
 
+URLBlacklistManager::~URLBlacklistManager() {
+}
+
 void URLBlacklistManager::ScheduleUpdate() {
   DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
   // Cancel pending updates, if any. This can happen if two preferences that
@@ -478,24 +483,39 @@
   std::unique_ptr<base::ListValue> allow(
       pref_service_->GetList(policy_prefs::kUrlWhitelist)->DeepCopy());
 
-  // The URLBlacklist is built on a background task. Once it's ready, it is
-  // passed to the URLBlacklistManager on the same thread as the
-  // background_task_runner_.
+  // Go through the IO thread to grab a WeakPtr to |this|. This is safe from
+  // here, since this task will always execute before a potential deletion of
+  // ProfileIOData on IO.
+  io_task_runner_->PostTask(FROM_HERE,
+                            base::Bind(&URLBlacklistManager::UpdateOnIO,
+                                       base::Unretained(this),
+                                       base::Passed(&block),
+                                       base::Passed(&allow)));
+}
+
+void URLBlacklistManager::UpdateOnIO(std::unique_ptr<base::ListValue> block,
+                                     std::unique_ptr<base::ListValue> allow) {
+  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
+  // The URLBlacklist is built on a worker thread. Once it's ready, it is passed
+  // to the URLBlacklistManager on IO.
   base::PostTaskAndReplyWithResult(
-      background_task_runner_.get(), FROM_HERE,
-      base::BindOnce(&BuildBlacklist, std::move(block), std::move(allow)),
-      base::BindOnce(&URLBlacklistManager::SetBlacklist,
-                     ui_weak_ptr_factory_.GetWeakPtr()));
+      background_task_runner_.get(),
+      FROM_HERE,
+      base::Bind(&BuildBlacklist,
+                 base::Passed(&block),
+                 base::Passed(&allow)),
+      base::Bind(&URLBlacklistManager::SetBlacklist,
+                 io_weak_ptr_factory_.GetWeakPtr()));
 }
 
 void URLBlacklistManager::SetBlacklist(
     std::unique_ptr<URLBlacklist> blacklist) {
-  DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
   blacklist_ = std::move(blacklist);
 }
 
 bool URLBlacklistManager::IsURLBlocked(const GURL& url) const {
-  DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
   // Ignore blob scheme for two reasons:
   // 1) PlzNavigate uses it to deliver the response to the renderer.
   // 2) A whitelisted page can use blob URLs internally.
@@ -504,13 +524,13 @@
 
 URLBlacklist::URLBlacklistState URLBlacklistManager::GetURLBlacklistState(
     const GURL& url) const {
-  DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
   return blacklist_->GetURLBlacklistState(url);
 }
 
 bool URLBlacklistManager::ShouldBlockRequestForFrame(const GURL& url,
                                                      int* reason) const {
-  DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
 
   bool block = false;
   if (override_blacklist_.Run(url, &block, reason))
diff --git a/components/policy/core/browser/url_blacklist_manager.h b/components/policy/core/browser/url_blacklist_manager.h
index d46e4e436..6cebaa0c 100644
--- a/components/policy/core/browser/url_blacklist_manager.h
+++ b/components/policy/core/browser/url_blacklist_manager.h
@@ -123,6 +123,22 @@
 };
 
 // Tracks the blacklist policies for a given profile, and updates it on changes.
+//
+// This class interacts with both the UI thread, where notifications of pref
+// changes are received from, and the IO thread, which owns it (in the
+// ProfileIOData) and checks for blacklisted URLs (from ChromeNetworkDelegate).
+//
+// It must be constructed on the UI thread, to set up |ui_weak_ptr_factory_| and
+// the prefs listeners.
+//
+// ShutdownOnUIThread must be called from UI before destruction, to release
+// the prefs listeners on the UI thread. This is done from ProfileIOData.
+//
+// Update tasks from the UI thread can post safely to the IO thread, since the
+// destruction order of Profile and ProfileIOData guarantees that if this
+// exists in UI, then a potential destruction on IO will come after any task
+// posted to IO from that method on UI. This is used to go through IO before
+// the actual update starts, and grab a WeakPtr.
 class POLICY_EXPORT URLBlacklistManager {
  public:
   // Returns true if the blacklist should be overridden for |url| and sets
@@ -132,11 +148,21 @@
       OverrideBlacklistCallback;
 
   // Must be constructed on the UI thread.
-  URLBlacklistManager(PrefService* pref_service,
-                      OverrideBlacklistCallback override_blacklist);
+  // |background_task_runner| is used to build the blacklist in a background
+  // thread.
+  // |io_task_runner| must be backed by the IO thread.
+  URLBlacklistManager(
+      PrefService* pref_service,
+      const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
+      OverrideBlacklistCallback override_blacklist);
   virtual ~URLBlacklistManager();
 
-  // Returns true if |url| is blocked by the current blacklist.
+  // Must be called on the UI thread, before destruction.
+  void ShutdownOnUIThread();
+
+  // Returns true if |url| is blocked by the current blacklist. Must be called
+  // from the IO thread.
   bool IsURLBlocked(const GURL& url) const;
 
   URLBlacklist::URLBlacklistState GetURLBlacklistState(const GURL& url) const;
@@ -150,9 +176,10 @@
   //
   // |reason| is populated with the exact reason for blocking the url if and
   // only if the return value is true otherwise it is left untouched.
+  // Must be called from the IO thread.
   bool ShouldBlockRequestForFrame(const GURL& url, int* reason) const;
 
-  // Replaces the current blacklist.
+  // Replaces the current blacklist. Must be called on the IO thread.
   // Virtual for testing.
   virtual void SetBlacklist(std::unique_ptr<URLBlacklist> blacklist);
 
@@ -168,7 +195,16 @@
   // Virtual for testing.
   virtual void Update();
 
+  // Starts the blacklist update on the IO thread, using the filters in
+  // |block| and |allow|. Protected for testing.
+  void UpdateOnIO(std::unique_ptr<base::ListValue> block,
+                  std::unique_ptr<base::ListValue> allow);
+
  private:
+  // ---------
+  // UI thread
+  // ---------
+
   // Used to track the policies and update the blacklist on changes.
   PrefChangeRegistrar pref_change_registrar_;
   PrefService* pref_service_;  // Weak.
@@ -176,15 +212,17 @@
   // Used to post tasks to a background thread.
   scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
 
+  // Used to post tasks to the IO thread.
+  scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
+
   // Used to optionally skip blacklisting for some URLs.
   OverrideBlacklistCallback override_blacklist_;
 
-  // Used to schedule tasks on the main loop to avoid rebuilding the blocklist
-  // multiple times during a message loop process. This can happen if two
-  // preferences that change the blacklist are updated in one message loop
-  // cycle.  In addition, we use this task runner to ensure that the
-  // URLBlocklistManager is only access from the thread call the constructor for
-  // data accesses.
+  // ---------
+  // IO thread
+  // ---------
+
+  // Used to post tasks to the UI thread.
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
 
   // The current blacklist.
@@ -193,6 +231,9 @@
   // Used to post update tasks to the UI thread.
   base::WeakPtrFactory<URLBlacklistManager> ui_weak_ptr_factory_;
 
+  // Used to get |weak_ptr_| to self on the IO thread.
+  base::WeakPtrFactory<URLBlacklistManager> io_weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(URLBlacklistManager);
 };
 
diff --git a/components/policy/core/browser/url_blacklist_manager_unittest.cc b/components/policy/core/browser/url_blacklist_manager_unittest.cc
index c1cfbb33..9b5f783 100644
--- a/components/policy/core/browser/url_blacklist_manager_unittest.cc
+++ b/components/policy/core/browser/url_blacklist_manager_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "components/policy/core/common/policy_pref_names.h"
@@ -39,6 +38,8 @@
  public:
   explicit TestingURLBlacklistManager(PrefService* pref_service)
       : URLBlacklistManager(pref_service,
+                            base::ThreadTaskRunnerHandle::Get(),
+                            base::ThreadTaskRunnerHandle::Get(),
                             base::Bind(OverrideBlacklistForURL)),
         update_called_(0),
         set_blacklist_called_(false) {}
@@ -48,6 +49,14 @@
   // Make this method public for testing.
   using URLBlacklistManager::ScheduleUpdate;
 
+  // Makes a direct call to UpdateOnIO during tests.
+  void UpdateOnIOForTesting() {
+    std::unique_ptr<base::ListValue> block(new base::ListValue);
+    block->AppendString("example.com");
+    std::unique_ptr<base::ListValue> allow(new base::ListValue);
+    URLBlacklistManager::UpdateOnIO(std::move(block), std::move(allow));
+  }
+
   // URLBlacklistManager overrides:
   void SetBlacklist(std::unique_ptr<URLBlacklist> blacklist) override {
     set_blacklist_called_ = true;
@@ -77,19 +86,21 @@
     pref_service_.registry()->RegisterListPref(policy_prefs::kUrlBlacklist);
     pref_service_.registry()->RegisterListPref(policy_prefs::kUrlWhitelist);
     blacklist_manager_.reset(new TestingURLBlacklistManager(&pref_service_));
-    scoped_task_environment_.RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
   void TearDown() override {
     if (blacklist_manager_.get())
-      scoped_task_environment_.RunUntilIdle();
+      blacklist_manager_->ShutdownOnUIThread();
+    base::RunLoop().RunUntilIdle();
+    // Delete |blacklist_manager_| while |io_thread_| is mapping IO to
+    // |loop_|.
     blacklist_manager_.reset();
   }
 
+  base::MessageLoopForIO loop_;
   TestingPrefServiceSimple pref_service_;
   std::unique_ptr<TestingURLBlacklistManager> blacklist_manager_;
-
-  base::test::ScopedTaskEnvironment scoped_task_environment_;
 };
 
 // Parameters for the FilterToComponents test.
@@ -216,8 +227,10 @@
   list->AppendString("example.com");
   pref_service_.SetManagedPref(policy_prefs::kUrlBlacklist, std::move(list));
   auto manager = base::MakeUnique<URLBlacklistManager>(
-      &pref_service_, URLBlacklistManager::OverrideBlacklistCallback());
-  scoped_task_environment_.RunUntilIdle();
+      &pref_service_, base::ThreadTaskRunnerHandle::Get(),
+      base::ThreadTaskRunnerHandle::Get(),
+      URLBlacklistManager::OverrideBlacklistCallback());
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(URLBlacklist::URL_IN_BLACKLIST,
             manager->GetURLBlacklistState(GURL("http://example.com")));
 }
@@ -227,8 +240,10 @@
   list->AppendString("example.com");
   pref_service_.SetManagedPref(policy_prefs::kUrlWhitelist, std::move(list));
   auto manager = base::MakeUnique<URLBlacklistManager>(
-      &pref_service_, URLBlacklistManager::OverrideBlacklistCallback());
-  scoped_task_environment_.RunUntilIdle();
+      &pref_service_, base::ThreadTaskRunnerHandle::Get(),
+      base::ThreadTaskRunnerHandle::Get(),
+      URLBlacklistManager::OverrideBlacklistCallback());
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(URLBlacklist::URL_IN_WHITELIST,
             manager->GetURLBlacklistState(GURL("http://example.com")));
 }
@@ -242,11 +257,45 @@
                                std::move(blacklist));
   pref_service_.SetManagedPref(policy_prefs::kUrlBlacklist,
                                std::move(whitelist));
-  scoped_task_environment_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, blacklist_manager_->update_called());
 }
 
+TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask0) {
+  // Post an update task to the UI thread.
+  blacklist_manager_->ScheduleUpdate();
+  // Shutdown comes before the task is executed.
+  blacklist_manager_->ShutdownOnUIThread();
+  blacklist_manager_.reset();
+  // Run the task after shutdown and deletion.
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask1) {
+  // Post an update task.
+  blacklist_manager_->ScheduleUpdate();
+  // Shutdown comes before the task is executed.
+  blacklist_manager_->ShutdownOnUIThread();
+  // Run the task after shutdown, but before deletion.
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0, blacklist_manager_->update_called());
+  blacklist_manager_.reset();
+  base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(URLBlacklistManagerTest, ShutdownWithPendingTask2) {
+  // This posts a task to the FILE thread.
+  blacklist_manager_->UpdateOnIOForTesting();
+  // But shutdown happens before it is done.
+  blacklist_manager_->ShutdownOnUIThread();
+
+  EXPECT_FALSE(blacklist_manager_->set_blacklist_called());
+  blacklist_manager_.reset();
+  base::RunLoop().RunUntilIdle();
+}
+
 INSTANTIATE_TEST_CASE_P(
     URLBlacklistFilterToComponentsTestInstance,
     URLBlacklistFilterToComponentsTest,
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index bd9a470..59f54214c 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -146,7 +146,7 @@
 #   persistent IDs for all fields (but not for groups!) are needed. These are
 #   specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
 #   because doing so would break the deployed wire format!
-#   For your editing convenience: highest ID currently used: 403
+#   For your editing convenience: highest ID currently used: 404
 #   And don't forget to also update the EnterprisePolicies enum of
 #   histograms.xml (run 'python tools/metrics/histograms/update_policies.py').
 #
@@ -10767,7 +10767,28 @@
 
       If this policy is not set, or the value after substitution is not a valid hostname, no hostname will be set in DHCP request. '''
     },
+    {
+      'name': 'AbusiveExperienceInterventionEnforce',
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome.*:65-', 'chrome_os:65-'],
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': True,
+      },
+      'example_value': True,
+      'id': 404,
+      'caption': '''Abusive Experience Intervention Enforce''',
+      'tags': [],
+      'desc': '''Allows you to set whether sites with abusive experiences should be prevented from opening new windows or tabs.
+
+      If this policy is set to True, sites with abusive experiences will be prevented from opening new windows or tabs.
+      However this behavior will not trigger if SafeBrowsingEnabled policy is set to False.
+      If this policy is set to False, sites with abusive experiences will be allowed to open new windows or tabs.
+      If this policy is left not set, True will be used.''',
+    },
   ],
+
   'messages': {
     # Messages that are not associated to any policies.
     'win_supported_winxpsp2': {
diff --git a/components/previews/content/previews_io_data.cc b/components/previews/content/previews_io_data.cc
index 7980750e1..9d5ed7a6 100644
--- a/components/previews/content/previews_io_data.cc
+++ b/components/previews/content/previews_io_data.cc
@@ -207,7 +207,7 @@
     PreviewsType type,
     net::EffectiveConnectionType effective_connection_type_threshold,
     const std::vector<std::string>& host_blacklist_from_server) const {
-  if (!request.url().has_host()) {
+  if (!request.url().has_host() || !PreviewsUserData::GetData(request)) {
     // Don't capture UMA on this case, as it is not important and can happen
     // when navigating to files on disk, etc.
     return false;
diff --git a/components/search/OWNERS b/components/search/OWNERS
index 718b61f..bad91db 100644
--- a/components/search/OWNERS
+++ b/components/search/OWNERS
@@ -1,4 +1,5 @@
 treib@chromium.org
+sfiera@chromium.org
 
 # Original implementors of most of the code, but not active in Chromium anymore:
 # - jered@chromium.org
diff --git a/components/security_state/content/content_utils.cc b/components/security_state/content/content_utils.cc
index e76a210..042b4b1 100644
--- a/components/security_state/content/content_utils.cc
+++ b/components/security_state/content/content_utils.cc
@@ -83,11 +83,18 @@
 void ExplainSafeBrowsingSecurity(
     const security_state::SecurityInfo& security_info,
     content::SecurityStyleExplanations* security_style_explanations) {
-  if (security_info.malicious_content_status !=
+  if (security_info.malicious_content_status ==
       security_state::MALICIOUS_CONTENT_STATUS_NONE) {
-    security_style_explanations->summary =
-        l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING);
+    return;
   }
+  // Override the main summary for the page.
+  security_style_explanations->summary =
+      l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING);
+  // Add a bullet describing the issue.
+  content::SecurityStyleExplanation explanation(
+      l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING_SUMMARY),
+      l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING_DESCRIPTION));
+  security_style_explanations->insecure_explanations.push_back(explanation);
 }
 
 void ExplainCertificateSecurity(
diff --git a/components/security_state/content/content_utils_unittest.cc b/components/security_state/content/content_utils_unittest.cc
index fc4b0df7..8e78e45a4 100644
--- a/components/security_state/content/content_utils_unittest.cc
+++ b/components/security_state/content/content_utils_unittest.cc
@@ -575,6 +575,21 @@
   EXPECT_EQ(0u, explanations.insecure_explanations.size());
 }
 
+// Tests that malicious safe browsing data in SecurityInfo causes an insecure
+// explanation to be set.
+TEST(SecurityStateContentUtilsTest, SafeBrowsingExplanation) {
+  security_state::SecurityInfo security_info;
+  security_info.cert_status = 0;
+  security_info.scheme_is_cryptographic = true;
+  security_info.malicious_content_status =
+      security_state::MALICIOUS_CONTENT_STATUS_MALWARE;
+  security_info.content_with_cert_errors_status =
+      security_state::CONTENT_STATUS_NONE;
+  content::SecurityStyleExplanations explanations;
+  GetSecurityStyle(security_info, &explanations);
+  EXPECT_EQ(1u, explanations.insecure_explanations.size());
+}
+
 // Tests that an explanation using the shorter constructor sets the correct
 // default values for other fields.
 TEST(SecurityStateContentUtilsTest, DefaultSecurityStyleExplanation) {
diff --git a/components/security_state_strings.grdp b/components/security_state_strings.grdp
index d38b26d..27601520 100644
--- a/components/security_state_strings.grdp
+++ b/components/security_state_strings.grdp
@@ -19,9 +19,15 @@
   <message name="IDS_EDITED_NONSECURE_DESCRIPTION" desc="Description of a security problem where the site is non-secure (HTTP) and user has entered data in a form field." translateable="false">
     Data was entered in a text field on a non-secure page. A warning has been added to the URL bar.
   </message>
-  <message name="IDS_SAFEBROWSING_WARNING" desc="Summary phrase for a security problem where the site is deemed unsafe by the SafeBrowsing service." translateable="false">
+  <message name="IDS_SAFEBROWSING_WARNING" desc="Main summary for page when it has been deemed unsafe by the SafeBrowsing service." translateable="false">
     This page is dangerous (flagged by Google Safe Browsing).
   </message>
+  <message name="IDS_SAFEBROWSING_WARNING_SUMMARY" desc="Summary phrase for a security problem where the site is deemed unsafe by the SafeBrowsing service." translateable="false">
+    Flagged by Google Safe Browsing
+  </message>
+  <message name="IDS_SAFEBROWSING_WARNING_DESCRIPTION" desc="Description of a security problem where the site is deemed unsafe by the SafeBrowsing service." translateable="false">
+    To check this page's status, visit g.co/safebrowsingstatus.
+  </message>
   <message name="IDS_SHA1" desc="Summary phrase for a security problem where the site's certificate chain contains a SHA1 signature." translateable="false">
     SHA-1 certificate
   </message>
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn
index 6835875..bd931ba 100644
--- a/components/signin/core/browser/android/BUILD.gn
+++ b/components/signin/core/browser/android/BUILD.gn
@@ -68,6 +68,5 @@
   java_files = [
     "javatests/src/org/chromium/components/signin/test/util/AccountHolder.java",
     "javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java",
-    "javatests/src/org/chromium/components/signin/test/util/SimpleFuture.java",
   ]
 }
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
index f0566e0..c5a7198 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
+++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
@@ -8,20 +8,17 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.UiThreadTestRule;
 
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ProfileDataSource;
 import org.chromium.components.signin.test.util.AccountHolder;
 import org.chromium.components.signin.test.util.FakeAccountManagerDelegate;
-import org.chromium.components.signin.test.util.SimpleFuture;
 
 /**
  * Test class for {@link AccountManagerFacade}.
@@ -32,7 +29,7 @@
     public UiThreadTestRule mRule = new UiThreadTestRule();
 
     private FakeAccountManagerDelegate mDelegate;
-    private AccountManagerFacade mHelper;
+    private AccountManagerFacade mFacade;
 
     @Before
     public void setUp() throws Exception {
@@ -41,12 +38,7 @@
         Assert.assertFalse(mDelegate.isRegisterObserversCalled());
         AccountManagerFacade.overrideAccountManagerFacadeForTests(mDelegate);
         Assert.assertTrue(mDelegate.isRegisterObserversCalled());
-        mHelper = AccountManagerFacade.get();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        AccountManagerFacade.resetAccountManagerFacadeForTests();
+        mFacade = AccountManagerFacade.get();
     }
 
     @Test
@@ -54,9 +46,9 @@
     public void testCanonicalAccount() {
         addTestAccount("test@gmail.com");
 
-        Assert.assertTrue(hasAccountForName("test@gmail.com"));
-        Assert.assertTrue(hasAccountForName("Test@gmail.com"));
-        Assert.assertTrue(hasAccountForName("te.st@gmail.com"));
+        Assert.assertTrue(mFacade.hasAccountForName("test@gmail.com"));
+        Assert.assertTrue(mFacade.hasAccountForName("Test@gmail.com"));
+        Assert.assertTrue(mFacade.hasAccountForName("te.st@gmail.com"));
     }
 
     // If this test starts flaking, please re-open crbug.com/568636 and make sure there is some sort
@@ -66,10 +58,10 @@
     public void testNonCanonicalAccount() {
         addTestAccount("test.me@gmail.com");
 
-        Assert.assertTrue(hasAccountForName("test.me@gmail.com"));
-        Assert.assertTrue(hasAccountForName("testme@gmail.com"));
-        Assert.assertTrue(hasAccountForName("Testme@gmail.com"));
-        Assert.assertTrue(hasAccountForName("te.st.me@gmail.com"));
+        Assert.assertTrue(mFacade.hasAccountForName("test.me@gmail.com"));
+        Assert.assertTrue(mFacade.hasAccountForName("testme@gmail.com"));
+        Assert.assertTrue(mFacade.hasAccountForName("Testme@gmail.com"));
+        Assert.assertTrue(mFacade.hasAccountForName("te.st.me@gmail.com"));
     }
 
     @Test
@@ -100,19 +92,4 @@
         mDelegate.addAccountHolderBlocking(holder);
         return account;
     }
-
-    private boolean hasAccountForName(final String accountName) {
-        final SimpleFuture<Boolean> result = new SimpleFuture<Boolean>();
-        ThreadUtils.postOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mHelper.hasAccountForName(accountName, result.createCallback());
-            }
-        });
-        try {
-            return result.get();
-        } catch (InterruptedException e) {
-            throw new RuntimeException("Exception occurred while waiting for future", e);
-        }
-    }
 }
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/SimpleFuture.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/SimpleFuture.java
deleted file mode 100644
index 0a157e3..0000000
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/SimpleFuture.java
+++ /dev/null
@@ -1,80 +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.
-
-package org.chromium.components.signin.test.util;
-
-import org.chromium.base.Callback;
-
-/**
- * A simple tool to make waiting for the result of an asynchronous operation easy.
- *
- * This class is thread-safe; the result can be provided and retrieved on any thread.
- *
- * Example usage:
- *
- *    final SimpleFuture<Integer> future = new SimpleFuture<Integer>();
- *    getValueAsynchronously(new Callback<Integer>() {
- *        public void onResult(Integer result) {
- *            // Do some other work...
- *            future.provide(result);
- *        }
- *    }
- *    int value = future.get();
- *
- * Or, if your callback doesn't need to do anything but provide the value:
- *
- *    SimpleFuture<Integer> result = new SimpleFuture<Integer>();
- *    getValueAsynchronously(result.createCallback());
- *    int value = result.get();
- *
- * @param <V> The type of the value this future will return.
- */
-public class SimpleFuture<V> {
-    private static final int GET_TIMEOUT_MS = 10000;
-
-    private final Object mLock = new Object();
-    private boolean mHasResult = false;
-    private V mResult;
-
-    /**
-     * Provide the result value of this future for get() to return.
-     *
-     * Any calls after the first are ignored.
-     */
-    public void provide(V result) {
-        synchronized (mLock) {
-            if (mHasResult) {
-                // You can only provide a result once.
-                return;
-            }
-            mHasResult = true;
-            mResult = result;
-            mLock.notifyAll();
-        }
-    }
-
-    /**
-     * Get the value of this future, or block until it's available.
-     */
-    public V get() throws InterruptedException {
-        synchronized (mLock) {
-            while (!mHasResult) {
-                mLock.wait(GET_TIMEOUT_MS);
-            }
-            return mResult;
-        }
-    }
-
-    /**
-     * Helper function to create a {@link Callback} that will provide its result.
-     */
-    public Callback<V> createCallback() {
-        return new Callback<V>() {
-            @Override
-            public void onResult(V result) {
-                provide(result);
-            }
-        };
-    }
-}
diff --git a/components/subresource_filter/content/browser/content_ruleset_service_unittest.cc b/components/subresource_filter/content/browser/content_ruleset_service_unittest.cc
index 01bd24f..9cbabb66 100644
--- a/components/subresource_filter/content/browser/content_ruleset_service_unittest.cc
+++ b/components/subresource_filter/content/browser/content_ruleset_service_unittest.cc
@@ -120,7 +120,9 @@
   void AssertSetRulesetForProcessMessageWithContent(
       const IPC::Message* message,
       const std::string& expected_contents) {
-    ASSERT_EQ(SubresourceFilterMsg_SetRulesetForProcess::ID, message->type());
+    ASSERT_EQ(
+        static_cast<uint32_t>(SubresourceFilterMsg_SetRulesetForProcess::ID),
+        message->type());
     base::File ruleset_file = ExtractRulesetFromMessage(message);
     ASSERT_TRUE(ruleset_file.IsValid());
     ASSERT_EQ(expected_contents, ReadFileContents(&ruleset_file));
diff --git a/components/test/data/autofill/autofill_unowned_address_checkout.html b/components/test/data/autofill/autofill_unowned_address_checkout.html
new file mode 100644
index 0000000..afb457cc
--- /dev/null
+++ b/components/test/data/autofill/autofill_unowned_address_checkout.html
@@ -0,0 +1,19 @@
+  Name: <input type="text" name="name" id="profile_autofill_name"><br>
+  Address: <input type="text" name="address"><br>
+  City: <input type="text" name="city"><br>
+  State: <select name="state">
+    <option value="CA">CA</option>
+    <option value="MA">MA</option>
+    <option value="NY">NY</option>
+    <option value="MD">MD</option>
+    <option value="OR">OR</option>
+    <option value="OH">OH</option>
+    <option value="IL">IL</option>
+    <option value="DC">DC</option>
+  </select> <br>
+  Zip: <input name="zip" id="form_zip"> <br>
+  Country: <input name="country" id="form_country"> <br>
+  Email: <input name="email" id="form_email"> <br>
+  Phone: <input name="phone" id="form_phone"> <br>
+  <input type="reset" value="Reset">
+  <input type="submit" value="Submit" id="profile_submit">
\ No newline at end of file
diff --git a/components/test/data/autofill/autofill_unowned_credit_card_checkout.html b/components/test/data/autofill/autofill_unowned_credit_card_checkout.html
new file mode 100644
index 0000000..12bc2a8b
--- /dev/null
+++ b/components/test/data/autofill/autofill_unowned_credit_card_checkout.html
@@ -0,0 +1,38 @@
+Name on card: <input autofocus="" type="text" name="name" id="credit_card_name"><br>
+Credit card number: <input type="text" name="CCNo" id="credit_card_number"><br>
+Expiry Date: <select name="CCExpiresMonth">
+  <option value="01">01</option>
+  <option value="02">02</option>
+  <option value="03">03</option>
+  <option value="04">04</option>
+  <option value="05">05</option>
+  <option value="06">06</option>
+  <option value="07">07</option>
+  <option value="08">08</option>
+  <option value="09">09</option>
+  <option value="10">10</option>
+  <option value="11">11</option>
+  <option value="12">12</option>
+</select>
+/
+<select name="CCExpiresYear">
+    <option value="2010">2010</option>
+    <option value="2011">2011</option>
+    <option value="2012">2012</option>
+    <option value="2013">2013</option>
+    <option value="2014">2014</option>
+    <option value="2015">2015</option>
+    <option value="2016">2016</option>
+    <option value="2017">2017</option>
+    <option value="2018">2018</option>
+    <option value="2019">2019</option>
+    <option value="2020">2020</option>
+    <option value="2021">2021</option>
+    <option value="2022">2022</option>
+    <option value="2023">2023</option>
+</select>
+<br>
+CVC: <input name="cvc">
+<br>
+<input type="reset" value="Reset">
+<input type="submit" value="Submit" id="credit_card_submit">
\ No newline at end of file
diff --git a/components/tracing/child/child_trace_message_filter_unittest.cc b/components/tracing/child/child_trace_message_filter_unittest.cc
index 4a090dd..ffb39bdc 100644
--- a/components/tracing/child/child_trace_message_filter_unittest.cc
+++ b/components/tracing/child/child_trace_message_filter_unittest.cc
@@ -72,7 +72,7 @@
 
   EXPECT_TRUE(fake_sender_.last_message_);
   EXPECT_EQ(fake_sender_.last_message_->type(),
-            TracingHostMsg_TriggerBackgroundTrace::ID);
+            static_cast<uint32_t>(TracingHostMsg_TriggerBackgroundTrace::ID));
 }
 
 TEST_F(ChildTraceMessageFilterTest, TestHistogramAborts) {
@@ -84,7 +84,7 @@
 
   EXPECT_TRUE(fake_sender_.last_message_);
   EXPECT_EQ(fake_sender_.last_message_->type(),
-            TracingHostMsg_AbortBackgroundTrace::ID);
+            static_cast<uint32_t>(TracingHostMsg_AbortBackgroundTrace::ID));
 }
 
 }  // namespace tracing
diff --git a/components/ui_devtools/views/dom_agent.cc b/components/ui_devtools/views/dom_agent.cc
index c14f8a87..39fe80d 100644
--- a/components/ui_devtools/views/dom_agent.cc
+++ b/components/ui_devtools/views/dom_agent.cc
@@ -652,10 +652,8 @@
   constexpr SkScalar intervals[] = {1.f, 4.f};
   flags.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
 
-  if (!render_text_) {
-    render_text_ =
-        base::WrapUnique<gfx::RenderText>(gfx::RenderText::CreateInstance());
-  }
+  if (!render_text_)
+    render_text_ = gfx::RenderText::CreateHarfBuzzInstance();
   DrawRulers(screen_bounds, canvas, render_text_.get());
 
   // Display guide lines if |highlight_rect_config_| is NO_DRAW.
diff --git a/components/ukm/content/source_url_recorder.cc b/components/ukm/content/source_url_recorder.cc
index 22eda75..6fb2c248 100644
--- a/components/ukm/content/source_url_recorder.cc
+++ b/components/ukm/content/source_url_recorder.cc
@@ -18,10 +18,6 @@
 
 namespace {
 
-bool IsValidUkmUrl(const GURL& url) {
-  return url.SchemeIsHTTPOrHTTPS();
-}
-
 // SourceUrlRecorderWebContentsObserver is responsible for recording UKM source
 // URLs, for all main frame navigations in a given WebContents.
 // SourceUrlRecorderWebContentsObserver records both the final URL for a
@@ -122,12 +118,10 @@
 
   const ukm::SourceId source_id = ukm::ConvertToSourceId(
       navigation_handle->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
-
-  if (IsValidUkmUrl(initial_url))
-    ukm_recorder->UpdateSourceURL(source_id, initial_url);
+  ukm_recorder->UpdateSourceURL(source_id, initial_url);
 
   const GURL& final_url = navigation_handle->GetURL();
-  if (final_url != initial_url && IsValidUkmUrl(final_url))
+  if (final_url != initial_url)
     ukm_recorder->UpdateSourceURL(source_id, final_url);
 }
 
diff --git a/components/ukm/content/source_url_recorder_browsertest.cc b/components/ukm/content/source_url_recorder_browsertest.cc
index 25d5d41..82d3425 100644
--- a/components/ukm/content/source_url_recorder_browsertest.cc
+++ b/components/ukm/content/source_url_recorder_browsertest.cc
@@ -90,16 +90,6 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverBrowserTest,
-                       IgnoreUnsupportedScheme) {
-  GURL url("about:blank");
-  content::NavigationHandleObserver observer(shell()->web_contents(), url);
-  content::NavigateToURL(shell(), url);
-  EXPECT_TRUE(observer.has_committed());
-  EXPECT_EQ(nullptr, GetSourceForNavigationId(observer.navigation_id()));
-  EXPECT_EQ(GURL(), GetAssociatedURLForWebContentsDocument());
-}
-
-IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverBrowserTest,
                        IgnoreUrlInSubframe) {
   GURL main_url = embedded_test_server()->GetURL("/page_with_iframe.html");
   GURL subframe_url = embedded_test_server()->GetURL("/title1.html");
diff --git a/components/ukm/content/source_url_recorder_test.cc b/components/ukm/content/source_url_recorder_test.cc
index dc8ed15b..2f53248 100644
--- a/components/ukm/content/source_url_recorder_test.cc
+++ b/components/ukm/content/source_url_recorder_test.cc
@@ -62,14 +62,6 @@
   EXPECT_EQ(final_url, GetAssociatedURLForWebContentsDocument());
 }
 
-TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUnsupportedScheme) {
-  NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(),
-                                                    GURL("about:blank"));
-  EXPECT_EQ(0ul, test_ukm_recorder_.sources_count());
-
-  EXPECT_EQ(GURL(), GetAssociatedURLForWebContentsDocument());
-}
-
 TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUrlInSubframe) {
   GURL main_frame_url("https://www.example.com/");
   GURL sub_frame_url("https://www.example.com/iframe.html");
diff --git a/components/ukm/ukm_recorder_impl.cc b/components/ukm/ukm_recorder_impl.cc
index d60a9666..6f7a81a2 100644
--- a/components/ukm/ukm_recorder_impl.cc
+++ b/components/ukm/ukm_recorder_impl.cc
@@ -4,6 +4,10 @@
 
 #include "components/ukm/ukm_recorder_impl.h"
 
+#include <memory>
+#include <string>
+#include <utility>
+
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
@@ -55,6 +59,19 @@
       kUkmFeature, "MaxEntries", kDefaultMaxEntries));
 }
 
+// Returns whether |url| has one of the schemes supported for logging to UKM.
+// URLs with other schemes will not be logged.
+// Note: This currently excludes chrome-extension:// URLs as in order to log
+// them, UKM needs to take into account extension-sync consent, which is not
+// yet done.
+bool HasSupportedScheme(const GURL& url) {
+  // TODO(asvitkine): Support chrome:// and about: URLs here once we have
+  // approval (and necessary logic) for them. Via:
+  //   url.SchemeIs(url::kAboutScheme) || url.SchemeIs("chrome")
+  // Also add FTP Scheme once approved: url.SchemeIs(url::kFtpScheme)
+  return url.SchemeIsHTTPOrHTTPS();
+}
+
 // True if we should record the initial_url field of the UKM Source proto.
 bool ShouldRecordInitialUrl() {
   return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature,
@@ -66,6 +83,7 @@
   RECORDING_DISABLED = 1,
   MAX_HIT = 2,
   NOT_WHITELISTED = 3,
+  UNSUPPORTED_URL_SCHEME = 4,
   NUM_DROPPED_DATA_REASONS
 };
 
@@ -189,6 +207,11 @@
     return;
   }
 
+  if (!HasSupportedScheme(url)) {
+    RecordDroppedSource(DroppedDataReason::UNSUPPORTED_URL_SCHEME);
+    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.
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc
index 7eabee4..e4bb0e7 100644
--- a/components/ukm/ukm_service_unittest.cc
+++ b/components/ukm/ukm_service_unittest.cc
@@ -36,11 +36,11 @@
 // A small shim exposing UkmRecorder methods to tests.
 class TestRecordingHelper {
  public:
-  TestRecordingHelper(UkmRecorder* recorder) : recorder_(recorder) {}
+  explicit TestRecordingHelper(UkmRecorder* recorder) : recorder_(recorder) {}
 
   void UpdateSourceURL(SourceId source_id, const GURL& url) {
     recorder_->UpdateSourceURL(source_id, url);
-  };
+  }
 
   std::unique_ptr<UkmEntryBuilder> GetEntryBuilder(SourceId source_id,
                                                    const char* event_name) {
@@ -49,6 +49,8 @@
 
  private:
   UkmRecorder* recorder_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestRecordingHelper);
 };
 
 namespace {
@@ -720,4 +722,58 @@
   }
 }
 
+TEST_F(UkmServiceTest, UnsupportedSchemes) {
+  struct {
+    const char* url;
+    bool expected_kept;
+  } test_cases[] = {
+      {"http://google.ca/", true},
+      {"https://google.ca/", true},
+      {"ftp://google.ca/", false},
+      {"about:blank", false},
+      {"chrome://version/", false},
+      {"file:///tmp/", false},
+      {"chrome-extension://bhcnanendmgjjeghamaccjnochlnhcgj", false},
+      {"abc://google.ca/", false},
+      {"www.google.ca/", false},
+  };
+
+  base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
+  ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {});
+  UkmService service(&prefs_, &client_);
+  TestRecordingHelper recorder(&service);
+
+  EXPECT_EQ(GetPersistedLogCount(), 0);
+  service.Initialize();
+  task_runner_->RunUntilIdle();
+  service.EnableRecording();
+  service.EnableReporting();
+
+  int64_t id_counter = 1;
+  int expected_kept_count = 0;
+  for (const auto& test : test_cases) {
+    auto source_id = GetWhitelistedSourceId(id_counter++);
+    recorder.UpdateSourceURL(source_id, GURL(test.url));
+    recorder.GetEntryBuilder(source_id, "FakeEntry");
+    if (test.expected_kept)
+      ++expected_kept_count;
+  }
+
+  service.Flush();
+  EXPECT_EQ(GetPersistedLogCount(), 1);
+  Report proto_report = GetPersistedReport();
+
+  EXPECT_EQ(expected_kept_count, proto_report.sources_size());
+  for (const auto& test : test_cases) {
+    bool found = false;
+    for (int i = 0; i < proto_report.sources_size(); ++i) {
+      if (proto_report.sources(i).url() == test.url) {
+        found = true;
+        break;
+      }
+    }
+    EXPECT_EQ(test.expected_kept, found) << test.url;
+  }
+}
+
 }  // namespace ukm
diff --git a/components/variations/client_filterable_state.h b/components/variations/client_filterable_state.h
index 20ebaa9..a244f79 100644
--- a/components/variations/client_filterable_state.h
+++ b/components/variations/client_filterable_state.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_VARIATIONS_CLIENT_FILTERABLE_STATE_H_
 #define COMPONENTS_VARIATIONS_CLIENT_FILTERABLE_STATE_H_
 
+#include <string>
+
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "base/version.h"
@@ -12,7 +14,7 @@
 
 namespace variations {
 
-// A contianer for all of the client state which is used for filtering studies.
+// A container for all of the client state which is used for filtering studies.
 struct ClientFilterableState {
   static Study::Platform GetCurrentPlatform();
 
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc
index 858ef2e..af52445 100644
--- a/components/variations/service/variations_service.cc
+++ b/components/variations/service/variations_service.cc
@@ -746,11 +746,6 @@
       std::move(feature_list), variation_ids, platform_field_trials);
 }
 
-bool VariationsService::CreateTrialsFromSeed(base::FeatureList* feature_list) {
-  return field_trial_creator_.CreateTrialsFromSeed(CreateLowEntropyProvider(),
-                                                   feature_list);
-}
-
 std::string VariationsService::GetStoredPermanentCountry() {
   const base::ListValue* list_value =
       local_state_->GetList(prefs::kVariationsPermanentConsistencyCountry);
diff --git a/components/variations/service/variations_service.h b/components/variations/service/variations_service.h
index 27b7147..0480f64 100644
--- a/components/variations/service/variations_service.h
+++ b/components/variations/service/variations_service.h
@@ -76,13 +76,6 @@
 
   ~VariationsService() override;
 
-  // Creates field trials based on the variations seed loaded from local state.
-  // If there is a problem loading the seed data, all trials specified by the
-  // seed may not be created. Some field trials are configured to override or
-  // associate with (for reporting) specific features. These associations are
-  // registered with |feature_list|.
-  bool CreateTrialsFromSeed(base::FeatureList* feature_list);
-
   // Should be called before startup of the main message loop.
   void PerformPreMainMessageLoopStartup();
 
diff --git a/components/variations/service/variations_service_unittest.cc b/components/variations/service/variations_service_unittest.cc
index 64ec1eb..dc7cf8d 100644
--- a/components/variations/service/variations_service_unittest.cc
+++ b/components/variations/service/variations_service_unittest.cc
@@ -917,7 +917,7 @@
   fetcher->SetResponseString(response);
   service.OnURLFetchComplete(fetcher);
 
-  // Verify that the streaks were rest.
+  // Verify that the streaks were reset.
   EXPECT_EQ(0, prefs_.GetInteger(prefs::kVariationsCrashStreak));
   EXPECT_EQ(0, prefs_.GetInteger(prefs::kVariationsFailedToFetchSeedStreak));
 }
diff --git a/components/viz/client/client_layer_tree_frame_sink.cc b/components/viz/client/client_layer_tree_frame_sink.cc
index c32d7341..bb2d743 100644
--- a/components/viz/client/client_layer_tree_frame_sink.cc
+++ b/components/viz/client/client_layer_tree_frame_sink.cc
@@ -144,8 +144,7 @@
   }
 
   TRACE_EVENT_FLOW_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
-                          "SubmitCompositorFrame",
-                          local_surface_id_.parent_id());
+                          "SubmitCompositorFrame", local_surface_id_.hash());
   bool tracing_enabled;
   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
                                      &tracing_enabled);
diff --git a/components/viz/client/client_layer_tree_frame_sink.h b/components/viz/client/client_layer_tree_frame_sink.h
index e82be90..1d874754 100644
--- a/components/viz/client/client_layer_tree_frame_sink.h
+++ b/components/viz/client/client_layer_tree_frame_sink.h
@@ -15,7 +15,7 @@
 #include "components/viz/client/viz_client_export.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/common/surfaces/surface_id.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
diff --git a/components/viz/client/local_surface_id_provider.cc b/components/viz/client/local_surface_id_provider.cc
index 68e356a..1f7ddc4 100644
--- a/components/viz/client/local_surface_id_provider.cc
+++ b/components/viz/client/local_surface_id_provider.cc
@@ -19,7 +19,7 @@
   if (!local_surface_id_.is_valid() ||
       surface_size_ != frame.size_in_pixels() ||
       frame.device_scale_factor() != device_scale_factor_) {
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
   }
   surface_size_ = frame.size_in_pixels();
   device_scale_factor_ = frame.device_scale_factor();
diff --git a/components/viz/client/local_surface_id_provider.h b/components/viz/client/local_surface_id_provider.h
index fa8e51cd..949b62d 100644
--- a/components/viz/client/local_surface_id_provider.h
+++ b/components/viz/client/local_surface_id_provider.h
@@ -7,7 +7,7 @@
 
 #include "components/viz/client/viz_client_export.h"
 #include "components/viz/common/surfaces/local_surface_id.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace viz {
@@ -37,7 +37,7 @@
   LocalSurfaceId local_surface_id_;
   gfx::Size surface_size_;
   float device_scale_factor_ = 0;
-  LocalSurfaceIdAllocator local_surface_id_allocator_;
+  ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
 
   DISALLOW_COPY_AND_ASSIGN(DefaultLocalSurfaceIdProvider);
 };
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn
index b3711687..3451065 100644
--- a/components/viz/common/BUILD.gn
+++ b/components/viz/common/BUILD.gn
@@ -124,8 +124,8 @@
     "surfaces/frame_sink_id_allocator.h",
     "surfaces/local_surface_id.cc",
     "surfaces/local_surface_id.h",
-    "surfaces/local_surface_id_allocator.cc",
-    "surfaces/local_surface_id_allocator.h",
+    "surfaces/parent_local_surface_id_allocator.cc",
+    "surfaces/parent_local_surface_id_allocator.h",
     "surfaces/sequence_surface_reference_factory.cc",
     "surfaces/sequence_surface_reference_factory.h",
     "surfaces/stub_surface_reference_factory.cc",
diff --git a/components/viz/common/surfaces/local_surface_id.cc b/components/viz/common/surfaces/local_surface_id.cc
index d34a2a5..49bc0852 100644
--- a/components/viz/common/surfaces/local_surface_id.cc
+++ b/components/viz/common/surfaces/local_surface_id.cc
@@ -9,8 +9,8 @@
 namespace viz {
 
 std::string LocalSurfaceId::ToString() const {
-  return base::StringPrintf("LocalSurfaceId(%d, %s" PRIu64 ")", parent_id_,
-                            nonce_.ToString().c_str());
+  return base::StringPrintf("LocalSurfaceId(%d, %d, %s" PRIu64 ")", parent_id_,
+                            child_sequence_number_, nonce_.ToString().c_str());
 }
 
 std::ostream& operator<<(std::ostream& out,
diff --git a/components/viz/common/surfaces/local_surface_id.h b/components/viz/common/surfaces/local_surface_id.h
index 75c8a2f..35d170d8 100644
--- a/components/viz/common/surfaces/local_surface_id.h
+++ b/components/viz/common/surfaces/local_surface_id.h
@@ -23,25 +23,40 @@
 
 class VIZ_COMMON_EXPORT LocalSurfaceId {
  public:
-  constexpr LocalSurfaceId() : parent_id_(0) {}
+  constexpr LocalSurfaceId() : parent_id_(0), child_sequence_number_(0) {}
 
   constexpr LocalSurfaceId(const LocalSurfaceId& other)
-      : parent_id_(other.parent_id_), nonce_(other.nonce_) {}
+      : parent_id_(other.parent_id_),
+        child_sequence_number_(other.child_sequence_number_),
+        nonce_(other.nonce_) {}
 
   constexpr LocalSurfaceId(uint32_t parent_id,
                            const base::UnguessableToken& nonce)
-      : parent_id_(parent_id), nonce_(nonce) {}
+      : parent_id_(parent_id), child_sequence_number_(1), nonce_(nonce) {}
+
+  constexpr LocalSurfaceId(uint32_t parent_id,
+                           uint32_t child_sequence_number,
+                           const base::UnguessableToken& nonce)
+      : parent_id_(parent_id),
+        child_sequence_number_(child_sequence_number),
+        nonce_(nonce) {}
 
   constexpr bool is_valid() const {
-    return parent_id_ != 0 && !nonce_.is_empty();
+    return parent_id_ != 0 && child_sequence_number_ != 0 && !nonce_.is_empty();
   }
 
   constexpr uint32_t parent_id() const { return parent_id_; }
 
+  constexpr uint32_t child_sequence_number() const {
+    return child_sequence_number_;
+  }
+
   constexpr const base::UnguessableToken& nonce() const { return nonce_; }
 
   bool operator==(const LocalSurfaceId& other) const {
-    return parent_id_ == other.parent_id_ && nonce_ == other.nonce_;
+    return parent_id_ == other.parent_id_ &&
+           child_sequence_number_ == other.child_sequence_number_ &&
+           nonce_ == other.nonce_;
   }
 
   bool operator!=(const LocalSurfaceId& other) const {
@@ -51,7 +66,8 @@
   size_t hash() const {
     DCHECK(is_valid()) << ToString();
     return base::HashInts(
-        parent_id_,
+        static_cast<uint64_t>(
+            base::HashInts(parent_id_, child_sequence_number_)),
         static_cast<uint64_t>(base::UnguessableTokenHash()(nonce_)));
   }
 
@@ -64,6 +80,7 @@
   friend bool operator<(const LocalSurfaceId& lhs, const LocalSurfaceId& rhs);
 
   uint32_t parent_id_;
+  uint32_t child_sequence_number_;
   base::UnguessableToken nonce_;
 };
 
@@ -72,8 +89,8 @@
     const LocalSurfaceId& local_surface_id);
 
 inline bool operator<(const LocalSurfaceId& lhs, const LocalSurfaceId& rhs) {
-  return std::tie(lhs.parent_id_, lhs.nonce_) <
-         std::tie(rhs.parent_id_, rhs.nonce_);
+  return std::tie(lhs.parent_id_, lhs.child_sequence_number_, lhs.nonce_) <
+         std::tie(rhs.parent_id_, rhs.child_sequence_number_, rhs.nonce_);
 }
 
 inline bool operator>(const LocalSurfaceId& lhs, const LocalSurfaceId& rhs) {
diff --git a/components/viz/common/surfaces/local_surface_id_allocator.cc b/components/viz/common/surfaces/local_surface_id_allocator.cc
deleted file mode 100644
index 1666033..0000000
--- a/components/viz/common/surfaces/local_surface_id_allocator.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
-
-#include <stdint.h>
-
-#include "base/rand_util.h"
-#include "base/unguessable_token.h"
-
-namespace viz {
-
-LocalSurfaceIdAllocator::LocalSurfaceIdAllocator() : next_id_(1u) {}
-
-LocalSurfaceIdAllocator::~LocalSurfaceIdAllocator() {}
-
-LocalSurfaceId LocalSurfaceIdAllocator::GenerateId() {
-  LocalSurfaceId id(next_id_, base::UnguessableToken::Create());
-  next_id_++;
-  return id;
-}
-
-}  // namespace viz
diff --git a/components/viz/common/surfaces/local_surface_id_allocator.h b/components/viz/common/surfaces/local_surface_id_allocator.h
deleted file mode 100644
index bc01fd5..0000000
--- a/components/viz/common/surfaces/local_surface_id_allocator.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_VIZ_COMMON_SURFACES_LOCAL_SURFACE_ID_ALLOCATOR_H_
-#define COMPONENTS_VIZ_COMMON_SURFACES_LOCAL_SURFACE_ID_ALLOCATOR_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "components/viz/common/surfaces/surface_id.h"
-#include "components/viz/common/viz_common_export.h"
-
-namespace viz {
-
-// This is a helper class for generating local surface IDs for a single
-// FrameSink. This is not threadsafe, to use from multiple threads wrap this
-// class in a mutex.
-class VIZ_COMMON_EXPORT LocalSurfaceIdAllocator {
- public:
-  LocalSurfaceIdAllocator();
-  ~LocalSurfaceIdAllocator();
-
-  LocalSurfaceId GenerateId();
-
- private:
-  uint32_t next_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(LocalSurfaceIdAllocator);
-};
-
-}  // namespace viz
-
-#endif  // COMPONENTS_VIZ_COMMON_SURFACES_LOCAL_SURFACE_ID_ALLOCATOR_H_
diff --git a/components/viz/common/surfaces/parent_local_surface_id_allocator.cc b/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
new file mode 100644
index 0000000..a5a5512
--- /dev/null
+++ b/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
@@ -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 "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
+
+#include <stdint.h>
+
+#include "base/rand_util.h"
+#include "base/unguessable_token.h"
+
+namespace viz {
+
+ParentLocalSurfaceIdAllocator::ParentLocalSurfaceIdAllocator() : next_id_(1u) {}
+
+ParentLocalSurfaceIdAllocator::~ParentLocalSurfaceIdAllocator() {}
+
+LocalSurfaceId ParentLocalSurfaceIdAllocator::GenerateId() {
+  LocalSurfaceId id(next_id_, base::UnguessableToken::Create());
+  next_id_++;
+  return id;
+}
+
+}  // namespace viz
diff --git a/components/viz/common/surfaces/parent_local_surface_id_allocator.h b/components/viz/common/surfaces/parent_local_surface_id_allocator.h
new file mode 100644
index 0000000..d30d272
--- /dev/null
+++ b/components/viz/common/surfaces/parent_local_surface_id_allocator.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_COMMON_SURFACES_PARENT_LOCAL_SURFACE_ID_ALLOCATOR_H_
+#define COMPONENTS_VIZ_COMMON_SURFACES_PARENT_LOCAL_SURFACE_ID_ALLOCATOR_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "components/viz/common/surfaces/surface_id.h"
+#include "components/viz/common/viz_common_export.h"
+
+namespace viz {
+
+// This is a helper class for generating local surface IDs for a single
+// FrameSink. This is not threadsafe, to use from multiple threads wrap this
+// class in a mutex.
+// The parent embeds a child's surface. The parent allocates a surface for the
+// child when the parent needs to change surface parameters, for example.
+class VIZ_COMMON_EXPORT ParentLocalSurfaceIdAllocator {
+ public:
+  ParentLocalSurfaceIdAllocator();
+  ~ParentLocalSurfaceIdAllocator();
+
+  LocalSurfaceId GenerateId();
+
+ private:
+  uint32_t next_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParentLocalSurfaceIdAllocator);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_COMMON_SURFACES_PARENT_LOCAL_SURFACE_ID_ALLOCATOR_H_
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 26cb7aff..72c468a3 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -199,10 +199,12 @@
 
   if (is_mac) {
     sources += [
+      "display_embedder/compositor_overlay_candidate_validator_mac.cc",
       "display_embedder/compositor_overlay_candidate_validator_mac.h",
-      "display_embedder/compositor_overlay_candidate_validator_mac.mm",
+      "display_embedder/gl_output_surface_mac.cc",
+      "display_embedder/gl_output_surface_mac.h",
+      "display_embedder/software_output_device_mac.cc",
       "display_embedder/software_output_device_mac.h",
-      "display_embedder/software_output_device_mac.mm",
     ]
 
     deps += [ "//ui/accelerated_widget_mac" ]
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc
index 9965e63..77bd2fb 100644
--- a/components/viz/service/display/display.cc
+++ b/components/viz/service/display/display.cc
@@ -461,6 +461,12 @@
     renderer_->DidReceiveTextureInUseResponses(responses);
 }
 
+void Display::DidReceiveCALayerParams(
+    const gfx::CALayerParams& ca_layer_params) {
+  if (client_)
+    client_->DisplayDidReceiveCALayerParams(ca_layer_params);
+}
+
 void Display::DidReceivePresentationFeedback(
     uint64_t swap_id,
     const gfx::PresentationFeedback& feedback) {
diff --git a/components/viz/service/display/display.h b/components/viz/service/display/display.h
index 3679944..2bb63f9 100644
--- a/components/viz/service/display/display.h
+++ b/components/viz/service/display/display.h
@@ -107,6 +107,8 @@
   void DidReceiveSwapBuffersAck(uint64_t swap_id) override;
   void DidReceiveTextureInUseResponses(
       const gpu::TextureInUseResponses& responses) override;
+  void DidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) override;
   void DidReceivePresentationFeedback(
       uint64_t swap_id,
       const gfx::PresentationFeedback& feedback) override;
diff --git a/components/viz/service/display/display_client.h b/components/viz/service/display/display_client.h
index 3b1c86b..286aa158f 100644
--- a/components/viz/service/display/display_client.h
+++ b/components/viz/service/display/display_client.h
@@ -7,6 +7,10 @@
 
 #include "components/viz/common/quads/render_pass.h"
 
+namespace gfx {
+struct CALayerParams;
+}  // namespace gfx
+
 namespace viz {
 
 class DisplayClient {
@@ -16,6 +20,8 @@
   virtual void DisplayWillDrawAndSwap(bool will_draw_and_swap,
                                       const RenderPassList& render_passes) = 0;
   virtual void DisplayDidDrawAndSwap() = 0;
+  virtual void DisplayDidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) = 0;
 };
 
 }  // namespace viz
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc
index 5fef6f6..e17f667 100644
--- a/components/viz/service/display/display_unittest.cc
+++ b/components/viz/service/display/display_unittest.cc
@@ -23,7 +23,7 @@
 #include "components/viz/common/quads/surface_draw_quad.h"
 #include "components/viz/common/resources/shared_bitmap_manager.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display_client.h"
 #include "components/viz/service/display/display_scheduler.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
@@ -170,7 +170,7 @@
 
   FrameSinkManagerImpl manager_;
   std::unique_ptr<CompositorFrameSinkSupport> support_;
-  LocalSurfaceIdAllocator id_allocator_;
+  ParentLocalSurfaceIdAllocator id_allocator_;
   scoped_refptr<base::NullTaskRunner> task_runner_;
   cc::TestSharedBitmapManager shared_bitmap_manager_;
   std::unique_ptr<BeginFrameSource> begin_frame_source_;
@@ -186,6 +186,8 @@
   void DisplayWillDrawAndSwap(bool will_draw_and_swap,
                               const RenderPassList& render_passes) override {}
   void DisplayDidDrawAndSwap() override {}
+  void DisplayDidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) override{};
 };
 
 void CopyCallback(bool* called, std::unique_ptr<CopyOutputResult> result) {
diff --git a/components/viz/service/display/output_surface_client.h b/components/viz/service/display/output_surface_client.h
index a5eecbb4..58c0865 100644
--- a/components/viz/service/display/output_surface_client.h
+++ b/components/viz/service/display/output_surface_client.h
@@ -15,6 +15,7 @@
 #include "ui/gfx/geometry/rect.h"
 
 namespace gfx {
+struct CALayerParams;
 struct PresentationFeedback;
 }  // namespace gfx
 
@@ -29,10 +30,14 @@
   // For surfaceless/ozone implementations to create damage for the next frame.
   virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0;
 
-  // For overlays.
+  // For synchronizing IOSurface use with the macOS WindowServer.
   virtual void DidReceiveTextureInUseResponses(
       const gpu::TextureInUseResponses& responses) = 0;
 
+  // For displaying a swapped frame's contents on macOS.
+  virtual void DidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) = 0;
+
   // A notification that the presentation feedback for a CompositorFrame with
   // given |swap_id|. See |gfx::PresentationFeedback| for detail.
   virtual void DidReceivePresentationFeedback(
diff --git a/components/viz/service/display/surface_aggregator_pixeltest.cc b/components/viz/service/display/surface_aggregator_pixeltest.cc
index b9b1756..9f07353d 100644
--- a/components/viz/service/display/surface_aggregator_pixeltest.cc
+++ b/components/viz/service/display/surface_aggregator_pixeltest.cc
@@ -9,7 +9,7 @@
 #include "components/viz/common/quads/render_pass.h"
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/common/quads/surface_draw_quad.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/surface_aggregator.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
@@ -43,7 +43,7 @@
 
  protected:
   FrameSinkManagerImpl manager_;
-  LocalSurfaceIdAllocator allocator_;
+  ParentLocalSurfaceIdAllocator allocator_;
   std::unique_ptr<CompositorFrameSinkSupport> support_;
 };
 
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
index 0c24ff5a..2fdd6b74 100644
--- a/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -24,7 +24,7 @@
 #include "components/viz/common/quads/surface_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
 #include "components/viz/common/resources/shared_bitmap_manager.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "components/viz/service/surfaces/surface.h"
@@ -51,8 +51,8 @@
 constexpr bool kNeedsSyncPoints = false;
 
 SurfaceId InvalidSurfaceId() {
-  static SurfaceId invalid(FrameSinkId(),
-                           LocalSurfaceId(0xdeadbeef, kArbitraryToken));
+  static SurfaceId invalid(
+      FrameSinkId(), LocalSurfaceId(0xdeadbeef, 0xdeadbeef, kArbitraryToken));
   return invalid;
 }
 
@@ -418,9 +418,9 @@
  protected:
   LocalSurfaceId root_local_surface_id_;
   Surface* root_surface_;
-  LocalSurfaceIdAllocator allocator_;
+  ParentLocalSurfaceIdAllocator allocator_;
   std::unique_ptr<CompositorFrameSinkSupport> child_support_;
-  LocalSurfaceIdAllocator child_allocator_;
+  ParentLocalSurfaceIdAllocator child_allocator_;
 };
 
 // Tests that a very simple frame containing only two solid color quads makes it
diff --git a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_mac.mm b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_mac.cc
similarity index 100%
rename from components/viz/service/display_embedder/compositor_overlay_candidate_validator_mac.mm
rename to components/viz/service/display_embedder/compositor_overlay_candidate_validator_mac.cc
diff --git a/components/viz/service/display_embedder/gl_output_surface.cc b/components/viz/service/display_embedder/gl_output_surface.cc
index 9ba6e8c..d146fe8 100644
--- a/components/viz/service/display_embedder/gl_output_surface.cc
+++ b/components/viz/service/display_embedder/gl_output_surface.cc
@@ -140,9 +140,10 @@
 
 void GLOutputSurface::OnGpuSwapBuffersCompleted(
     const gpu::SwapBuffersCompleteParams& params) {
-  // TODO(ccameron): Route |params.ca_layer_params|.
   if (!params.texture_in_use_responses.empty())
     client_->DidReceiveTextureInUseResponses(params.texture_in_use_responses);
+  if (!params.ca_layer_params.is_empty)
+    client_->DidReceiveCALayerParams(params.ca_layer_params);
   DidReceiveSwapBuffersAck(params.swap_response.result,
                            params.swap_response.swap_id);
   latency_info_cache_.OnSwapBuffersCompleted(params.swap_response);
diff --git a/components/viz/service/display_embedder/gl_output_surface_mac.cc b/components/viz/service/display_embedder/gl_output_surface_mac.cc
new file mode 100644
index 0000000..61bdd2c
--- /dev/null
+++ b/components/viz/service/display_embedder/gl_output_surface_mac.cc
@@ -0,0 +1,16 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/gl_output_surface_mac.h"
+
+namespace viz {
+
+GLOutputSurfaceMac::GLOutputSurfaceMac(
+    scoped_refptr<InProcessContextProvider> context_provider,
+    SyntheticBeginFrameSource* synthetic_begin_frame_source)
+    : GLOutputSurface(context_provider, synthetic_begin_frame_source) {}
+
+GLOutputSurfaceMac::~GLOutputSurfaceMac() {}
+
+}  // namespace viz
diff --git a/components/viz/service/display_embedder/gl_output_surface_mac.h b/components/viz/service/display_embedder/gl_output_surface_mac.h
new file mode 100644
index 0000000..fc72edc
--- /dev/null
+++ b/components/viz/service/display_embedder/gl_output_surface_mac.h
@@ -0,0 +1,23 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_MAC_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_MAC_H_
+
+#include "components/viz/service/display_embedder/gl_output_surface.h"
+
+namespace viz {
+
+// TODO(ccameron): This should share most of its implementation with
+// GLOutputSurfaceOzone.
+class GLOutputSurfaceMac : public GLOutputSurface {
+ public:
+  GLOutputSurfaceMac(scoped_refptr<InProcessContextProvider> context_provider,
+                     SyntheticBeginFrameSource* synthetic_begin_frame_source);
+  ~GLOutputSurfaceMac() override;
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_MAC_H_
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc
index 863f533..c8333ef 100644
--- a/components/viz/service/display_embedder/gpu_display_provider.cc
+++ b/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -33,6 +33,7 @@
 #endif
 
 #if defined(OS_MACOSX)
+#include "components/viz/service/display_embedder/gl_output_surface_mac.h"
 #include "components/viz/service/display_embedder/software_output_device_mac.h"
 #endif
 
@@ -129,6 +130,9 @@
           std::move(context_provider), widget,
           synthetic_begin_frame_source.get(), gpu_memory_buffer_manager_.get(),
           GL_TEXTURE_2D, GL_RGB);
+#elif defined(OS_MACOSX)
+      output_surface = base::MakeUnique<GLOutputSurfaceMac>(
+          std::move(context_provider), synthetic_begin_frame_source.get());
 #else
       NOTREACHED();
 #endif
diff --git a/components/viz/service/display_embedder/software_output_device_mac.mm b/components/viz/service/display_embedder/software_output_device_mac.cc
similarity index 91%
rename from components/viz/service/display_embedder/software_output_device_mac.mm
rename to components/viz/service/display_embedder/software_output_device_mac.cc
index 9b79e7e..40570b3 100644
--- a/components/viz/service/display_embedder/software_output_device_mac.mm
+++ b/components/viz/service/display_embedder/software_output_device_mac.cc
@@ -7,7 +7,7 @@
 #include "base/mac/foundation_util.h"
 #include "base/trace_event/trace_event.h"
 #include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
+#include "ui/accelerated_widget_mac/ca_layer_frame_sink.h"
 #include "ui/gfx/mac/io_surface.h"
 #include "ui/gfx/skia_util.h"
 
@@ -179,13 +179,20 @@
   current_paint_canvas_.reset();
 
   if (widget_ != gfx::kNullAcceleratedWidget) {
-    ui::AcceleratedWidgetMac* widget = ui::AcceleratedWidgetMac::Get(widget_);
-    if (widget) {
-      widget->GotIOSurfaceFrame(current_paint_buffer_->io_surface, pixel_size_,
-                                scale_factor_);
+    gfx::CALayerParams ca_layer_params;
+    ca_layer_params.is_empty = false;
+    ca_layer_params.scale_factor = scale_factor_;
+    ca_layer_params.pixel_size = pixel_size_;
+    ca_layer_params.io_surface_mach_port.reset(
+        IOSurfaceCreateMachPort(current_paint_buffer_->io_surface));
+    ui::CALayerFrameSink* ca_layer_frame_sink =
+        ui::CALayerFrameSink::FromAcceleratedWidget(widget_);
+    if (ca_layer_frame_sink) {
+      ca_layer_frame_sink->SetSuspended(false);
+      ca_layer_frame_sink->UpdateCALayerTree(ca_layer_params);
       base::TimeTicks vsync_timebase;
       base::TimeDelta vsync_interval;
-      widget->GetVSyncParameters(&vsync_timebase, &vsync_interval);
+      ca_layer_frame_sink->GetVSyncParameters(&vsync_timebase, &vsync_interval);
       if (!update_vsync_callback_.is_null())
         update_vsync_callback_.Run(vsync_timebase, vsync_interval);
     }
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
index 366a41d0..6929485 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -8,7 +8,7 @@
 #include "cc/trees/layer_tree_frame_sink_client.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support_manager.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
@@ -98,7 +98,7 @@
   if (!local_surface_id_.is_valid() ||
       frame.size_in_pixels() != last_swap_frame_size_ ||
       frame.device_scale_factor() != device_scale_factor_) {
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
     last_swap_frame_size_ = frame.size_in_pixels();
     device_scale_factor_ = frame.device_scale_factor();
     display_->SetLocalSurfaceId(local_surface_id_, device_scale_factor_);
@@ -132,6 +132,12 @@
   // be drawn.
 }
 
+void DirectLayerTreeFrameSink::DisplayDidReceiveCALayerParams(
+    const gfx::CALayerParams& ca_layer_params) {
+  // TODO(ccameron): Continue plumbing |ca_layer_params| through to
+  // ui::AcceleratedWidgetMac.
+}
+
 void DirectLayerTreeFrameSink::DidReceiveCompositorFrameAck(
     const std::vector<ReturnedResource>& resources) {
   client_->ReclaimResources(resources);
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
index 2334610..94858eb8 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
@@ -9,7 +9,7 @@
 #include "base/threading/thread_checker.h"
 #include "cc/trees/layer_tree_frame_sink.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display_client.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/viz_service_export.h"
@@ -62,6 +62,8 @@
   void DisplayWillDrawAndSwap(bool will_draw_and_swap,
                               const RenderPassList& render_passes) override;
   void DisplayDidDrawAndSwap() override;
+  void DisplayDidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) override;
 
  protected:
   std::unique_ptr<CompositorFrameSinkSupport> support_;  // protected for test.
@@ -93,7 +95,7 @@
   LocalSurfaceId local_surface_id_;
   CompositorFrameSinkSupportManager* const support_manager_;
   FrameSinkManagerImpl* frame_sink_manager_;
-  LocalSurfaceIdAllocator local_surface_id_allocator_;
+  ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
   Display* display_;
   gfx::Size last_swap_frame_size_;
   float device_scale_factor_ = 1.f;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
index 61daa54..cbf4a1f2 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -14,7 +14,7 @@
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/frame_sinks/delay_based_time_source.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/display/display_scheduler.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support_manager.h"
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
index a916e31a..c7ac9f4 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -26,11 +26,15 @@
     default;
 
 FrameSinkManagerImpl::FrameSinkSourceMapping::FrameSinkSourceMapping(
-    const FrameSinkSourceMapping& other) = default;
+    FrameSinkSourceMapping&& other) = default;
 
 FrameSinkManagerImpl::FrameSinkSourceMapping::~FrameSinkSourceMapping() =
     default;
 
+FrameSinkManagerImpl::FrameSinkSourceMapping&
+FrameSinkManagerImpl::FrameSinkSourceMapping::operator=(
+    FrameSinkSourceMapping&& other) = default;
+
 FrameSinkManagerImpl::SinkAndSupport::SinkAndSupport() = default;
 
 FrameSinkManagerImpl::SinkAndSupport::SinkAndSupport(SinkAndSupport&& other) =
@@ -158,10 +162,9 @@
   // then this will create an infinite loop.  Might as well just crash here.
   CHECK(!ChildContains(child_frame_sink_id, parent_frame_sink_id));
 
-  std::vector<FrameSinkId>& children =
-      frame_sink_source_map_[parent_frame_sink_id].children;
-  DCHECK(!base::ContainsValue(children, child_frame_sink_id));
-  children.push_back(child_frame_sink_id);
+  auto& children = frame_sink_source_map_[parent_frame_sink_id].children;
+  DCHECK(!base::ContainsKey(children, child_frame_sink_id));
+  children.insert(child_frame_sink_id);
 
   // If the parent has no source, then attaching it to this child will
   // not change any downstream sources.
@@ -177,32 +180,21 @@
 void FrameSinkManagerImpl::UnregisterFrameSinkHierarchy(
     const FrameSinkId& parent_frame_sink_id,
     const FrameSinkId& child_frame_sink_id) {
-  // Deliberately do not check validity of either parent or child
-  // FrameSinkId here.  They were valid during the registration, so were
-  // valid at some point in time.  This makes it possible to invalidate parent
-  // and child FrameSinkIds independently of each other and not have an ordering
-  // dependency  of unregistering the hierarchy first before either of them.
-  DCHECK_EQ(frame_sink_source_map_.count(parent_frame_sink_id), 1u);
-
+  // Deliberately do not check validity of either parent or child FrameSinkId
+  // here. They were valid during the registration, so were valid at some point
+  // in time. This makes it possible to invalidate parent and child FrameSinkIds
+  // independently of each other and not have an ordering dependency of
+  // unregistering the hierarchy first before either of them.
   auto iter = frame_sink_source_map_.find(parent_frame_sink_id);
+  DCHECK(iter != frame_sink_source_map_.end());
 
-  std::vector<FrameSinkId>& children = iter->second.children;
-  bool found_child = false;
-  for (size_t i = 0; i < children.size(); ++i) {
-    if (children[i] == child_frame_sink_id) {
-      found_child = true;
-      children[i] = children.back();
-      children.resize(children.size() - 1);
-      break;
-    }
-  }
-  DCHECK(found_child);
+  // Remove |child_frame_sink_id| from parents list of children.
+  auto& mapping = iter->second;
+  DCHECK(base::ContainsKey(mapping.children, child_frame_sink_id));
+  mapping.children.erase(child_frame_sink_id);
 
-  // The CompositorFrameSinkSupport and hierarchy can be registered/unregistered
-  // in either order, so empty frame_sink_source_map entries need to be
-  // checked when removing either clients or relationships.
-  if (!iter->second.has_children() && !iter->second.source &&
-      !compositor_frame_sinks_.count(parent_frame_sink_id)) {
+  // Delete the FrameSinkSourceMapping for |parent_frame_sink_id| if empty.
+  if (!mapping.has_children() && !mapping.source) {
     frame_sink_source_map_.erase(iter);
     return;
   }
@@ -215,7 +207,7 @@
 
   // TODO(enne): these walks could be done in one step.
   RecursivelyDetachBeginFrameSource(child_frame_sink_id, parent_source);
-  for (auto source_iter : registered_sources_)
+  for (auto& source_iter : registered_sources_)
     RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first);
 }
 
@@ -292,18 +284,16 @@
   FrameSinkSourceMapping& mapping = frame_sink_source_map_[frame_sink_id];
   if (!mapping.source) {
     mapping.source = source;
-    auto client_iter = compositor_frame_sinks_.find(frame_sink_id);
-    if (client_iter != compositor_frame_sinks_.end())
-      client_iter->second.support->SetBeginFrameSource(source);
+    auto iter = compositor_frame_sinks_.find(frame_sink_id);
+    if (iter != compositor_frame_sinks_.end())
+      iter->second.support->SetBeginFrameSource(source);
   }
-  for (size_t i = 0; i < mapping.children.size(); ++i) {
-    // |frame_sink_source_map_| is a container that can allocate new memory and
-    // move data between buffers. Copy child's FrameSinkId before passing
-    // it to RecursivelyAttachBeginFrameSource so that we don't reference data
-    // inside |frame_sink_source_map_|.
-    FrameSinkId child_copy = mapping.children[i];
-    RecursivelyAttachBeginFrameSource(child_copy, source);
-  }
+
+  // Copy the list of children because RecursivelyAttachBeginFrameSource() can
+  // modify |frame_sink_source_map_| and invalidate iterators.
+  base::flat_set<FrameSinkId> children = mapping.children;
+  for (const FrameSinkId& child : children)
+    RecursivelyAttachBeginFrameSource(child, source);
 }
 
 void FrameSinkManagerImpl::RecursivelyDetachBeginFrameSource(
@@ -312,23 +302,26 @@
   auto iter = frame_sink_source_map_.find(frame_sink_id);
   if (iter == frame_sink_source_map_.end())
     return;
-  if (iter->second.source == source) {
-    iter->second.source = nullptr;
+
+  auto& mapping = iter->second;
+  if (mapping.source == source) {
+    mapping.source = nullptr;
     auto client_iter = compositor_frame_sinks_.find(frame_sink_id);
     if (client_iter != compositor_frame_sinks_.end())
       client_iter->second.support->SetBeginFrameSource(nullptr);
   }
 
-  if (!iter->second.has_children() &&
-      !compositor_frame_sinks_.count(frame_sink_id)) {
+  // Delete the FrameSinkSourceMapping for |frame_sink_id| if empty.
+  if (!mapping.has_children()) {
     frame_sink_source_map_.erase(iter);
     return;
   }
 
-  std::vector<FrameSinkId>& children = iter->second.children;
-  for (size_t i = 0; i < children.size(); ++i) {
-    RecursivelyDetachBeginFrameSource(children[i], source);
-  }
+  // Copy the list of children because RecursivelyDetachBeginFrameSource() can
+  // modify |frame_sink_source_map_| and invalidate iterators.
+  base::flat_set<FrameSinkId> children = mapping.children;
+  for (const FrameSinkId& child : children)
+    RecursivelyDetachBeginFrameSource(child, source);
 }
 
 CapturableFrameSink* FrameSinkManagerImpl::FindCapturableFrameSink(
@@ -346,11 +339,10 @@
   if (iter == frame_sink_source_map_.end())
     return false;
 
-  const std::vector<FrameSinkId>& children = iter->second.children;
-  for (size_t i = 0; i < children.size(); ++i) {
-    if (children[i] == search_frame_sink_id)
+  for (const FrameSinkId& child : iter->second.children) {
+    if (child == search_frame_sink_id)
       return true;
-    if (ChildContains(children[i], search_frame_sink_id))
+    if (ChildContains(child, search_frame_sink_id))
       return true;
   }
   return false;
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
index 784b586..6e1fa897 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -7,10 +7,11 @@
 
 #include <stdint.h>
 
-#include <unordered_map>
-#include <vector>
+#include <memory>
+#include <string>
 
 #include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
@@ -158,16 +159,23 @@
                            uint32_t frame_token);
 
  private:
+  friend class FrameSinkManagerTest;
+
   // BeginFrameSource routing information for a FrameSinkId.
   struct FrameSinkSourceMapping {
     FrameSinkSourceMapping();
-    FrameSinkSourceMapping(const FrameSinkSourceMapping& other);
+    FrameSinkSourceMapping(FrameSinkSourceMapping&& other);
     ~FrameSinkSourceMapping();
+    FrameSinkSourceMapping& operator=(FrameSinkSourceMapping&& other);
+
     bool has_children() const { return !children.empty(); }
     // The currently assigned begin frame source for this client.
     BeginFrameSource* source = nullptr;
     // This represents a dag of parent -> children mapping.
-    std::vector<FrameSinkId> children;
+    base::flat_set<FrameSinkId> children;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(FrameSinkSourceMapping);
   };
 
   struct SinkAndSupport {
@@ -182,6 +190,9 @@
 
     // This can be owned by |sink| or owned externally.
     CompositorFrameSinkSupport* support = nullptr;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(SinkAndSupport);
   };
 
   void RecursivelyAttachBeginFrameSource(const FrameSinkId& frame_sink_id,
@@ -202,13 +213,16 @@
   // Provides a Display for CreateRootCompositorFrameSink().
   DisplayProvider* const display_provider_;
 
-  std::unordered_map<FrameSinkId, FrameSinkSourceMapping, FrameSinkIdHash>
-      frame_sink_source_map_;
-
   // Set of BeginFrameSource along with associated FrameSinkIds. Any child
-  // that is implicitly using this framesink must be reachable by the
+  // that is implicitly using this frame sink must be reachable by the
   // parent in the dag.
-  std::unordered_map<BeginFrameSource*, FrameSinkId> registered_sources_;
+  base::flat_map<BeginFrameSource*, FrameSinkId> registered_sources_;
+
+  // Contains FrameSinkId hierarchy and BeginFrameSource mapping.
+  base::flat_map<FrameSinkId, FrameSinkSourceMapping> frame_sink_source_map_;
+
+  // Contains (and maybe owns) the CompositorFrameSinkSupport.
+  base::flat_map<FrameSinkId, SinkAndSupport> compositor_frame_sinks_;
 
   PrimaryBeginFrameSource primary_source_;
 
@@ -218,18 +232,16 @@
 
   HitTestManager hit_test_manager_;
 
-  base::flat_map<FrameSinkId, SinkAndSupport> compositor_frame_sinks_;
-
   THREAD_CHECKER(thread_checker_);
 
-  // This will point to |client_ptr_| if using Mojo or a provided client if
-  // directly connected. Use this to make function calls.
-  mojom::FrameSinkManagerClient* client_ = nullptr;
-
   // |video_detector_| is instantiated lazily in order to avoid overhead on
   // platforms that don't need video detection.
   std::unique_ptr<VideoDetector> video_detector_;
 
+  // This will point to |client_ptr_| if using Mojo or a provided client if
+  // directly connected. Use this to make function calls.
+  mojom::FrameSinkManagerClient* client_ = nullptr;
+
   mojom::FrameSinkManagerClientPtr client_ptr_;
   mojo::Binding<mojom::FrameSinkManager> binding_;
 
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
index 1ae67381..e9d916f 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -34,6 +34,12 @@
     return support->begin_frame_source_;
   }
 
+  // testing::Test implementation.
+  void TearDown() override {
+    // Make sure that all FrameSinkSourceMappings have been deleted.
+    EXPECT_TRUE(manager_.frame_sink_source_map_.empty());
+  }
+
  protected:
   FrameSinkManagerImpl manager_;
 };
@@ -256,6 +262,10 @@
   manager_.UnregisterBeginFrameSource(&root_source);
   EXPECT_EQ(nullptr, GetBeginFrameSource(root));
   EXPECT_EQ(nullptr, GetBeginFrameSource(client_c));
+
+  // Unregister all registered hierarchy.
+  manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA);
+  manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdC);
 }
 
 // This test sets up the same hierarchy as ParentWithoutClientRetained.
@@ -296,6 +306,10 @@
   manager_.UnregisterBeginFrameSource(&root_source);
   EXPECT_EQ(nullptr, GetBeginFrameSource(root));
   EXPECT_EQ(nullptr, GetBeginFrameSource(client_c));
+
+  // Unregister all registered hierarchy.
+  manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA);
+  manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdC);
 }
 
 namespace {
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
index 8dc2f4a7..b36fb386 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -128,6 +128,12 @@
   hit_test_aggregator_.Aggregate(display_->CurrentSurfaceId());
 }
 
+void RootCompositorFrameSinkImpl::DisplayDidReceiveCALayerParams(
+    const gfx::CALayerParams& ca_layer_params) {
+  // TODO(ccameron): Continue plumbing |ca_layer_params| through to
+  // ui::AcceleratedWidgetMac.
+}
+
 void RootCompositorFrameSinkImpl::DisplayDidDrawAndSwap() {}
 
 void RootCompositorFrameSinkImpl::OnClientConnectionLost() {
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
index ee5fef2..5d5fcad 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
@@ -74,6 +74,8 @@
   void DisplayWillDrawAndSwap(bool will_draw_and_swap,
                               const RenderPassList& render_passes) override;
   void DisplayDidDrawAndSwap() override;
+  void DisplayDidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) override;
 
   void OnClientConnectionLost();
 
diff --git a/components/viz/service/frame_sinks/video_detector_unittest.cc b/components/viz/service/frame_sinks/video_detector_unittest.cc
index 10efc3d..b1fe23ae 100644
--- a/components/viz/service/frame_sinks/video_detector_unittest.cc
+++ b/components/viz/service/frame_sinks/video_detector_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
 #include "components/viz/common/quads/surface_draw_quad.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/surface_aggregator.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
@@ -92,7 +92,8 @@
 
     root_frame_sink_ = CreateFrameSink();
     root_frame_sink_->SubmitCompositorFrame(
-        local_surface_id_allocator_.GenerateId(), MakeDefaultCompositorFrame());
+        parent_local_surface_id_allocator_.GenerateId(),
+        MakeDefaultCompositorFrame());
   }
 
  protected:
@@ -140,7 +141,7 @@
     LocalSurfaceId local_surface_id =
         frame_sink->local_surface_id().is_valid()
             ? frame_sink->local_surface_id()
-            : local_surface_id_allocator_.GenerateId();
+            : parent_local_surface_id_allocator_.GenerateId();
     frame_sink->SubmitCompositorFrame(local_surface_id,
                                       MakeDamagedCompositorFrame(damage));
   }
@@ -190,7 +191,7 @@
 
   FrameSinkManagerImpl frame_sink_manager_;
   FakeCompositorFrameSinkClient frame_sink_client_;
-  LocalSurfaceIdAllocator local_surface_id_allocator_;
+  ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
   SurfaceAggregator surface_aggregator_;
   std::unique_ptr<CompositorFrameSinkSupport> root_frame_sink_;
   std::set<CompositorFrameSinkSupport*> embedded_clients_;
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc
index bb5786a3..1df53fc6 100644
--- a/components/viz/service/surfaces/surface.cc
+++ b/components/viz/service/surfaces/surface.cc
@@ -13,7 +13,7 @@
 #include "components/viz/common/frame_sinks/copy_output_request.h"
 #include "components/viz/common/resources/returned_resource.h"
 #include "components/viz/common/resources/transferable_resource.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/surfaces/surface_client.h"
 #include "components/viz/service/surfaces/surface_manager.h"
 #include "components/viz/service/viz_service_export.h"
diff --git a/components/viz/service/surfaces/surface_hittest_unittest.cc b/components/viz/service/surfaces/surface_hittest_unittest.cc
index bedd0bf..c97f437 100644
--- a/components/viz/service/surfaces/surface_hittest_unittest.cc
+++ b/components/viz/service/surfaces/surface_hittest_unittest.cc
@@ -5,7 +5,7 @@
 #include <stddef.h>
 
 #include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "components/viz/service/surfaces/surface.h"
@@ -111,13 +111,13 @@
   // Add a reference to a non-existant child surface on the root surface.
   SurfaceId child_surface_id(
       kArbitraryFrameSink,
-      LocalSurfaceId(0xdeadbeef, base::UnguessableToken::Create()));
+      LocalSurfaceId(0xdeadbeef, 0xdeadbeef, base::UnguessableToken::Create()));
   gfx::Rect child_rect(200, 200);
   CreateSurfaceDrawQuad(root_pass, gfx::Transform(), root_rect, child_rect,
                         child_surface_id);
 
   // Submit the root frame.
-  LocalSurfaceIdAllocator root_allocator;
+  ParentLocalSurfaceIdAllocator root_allocator;
   LocalSurfaceId root_local_surface_id = root_allocator.GenerateId();
   SurfaceId root_surface_id(kRootFrameSink, root_local_surface_id);
   root_support().SubmitCompositorFrame(root_local_surface_id,
@@ -142,7 +142,7 @@
   CompositorFrame root_frame = CreateCompositorFrame(root_rect, &root_pass);
 
   // Submit the root frame.
-  LocalSurfaceIdAllocator root_allocator;
+  ParentLocalSurfaceIdAllocator root_allocator;
   LocalSurfaceId root_local_surface_id = root_allocator.GenerateId();
   SurfaceId root_surface_id(kRootFrameSink, root_local_surface_id);
   root_support().SubmitCompositorFrame(root_local_surface_id,
@@ -164,7 +164,7 @@
   CompositorFrame root_frame = CreateCompositorFrame(root_rect, &root_pass);
 
   // Add a reference to the child surface on the root surface.
-  LocalSurfaceIdAllocator child_allocator;
+  ParentLocalSurfaceIdAllocator child_allocator;
   LocalSurfaceId child_local_surface_id = child_allocator.GenerateId();
   SurfaceId child_surface_id(kChildFrameSink, child_local_surface_id);
   gfx::Rect child_rect(200, 200);
@@ -175,7 +175,7 @@
       root_rect, child_rect, child_surface_id);
 
   // Submit the root frame.
-  LocalSurfaceIdAllocator root_allocator;
+  ParentLocalSurfaceIdAllocator root_allocator;
   LocalSurfaceId root_local_surface_id = root_allocator.GenerateId();
   SurfaceId root_surface_id(kRootFrameSink, root_local_surface_id);
   root_support().SubmitCompositorFrame(root_local_surface_id,
@@ -261,7 +261,7 @@
                            invalid_render_pass_id);
 
   // Add a reference to the child surface on the root surface.
-  LocalSurfaceIdAllocator child_allocator;
+  ParentLocalSurfaceIdAllocator child_allocator;
   LocalSurfaceId child_local_surface_id = child_allocator.GenerateId();
   SurfaceId child_surface_id(kChildFrameSink, child_local_surface_id);
   gfx::Rect child_rect(200, 200);
@@ -272,7 +272,7 @@
       root_rect, child_rect, child_surface_id);
 
   // Submit the root frame.
-  LocalSurfaceIdAllocator root_allocator;
+  ParentLocalSurfaceIdAllocator root_allocator;
   LocalSurfaceId root_local_surface_id = root_allocator.GenerateId();
   SurfaceId root_surface_id(kRootFrameSink, root_local_surface_id);
   root_support().SubmitCompositorFrame(root_local_surface_id,
@@ -347,7 +347,7 @@
                            gfx::Rect(100, 100), child_solid_quad_rect);
 
   // Submit the root frame.
-  LocalSurfaceIdAllocator root_allocator;
+  ParentLocalSurfaceIdAllocator root_allocator;
   LocalSurfaceId root_local_surface_id = root_allocator.GenerateId();
   SurfaceId root_surface_id(kRootFrameSink, root_local_surface_id);
   root_support().SubmitCompositorFrame(root_local_surface_id,
@@ -383,7 +383,7 @@
   CompositorFrame root_frame = CreateCompositorFrame(root_rect, &root_pass);
 
   // Add a reference to the child surface on the root surface.
-  LocalSurfaceIdAllocator child_allocator;
+  ParentLocalSurfaceIdAllocator child_allocator;
   LocalSurfaceId child_local_surface_id = child_allocator.GenerateId();
   SurfaceId child_surface_id(kChildFrameSink, child_local_surface_id);
   gfx::Rect child_rect(200, 200);
@@ -394,7 +394,7 @@
       root_rect, child_rect, child_surface_id);
 
   // Submit the root frame.
-  LocalSurfaceIdAllocator root_allocator;
+  ParentLocalSurfaceIdAllocator root_allocator;
   LocalSurfaceId root_local_surface_id = root_allocator.GenerateId();
   SurfaceId root_surface_id(kRootFrameSink, root_local_surface_id);
   root_support().SubmitCompositorFrame(root_local_surface_id,
diff --git a/components/viz/service/surfaces/surface_manager.cc b/components/viz/service/surfaces/surface_manager.cc
index cf1478d..6180f79c 100644
--- a/components/viz/service/surfaces/surface_manager.cc
+++ b/components/viz/service/surfaces/surface_manager.cc
@@ -14,7 +14,7 @@
 #include "base/containers/queue.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/common/surfaces/stub_surface_reference_factory.h"
 #include "components/viz/common/surfaces/surface_info.h"
 #include "components/viz/service/surfaces/direct_surface_reference_factory.h"
diff --git a/components/viz/service/surfaces/surface_unittest.cc b/components/viz/service/surfaces/surface_unittest.cc
index 600ad20..da829cbc 100644
--- a/components/viz/service/surfaces/surface_unittest.cc
+++ b/components/viz/service/surfaces/surface_unittest.cc
@@ -6,7 +6,7 @@
 #include "base/memory/ptr_util.h"
 #include "cc/test/scheduler_test_common.h"
 #include "components/viz/common/frame_sinks/copy_output_result.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "components/viz/service/surfaces/surface_dependency_tracker.h"
@@ -108,7 +108,7 @@
 
 TEST(SurfaceTest, SurfaceIds) {
   for (size_t i = 0; i < 3; ++i) {
-    LocalSurfaceIdAllocator allocator;
+    ParentLocalSurfaceIdAllocator allocator;
     LocalSurfaceId id1 = allocator.GenerateId();
     LocalSurfaceId id2 = allocator.GenerateId();
     EXPECT_NE(id1, id2);
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc
index a6604e6..da0eb77d 100644
--- a/components/viz/test/test_layer_tree_frame_sink.cc
+++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -40,7 +40,7 @@
       refresh_rate_(refresh_rate),
       task_runner_(std::move(task_runner)),
       frame_sink_id_(kLayerTreeFrameSinkId),
-      local_surface_id_allocator_(new LocalSurfaceIdAllocator),
+      parent_local_surface_id_allocator_(new ParentLocalSurfaceIdAllocator),
       external_begin_frame_source_(this),
       weak_ptr_factory_(this) {
   // Always use sync tokens so that code paths in resource provider that deal
@@ -123,7 +123,7 @@
   support_ = nullptr;
   display_ = nullptr;
   begin_frame_source_ = nullptr;
-  local_surface_id_allocator_ = nullptr;
+  parent_local_surface_id_allocator_ = nullptr;
   frame_sink_manager_ = nullptr;
   test_client_ = nullptr;
   LayerTreeFrameSink::DetachFromClient();
@@ -144,7 +144,7 @@
   float device_scale_factor = frame.device_scale_factor();
   if (!local_surface_id_.is_valid() || frame_size != display_size_ ||
       device_scale_factor != device_scale_factor_) {
-    local_surface_id_ = local_surface_id_allocator_->GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_->GenerateId();
     display_->SetLocalSurfaceId(local_surface_id_, device_scale_factor);
     display_->Resize(frame_size);
     display_size_ = frame_size;
@@ -224,6 +224,9 @@
   test_client_->DisplayDidDrawAndSwap();
 }
 
+void TestLayerTreeFrameSink::DisplayDidReceiveCALayerParams(
+    const gfx::CALayerParams& ca_layer_params) {}
+
 void TestLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) {
   support_->SetNeedsBeginFrame(needs_begin_frames);
 }
diff --git a/components/viz/test/test_layer_tree_frame_sink.h b/components/viz/test/test_layer_tree_frame_sink.h
index 8a15736..0a58c64 100644
--- a/components/viz/test/test_layer_tree_frame_sink.h
+++ b/components/viz/test/test_layer_tree_frame_sink.h
@@ -10,7 +10,7 @@
 #include "cc/trees/layer_tree_frame_sink.h"
 #include "components/viz/common/display/renderer_settings.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/display/display_client.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
@@ -108,6 +108,8 @@
   void DisplayWillDrawAndSwap(bool will_draw_and_swap,
                               const RenderPassList& render_passes) override;
   void DisplayDidDrawAndSwap() override;
+  void DisplayDidReceiveCALayerParams(
+      const gfx::CALayerParams& ca_layer_params) override;
 
  private:
   // ExternalBeginFrameSource implementation.
@@ -126,7 +128,8 @@
   // TODO(danakj): These don't need to be stored in unique_ptrs when
   // LayerTreeFrameSink is owned/destroyed on the compositor thread.
   std::unique_ptr<FrameSinkManagerImpl> frame_sink_manager_;
-  std::unique_ptr<LocalSurfaceIdAllocator> local_surface_id_allocator_;
+  std::unique_ptr<ParentLocalSurfaceIdAllocator>
+      parent_local_surface_id_allocator_;
   LocalSurfaceId local_surface_id_;
   gfx::Size display_size_;
   float device_scale_factor_ = 0;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 2e9b1cd..76191f4 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1033,6 +1033,8 @@
     "loader/wake_lock_resource_throttle.h",
     "loader_delegate_impl.cc",
     "loader_delegate_impl.h",
+    "locks/lock_manager.cc",
+    "locks/lock_manager.h",
     "mach_broker_mac.h",
     "mach_broker_mac.mm",
     "manifest/manifest_icon_downloader.cc",
@@ -2250,8 +2252,8 @@
       "compositor/browser_compositor_output_surface.h",
       "compositor/gpu_browser_compositor_output_surface.cc",
       "compositor/gpu_browser_compositor_output_surface.h",
+      "compositor/gpu_output_surface_mac.cc",
       "compositor/gpu_output_surface_mac.h",
-      "compositor/gpu_output_surface_mac.mm",
       "compositor/gpu_process_transport_factory.cc",
       "compositor/gpu_process_transport_factory.h",
       "compositor/gpu_surfaceless_browser_compositor_output_surface.cc",
@@ -2287,7 +2289,7 @@
         # GL_TRIANGLES_ADJACENCY_EXT and GL_TRIANGLE_STRIP_ADJACENCY_EXT. They
         # get the same values but with different formatting (0xD vs 0x000D).
         # https://crbug.com/783666
-        "compositor/gpu_output_surface_mac.mm",
+        "compositor/gpu_output_surface_mac.cc",
       ]
     }
     if (enable_vulkan) {
diff --git a/content/browser/DEPS b/content/browser/DEPS
index fba3c0e..5c31b84ee5 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -91,6 +91,7 @@
   "+third_party/WebKit/public/platform/WebTouchEvent.h",
   "+third_party/WebKit/public/platform/WebTextInputType.h",
   "+third_party/WebKit/public/platform/mac/WebScrollbarTheme.h",
+  "+third_party/WebKit/public/platform/modules/locks/lock_manager.mojom.h",
   "+third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h",
   "+third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h",
   "+third_party/WebKit/public/platform/modules/notifications/WebNotificationConstants.h",
diff --git a/content/browser/accessibility/accessibility_tree_formatter_android.cc b/content/browser/accessibility/accessibility_tree_formatter_android.cc
index 0a0487518..359986e8 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_android.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -24,28 +24,12 @@
 namespace {
 
 const char* const BOOL_ATTRIBUTES[] = {
-  "checkable",
-  "checked",
-  "clickable",
-  "collection",
-  "collection_item",
-  "content_invalid",
-  "disabled",
-  "dismissable",
-  "editable_text",
-  "focusable",
-  "focused",
-  "has_non_empty_value",
-  "heading",
-  "hierarchical",
-  "invisible",
-  "link",
-  "multiline",
-  "password",
-  "range",
-  "scrollable",
-  "selected"
-};
+    "checkable",       "checked",         "clickable", "collection",
+    "collection_item", "content_invalid", "disabled",  "dismissable",
+    "editable_text",   "focusable",       "focused",   "has_non_empty_value",
+    "heading",         "hierarchical",    "invisible", "link",
+    "multiline",       "password",        "range",     "scrollable",
+    "selected",        "interesting"};
 
 const char* const STRING_ATTRIBUTES[] = {
     "name", "hint",
@@ -131,6 +115,7 @@
   dict->SetBoolean("password", android_node->IsPassword());
   dict->SetBoolean("scrollable", android_node->IsScrollable());
   dict->SetBoolean("selected", android_node->IsSelected());
+  dict->SetBoolean("interesting", android_node->IsInterestingOnAndroid());
 
   // String attributes.
   dict->SetString("name", android_node->GetText());
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 38bbf3a..99666dd 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -312,6 +312,14 @@
   if (ui::IsControl(GetRole()))
     return true;
 
+  // A non focusable child of a control is not interesting
+  const BrowserAccessibility* parent = PlatformGetParent();
+  while (parent != nullptr) {
+    if (ui::IsControl(parent->GetRole()))
+      return false;
+    parent = parent->PlatformGetParent();
+  }
+
   // Otherwise, the interesting nodes are leaf nodes with non-whitespace text.
   return PlatformIsLeaf() &&
       !base::ContainsOnlyChars(GetText(), base::kWhitespaceUTF16);
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index fe1875f..04ee55c4 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -177,13 +177,17 @@
 void BrowserAccessibilityManager::Initialize(
     const ui::AXTreeUpdate& initial_tree) {
   if (!tree_->Unserialize(initial_tree)) {
+    static auto* ax_tree_error = base::debug::AllocateCrashKeyString(
+        "ax_tree_error", base::debug::CrashKeySize::Size32);
+    static auto* ax_tree_update = base::debug::AllocateCrashKeyString(
+        "ax_tree_update", base::debug::CrashKeySize::Size64);
     // Temporarily log some additional crash keys so we can try to
     // figure out why we're getting bad accessibility trees here.
     // http://crbug.com/765490
     // Be sure to re-enable BrowserAccessibilityManagerTest.TestFatalError
     // when done (or delete it if no longer needed).
-    base::debug::SetCrashKeyValue("ax_tree_error", tree_->error());
-    base::debug::SetCrashKeyValue("ax_tree_update", initial_tree.ToString());
+    base::debug::SetCrashKeyString(ax_tree_error, tree_->error());
+    base::debug::SetCrashKeyString(ax_tree_update, initial_tree.ToString());
     LOG(FATAL) << tree_->error();
   }
 }
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index bcc21914..f0171fc0 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -243,6 +243,7 @@
   //
 
   AddFilter(filters, "hint=*");
+  AddFilter(filters, "interesting", Filter::DENY);
 
   //
   // General
@@ -320,6 +321,9 @@
   RunHtmlTest(FILE_PATH_LITERAL("a-onclick.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAIsInteresting) {
+  RunHtmlTest(FILE_PATH_LITERAL("isInteresting.html"));
+}
 
 #if defined(THREAD_SANITIZER)
 // See (crbug.com/708759).
diff --git a/content/browser/accessibility/fullscreen_browsertest.cc b/content/browser/accessibility/fullscreen_browsertest.cc
new file mode 100644
index 0000000..a93f1372
--- /dev/null
+++ b/content/browser/accessibility/fullscreen_browsertest.cc
@@ -0,0 +1,108 @@
+// 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/logging.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/accessibility_browser_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class AccessibilityFullscreenBrowserTest : public ContentBrowserTest {
+ public:
+  AccessibilityFullscreenBrowserTest() = default;
+  ~AccessibilityFullscreenBrowserTest() override = default;
+
+ protected:
+  BrowserAccessibility* FindButton(BrowserAccessibility* node) {
+    if (node->GetRole() == ui::AX_ROLE_BUTTON)
+      return node;
+    for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
+      if (BrowserAccessibility* button = FindButton(node->PlatformGetChild(i)))
+        return button;
+    }
+    return nullptr;
+  }
+
+  int CountLinks(BrowserAccessibility* node) {
+    if (node->GetRole() == ui::AX_ROLE_LINK)
+      return 1;
+    int links_in_children = 0;
+    for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
+      links_in_children += CountLinks(node->PlatformGetChild(i));
+    }
+    return links_in_children;
+  }
+};
+
+namespace {
+
+// FakeFullscreenDelegate simply stores the latest requested mod and reports it
+// back, which is all that is required for the renderer to enter fullscreen.
+class FakeFullscreenDelegate : public WebContentsDelegate {
+ public:
+  FakeFullscreenDelegate() = default;
+  ~FakeFullscreenDelegate() override = default;
+
+  void EnterFullscreenModeForTab(WebContents*, const GURL&) override {
+    is_fullscreen_ = true;
+  }
+
+  void ExitFullscreenModeForTab(WebContents*) override {
+    is_fullscreen_ = false;
+  }
+
+  bool IsFullscreenForTabOrPending(const WebContents*) const override {
+    return is_fullscreen_;
+  }
+
+ private:
+  bool is_fullscreen_ = false;
+  DISALLOW_COPY_AND_ASSIGN(FakeFullscreenDelegate);
+};
+
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(AccessibilityFullscreenBrowserTest,
+                       IgnoreElementsOutsideFullscreenElement) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  FakeFullscreenDelegate delegate;
+  shell()->web_contents()->SetDelegate(&delegate);
+
+  AccessibilityNotificationWaiter waiter(
+      shell()->web_contents(), ui::kAXModeComplete, ui::AX_EVENT_LOAD_COMPLETE);
+  GURL url(
+      embedded_test_server()->GetURL("/accessibility/fullscreen/links.html"));
+  NavigateToURL(shell(), url);
+  waiter.WaitForNotification();
+
+  WebContentsImpl* web_contents =
+      static_cast<WebContentsImpl*>(shell()->web_contents());
+  BrowserAccessibilityManager* manager =
+      web_contents->GetRootBrowserAccessibilityManager();
+
+  // Initially there are 3 links in the accessiblity tree.
+  EXPECT_EQ(3, CountLinks(manager->GetRoot()));
+
+  // Enter fullscreen by finding the button and performing the default action,
+  // which is to click it.
+  BrowserAccessibility* button = FindButton(manager->GetRoot());
+  ASSERT_NE(nullptr, button);
+  manager->DoDefaultAction(*button);
+
+  // Upon entering fullscreen, the page will change the button text to "Done".
+  WaitForAccessibilityTreeToContainNodeWithName(web_contents, "Done");
+
+  // Now, the two links outside of the fullscreen element are gone.
+  EXPECT_EQ(1, CountLinks(manager->GetRoot()));
+}
+
+}  // namespace content
diff --git a/content/browser/appcache/appcache_backend_impl.cc b/content/browser/appcache/appcache_backend_impl.cc
index 1fe4457..e3543ec6 100644
--- a/content/browser/appcache/appcache_backend_impl.cc
+++ b/content/browser/appcache/appcache_backend_impl.cc
@@ -88,35 +88,33 @@
 }
 
 bool AppCacheBackendImpl::GetStatusWithCallback(int host_id,
-                                                GetStatusCallback callback,
-                                                void* callback_param) {
+                                                GetStatusCallback* callback) {
   AppCacheHost* host = GetHost(host_id);
   if (!host)
     return false;
 
-  host->GetStatusWithCallback(std::move(callback), callback_param);
+  host->GetStatusWithCallback(std::move(*callback));
   return true;
 }
 
-bool AppCacheBackendImpl::StartUpdateWithCallback(int host_id,
-                                                  StartUpdateCallback callback,
-                                                  void* callback_param) {
+bool AppCacheBackendImpl::StartUpdateWithCallback(
+    int host_id,
+    StartUpdateCallback* callback) {
   AppCacheHost* host = GetHost(host_id);
   if (!host)
     return false;
 
-  host->StartUpdateWithCallback(std::move(callback), callback_param);
+  host->StartUpdateWithCallback(std::move(*callback));
   return true;
 }
 
 bool AppCacheBackendImpl::SwapCacheWithCallback(int host_id,
-                                                SwapCacheCallback callback,
-                                                void* callback_param) {
+                                                SwapCacheCallback* callback) {
   AppCacheHost* host = GetHost(host_id);
   if (!host)
     return false;
 
-  host->SwapCacheWithCallback(std::move(callback), callback_param);
+  host->SwapCacheWithCallback(std::move(*callback));
   return true;
 }
 
diff --git a/content/browser/appcache/appcache_backend_impl.h b/content/browser/appcache/appcache_backend_impl.h
index 96ee706a..abde0b3 100644
--- a/content/browser/appcache/appcache_backend_impl.h
+++ b/content/browser/appcache/appcache_backend_impl.h
@@ -42,15 +42,13 @@
   bool MarkAsForeignEntry(int host_id,
                           const GURL& document_url,
                           int64_t cache_document_was_loaded_from);
-  bool GetStatusWithCallback(int host_id,
-                             GetStatusCallback callback,
-                             void* callback_param);
-  bool StartUpdateWithCallback(int host_id,
-                               StartUpdateCallback callback,
-                               void* callback_param);
-  bool SwapCacheWithCallback(int host_id,
-                             SwapCacheCallback callback,
-                             void* callback_param);
+
+  // The xxxWithCallback functions take ownership of the callback iff the host
+  // is found (and the return value is true). If the result is false, the
+  // callback is still available to the caller of these methods.
+  bool GetStatusWithCallback(int host_id, GetStatusCallback* callback);
+  bool StartUpdateWithCallback(int host_id, StartUpdateCallback* callback);
+  bool SwapCacheWithCallback(int host_id, SwapCacheCallback* callback);
 
   // Returns a pointer to a registered host. The backend retains ownership.
   AppCacheHost* GetHost(int host_id) {
diff --git a/content/browser/appcache/appcache_dispatcher_host.cc b/content/browser/appcache/appcache_dispatcher_host.cc
index 86889c5..4ead75c6 100644
--- a/content/browser/appcache/appcache_dispatcher_host.cc
+++ b/content/browser/appcache/appcache_dispatcher_host.cc
@@ -11,21 +11,23 @@
 #include "content/browser/appcache/chrome_appcache_service.h"
 #include "content/browser/bad_message.h"
 #include "content/common/appcache_messages.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/common/browser_side_navigation_policy.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
 
 namespace content {
 
 AppCacheDispatcherHost::AppCacheDispatcherHost(
     ChromeAppCacheService* appcache_service,
-    int process_id)
-    : BrowserMessageFilter(AppCacheMsgStart),
-      appcache_service_(appcache_service),
+    int process_id,
+    base::WeakPtr<IPC::Sender> sender)
+    : appcache_service_(appcache_service),
       frontend_proxy_(this),
       process_id_(process_id),
-      weak_factory_(this) {
-}
+      sender_(std::move(sender)),
+      weak_factory_(this) {}
 
-void AppCacheDispatcherHost::OnChannelConnected(int32_t peer_pid) {
+void AppCacheDispatcherHost::InitBackend() {
   if (!appcache_service_.get())
     return;
 
@@ -33,37 +35,44 @@
                            process_id_);
 }
 
-bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(AppCacheDispatcherHost, message)
-    IPC_MESSAGE_HANDLER(AppCacheHostMsg_RegisterHost, OnRegisterHost)
-    IPC_MESSAGE_HANDLER(AppCacheHostMsg_UnregisterHost, OnUnregisterHost)
-    IPC_MESSAGE_HANDLER(AppCacheHostMsg_SetSpawningHostId, OnSetSpawningHostId)
-    IPC_MESSAGE_HANDLER(AppCacheHostMsg_GetResourceList, OnGetResourceList)
-    IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCache, OnSelectCache)
-    IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCacheForSharedWorker,
-                        OnSelectCacheForSharedWorker)
-    IPC_MESSAGE_HANDLER(AppCacheHostMsg_MarkAsForeignEntry,
-                        OnMarkAsForeignEntry)
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheHostMsg_GetStatus, OnGetStatus)
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheHostMsg_StartUpdate, OnStartUpdate)
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheHostMsg_SwapCache, OnSwapCache)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
+AppCacheDispatcherHost::~AppCacheDispatcherHost() = default;
 
-  return handled;
+// static
+void AppCacheDispatcherHost::Create(ChromeAppCacheService* appcache_service,
+                                    int process_id,
+                                    base::WeakPtr<IPC::Sender> sender,
+                                    mojom::AppCacheBackendRequest request) {
+  auto* appcache_dispatcher_host = new AppCacheDispatcherHost(
+      appcache_service, process_id, std::move(sender));
+
+  appcache_dispatcher_host->InitBackend();
+  mojo::MakeStrongBinding(base::WrapUnique(appcache_dispatcher_host),
+                          std::move(request));
 }
 
-AppCacheDispatcherHost::~AppCacheDispatcherHost() {
+void SendOnUIThread(base::WeakPtr<IPC::Sender> sender,
+                    std::unique_ptr<IPC::Message> msg) {
+  if (sender) {
+    sender->Send(msg.release());
+  }
 }
 
-void AppCacheDispatcherHost::OnRegisterHost(int host_id) {
+bool AppCacheDispatcherHost::Send(IPC::Message* msg) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&SendOnUIThread, sender_, base::WrapUnique(msg)));
+  // The callers of this send method are ignoring the result anyway.
+  return true;
+}
+
+void AppCacheDispatcherHost::RegisterHost(int32_t host_id) {
   if (appcache_service_.get()) {
     // PlzNavigate
     // The AppCacheHost could have been precreated in which case we want to
     // register it with the backend here.
     if (IsBrowserSideNavigationEnabled()) {
-      std::unique_ptr<AppCacheHost> host =
+      std::unique_ptr<content::AppCacheHost> host =
           AppCacheNavigationHandleCore::GetPrecreatedHost(host_id);
       if (host.get()) {
         backend_impl_.RegisterPrecreatedHost(std::move(host));
@@ -71,163 +80,114 @@
       }
     }
     if (!backend_impl_.RegisterHost(host_id)) {
-      bad_message::ReceivedBadMessage(this, bad_message::ACDH_REGISTER);
+      mojo::ReportBadMessage("ACDH_REGISTER");
     }
   }
 }
 
-void AppCacheDispatcherHost::OnUnregisterHost(int host_id) {
+void AppCacheDispatcherHost::UnregisterHost(int32_t host_id) {
   if (appcache_service_.get()) {
     if (!backend_impl_.UnregisterHost(host_id)) {
-      bad_message::ReceivedBadMessage(this, bad_message::ACDH_UNREGISTER);
+      mojo::ReportBadMessage("ACDH_UNREGISTER");
     }
   }
 }
 
-void AppCacheDispatcherHost::OnSetSpawningHostId(
-    int host_id, int spawning_host_id) {
+void AppCacheDispatcherHost::SetSpawningHostId(int32_t host_id,
+                                               int spawning_host_id) {
   if (appcache_service_.get()) {
     if (!backend_impl_.SetSpawningHostId(host_id, spawning_host_id))
-      bad_message::ReceivedBadMessage(this, bad_message::ACDH_SET_SPAWNING);
+      mojo::ReportBadMessage("ACDH_SET_SPAWNING");
   }
 }
 
-void AppCacheDispatcherHost::OnSelectCache(
-    int host_id,
-    const GURL& document_url,
-    int64_t cache_document_was_loaded_from,
-    const GURL& opt_manifest_url) {
+void AppCacheDispatcherHost::SelectCache(int32_t host_id,
+                                         const GURL& document_url,
+                                         int64_t cache_document_was_loaded_from,
+                                         const GURL& opt_manifest_url) {
   if (appcache_service_.get()) {
     if (!backend_impl_.SelectCache(host_id, document_url,
                                    cache_document_was_loaded_from,
                                    opt_manifest_url)) {
-      bad_message::ReceivedBadMessage(this, bad_message::ACDH_SELECT_CACHE);
+      mojo::ReportBadMessage("ACDH_SELECT_CACHE");
     }
   } else {
-    frontend_proxy_.OnCacheSelected(host_id, AppCacheInfo());
+    frontend_proxy_.OnCacheSelected(host_id, std::move(AppCacheInfo()));
   }
 }
 
-void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(int host_id,
-                                                          int64_t appcache_id) {
+void AppCacheDispatcherHost::SelectCacheForSharedWorker(int32_t host_id,
+                                                        int64_t appcache_id) {
   if (appcache_service_.get()) {
     if (!backend_impl_.SelectCacheForSharedWorker(host_id, appcache_id))
-      bad_message::ReceivedBadMessage(
-          this, bad_message::ACDH_SELECT_CACHE_FOR_SHARED_WORKER);
+      mojo::ReportBadMessage("ACDH_SELECT_CACHE_FOR_SHARED_WORKER");
   } else {
-    frontend_proxy_.OnCacheSelected(host_id, AppCacheInfo());
+    frontend_proxy_.OnCacheSelected(host_id, std::move(AppCacheInfo()));
   }
 }
 
-void AppCacheDispatcherHost::OnMarkAsForeignEntry(
-    int host_id,
+void AppCacheDispatcherHost::MarkAsForeignEntry(
+    int32_t host_id,
     const GURL& document_url,
     int64_t cache_document_was_loaded_from) {
   if (appcache_service_.get()) {
     if (!backend_impl_.MarkAsForeignEntry(host_id, document_url,
                                           cache_document_was_loaded_from)) {
-      bad_message::ReceivedBadMessage(this,
-                                      bad_message::ACDH_MARK_AS_FOREIGN_ENTRY);
+      mojo::ReportBadMessage("ACDH_MARK_AS_FOREIGN_ENTRY");
     }
   }
 }
 
-void AppCacheDispatcherHost::OnGetResourceList(
-    int host_id, std::vector<AppCacheResourceInfo>* params) {
-  if (appcache_service_.get())
-    backend_impl_.GetResourceList(host_id, params);
-}
-
-void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) {
-  if (pending_reply_msg_) {
-    bad_message::ReceivedBadMessage(
-        this, bad_message::ACDH_PENDING_REPLY_IN_GET_STATUS);
-    delete reply_msg;
-    return;
-  }
-
-  pending_reply_msg_.reset(reply_msg);
+void AppCacheDispatcherHost::GetResourceList(int32_t host_id,
+                                             GetResourceListCallback callback) {
+  std::vector<AppCacheResourceInfo> params;
+  std::vector<mojom::AppCacheResourceInfoPtr> out;
   if (appcache_service_.get()) {
-    if (!backend_impl_.GetStatusWithCallback(
-            host_id,
-            base::BindOnce(&AppCacheDispatcherHost::GetStatusCallback,
-                           weak_factory_.GetWeakPtr()),
-            reply_msg)) {
-      bad_message::ReceivedBadMessage(this, bad_message::ACDH_GET_STATUS);
-    }
-    return;
-  }
+    backend_impl_.GetResourceList(host_id, &params);
 
-  GetStatusCallback(AppCacheStatus::APPCACHE_STATUS_UNCACHED, reply_msg);
+    // Box up params for output.
+    out.reserve(params.size());
+    for (auto& p : params) {
+      out.emplace_back(base::in_place, std::move(p));
+    }
+  }
+  std::move(callback).Run(std::move(out));
 }
 
-void AppCacheDispatcherHost::OnStartUpdate(int host_id,
-                                           IPC::Message* reply_msg) {
-  if (pending_reply_msg_) {
-    bad_message::ReceivedBadMessage(
-        this, bad_message::ACDH_PENDING_REPLY_IN_START_UPDATE);
-    delete reply_msg;
-    return;
-  }
-
-  pending_reply_msg_.reset(reply_msg);
+void AppCacheDispatcherHost::GetStatus(int32_t host_id,
+                                       GetStatusCallback callback) {
   if (appcache_service_.get()) {
-    if (!backend_impl_.StartUpdateWithCallback(
-            host_id,
-            base::BindOnce(&AppCacheDispatcherHost::StartUpdateCallback,
-                           weak_factory_.GetWeakPtr()),
-            reply_msg)) {
-      bad_message::ReceivedBadMessage(this, bad_message::ACDH_START_UPDATE);
+    if (backend_impl_.GetStatusWithCallback(host_id, &callback)) {
+      return;
+    } else {
+      mojo::ReportBadMessage("ACDH_GET_STATUS");
     }
-    return;
   }
-
-  StartUpdateCallback(false, reply_msg);
+  std::move(callback).Run(AppCacheStatus::APPCACHE_STATUS_UNCACHED);
 }
 
-void AppCacheDispatcherHost::OnSwapCache(int host_id, IPC::Message* reply_msg) {
-  if (pending_reply_msg_) {
-    bad_message::ReceivedBadMessage(
-        this, bad_message::ACDH_PENDING_REPLY_IN_SWAP_CACHE);
-    delete reply_msg;
-    return;
-  }
-
-  pending_reply_msg_.reset(reply_msg);
+void AppCacheDispatcherHost::StartUpdate(int32_t host_id,
+                                         StartUpdateCallback callback) {
   if (appcache_service_.get()) {
-    if (!backend_impl_.SwapCacheWithCallback(
-            host_id,
-            base::BindOnce(&AppCacheDispatcherHost::SwapCacheCallback,
-                           weak_factory_.GetWeakPtr()),
-            reply_msg)) {
-      bad_message::ReceivedBadMessage(this, bad_message::ACDH_SWAP_CACHE);
+    if (backend_impl_.StartUpdateWithCallback(host_id, &callback)) {
+      return;
+    } else {
+      mojo::ReportBadMessage("ACDH_START_UPDATE");
     }
-    return;
   }
-
-  SwapCacheCallback(false, reply_msg);
+  std::move(callback).Run(false);
 }
 
-void AppCacheDispatcherHost::GetStatusCallback(
-    AppCacheStatus status, void* param) {
-  IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param);
-  DCHECK_EQ(pending_reply_msg_.get(), reply_msg);
-  AppCacheHostMsg_GetStatus::WriteReplyParams(reply_msg, status);
-  Send(pending_reply_msg_.release());
-}
-
-void AppCacheDispatcherHost::StartUpdateCallback(bool result, void* param) {
-  IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param);
-  DCHECK_EQ(pending_reply_msg_.get(), reply_msg);
-  AppCacheHostMsg_StartUpdate::WriteReplyParams(reply_msg, result);
-  Send(pending_reply_msg_.release());
-}
-
-void AppCacheDispatcherHost::SwapCacheCallback(bool result, void* param) {
-  IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param);
-  DCHECK_EQ(pending_reply_msg_.get(), reply_msg);
-  AppCacheHostMsg_SwapCache::WriteReplyParams(reply_msg, result);
-  Send(pending_reply_msg_.release());
+void AppCacheDispatcherHost::SwapCache(int32_t host_id,
+                                       SwapCacheCallback callback) {
+  if (appcache_service_.get()) {
+    if (backend_impl_.SwapCacheWithCallback(host_id, &callback)) {
+      return;
+    } else {
+      mojo::ReportBadMessage("ACDH_SWAP_CACHE");
+    }
+  }
+  std::move(callback).Run(false);
 }
 
 }  // namespace content
diff --git a/content/browser/appcache/appcache_dispatcher_host.h b/content/browser/appcache/appcache_dispatcher_host.h
index 39764ef..e28f110 100644
--- a/content/browser/appcache/appcache_dispatcher_host.h
+++ b/content/browser/appcache/appcache_dispatcher_host.h
@@ -16,6 +16,7 @@
 #include "base/process/process.h"
 #include "content/browser/appcache/appcache_backend_impl.h"
 #include "content/browser/appcache/appcache_frontend_proxy.h"
+#include "content/common/appcache.mojom.h"
 #include "content/public/browser/browser_message_filter.h"
 
 namespace content {
@@ -25,50 +26,52 @@
 // its child processes. There is a distinct host for each child process.
 // Messages are handled on the IO thread. The RenderProcessHostImpl creates
 // an instance and delegates calls to it.
-class AppCacheDispatcherHost : public BrowserMessageFilter {
+class AppCacheDispatcherHost : public IPC::Sender,
+                               public mojom::AppCacheBackend {
  public:
   AppCacheDispatcherHost(ChromeAppCacheService* appcache_service,
-                         int process_id);
-
-  // BrowserIOMessageFilter implementation
-  void OnChannelConnected(int32_t peer_pid) override;
-  bool OnMessageReceived(const IPC::Message& message) override;
-
- protected:
+                         int process_id,
+                         base::WeakPtr<IPC::Sender> sender);
   ~AppCacheDispatcherHost() override;
 
+  static void Create(ChromeAppCacheService* appcache_service,
+                     int process_id,
+                     base::WeakPtr<IPC::Sender> sender,
+                     mojom::AppCacheBackendRequest request);
+
+  void InitBackend();
+
+  bool Send(IPC::Message* msg) override;
+
  private:
-  // IPC message handlers
-  void OnRegisterHost(int host_id);
-  void OnUnregisterHost(int host_id);
-  void OnSetSpawningHostId(int host_id, int spawning_host_id);
-  void OnSelectCache(int host_id,
-                     const GURL& document_url,
-                     int64_t cache_document_was_loaded_from,
-                     const GURL& opt_manifest_url);
-  void OnSelectCacheForSharedWorker(int host_id, int64_t appcache_id);
-  void OnMarkAsForeignEntry(int host_id,
-                            const GURL& document_url,
-                            int64_t cache_document_was_loaded_from);
-  void OnGetStatus(int host_id, IPC::Message* reply_msg);
-  void OnStartUpdate(int host_id, IPC::Message* reply_msg);
-  void OnSwapCache(int host_id, IPC::Message* reply_msg);
-  void OnGetResourceList(
-      int host_id,
-      std::vector<AppCacheResourceInfo>* resource_infos);
-  void GetStatusCallback(AppCacheStatus status, void* param);
-  void StartUpdateCallback(bool result, void* param);
-  void SwapCacheCallback(bool result, void* param);
+  // mojom::AppCacheHost
+  void RegisterHost(int32_t host_id) override;
+  void UnregisterHost(int32_t host_id) override;
+  void SetSpawningHostId(int32_t host_id, int spawning_host_id) override;
+  void SelectCache(int32_t host_id,
+                   const GURL& document_url,
+                   int64_t cache_document_was_loaded_from,
+                   const GURL& opt_manifest_url) override;
+  void SelectCacheForSharedWorker(int32_t host_id,
+                                  int64_t appcache_id) override;
+  void MarkAsForeignEntry(int32_t host_id,
+                          const GURL& document_url,
+                          int64_t cache_document_was_loaded_from) override;
+  void GetStatus(int32_t host_id, GetStatusCallback callback) override;
+  void StartUpdate(int32_t host_id, StartUpdateCallback callback) override;
+  void SwapCache(int32_t host_id, SwapCacheCallback callback) override;
+  void GetResourceList(int32_t host_id,
+                       GetResourceListCallback callback) override;
 
   scoped_refptr<ChromeAppCacheService> appcache_service_;
   AppCacheFrontendProxy frontend_proxy_;
   AppCacheBackendImpl backend_impl_;
 
-  std::unique_ptr<IPC::Message> pending_reply_msg_;
-
   // The corresponding ChildProcessHost object's id().
   int process_id_;
 
+  base::WeakPtr<IPC::Sender> sender_;
+
   base::WeakPtrFactory<AppCacheDispatcherHost> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(AppCacheDispatcherHost);
diff --git a/content/browser/appcache/appcache_host.cc b/content/browser/appcache/appcache_host.cc
index 13d4101..634dd44 100644
--- a/content/browser/appcache/appcache_host.cc
+++ b/content/browser/appcache/appcache_host.cc
@@ -62,7 +62,6 @@
       frontend_(frontend),
       service_(service),
       storage_(service->storage()),
-      pending_callback_param_(nullptr),
       main_resource_was_namespace_entry_(false),
       main_resource_blocked_(false),
       associated_cache_info_pending_(false),
@@ -146,7 +145,6 @@
       frontend_->OnContentBlocked(host_id_, manifest_url);
       return true;
     }
-
     // Note: The client detects if the document was not loaded using HTTP GET
     // and invokes SelectCache without a manifest url, so that detection step
     // is also skipped here. See WebApplicationCacheHostImpl.cc
@@ -155,7 +153,6 @@
     LoadOrCreateGroup(manifest_url);
     return true;
   }
-
   // TODO(michaeln): If there was a manifest URL, the user agent may report
   // to the user that it was ignored, to aid in application development.
   FinishCacheSelection(nullptr, nullptr);
@@ -194,14 +191,12 @@
   return true;
 }
 
-void AppCacheHost::GetStatusWithCallback(GetStatusCallback callback,
-                                         void* callback_param) {
+void AppCacheHost::GetStatusWithCallback(GetStatusCallback callback) {
   DCHECK(pending_start_update_callback_.is_null() &&
          pending_swap_cache_callback_.is_null() &&
          pending_get_status_callback_.is_null());
 
   pending_get_status_callback_ = std::move(callback);
-  pending_callback_param_ = callback_param;
   if (is_selection_pending())
     return;
 
@@ -211,19 +206,15 @@
 void AppCacheHost::DoPendingGetStatus() {
   DCHECK_EQ(false, pending_get_status_callback_.is_null());
 
-  std::move(pending_get_status_callback_)
-      .Run(GetStatus(), pending_callback_param_);
-  pending_callback_param_ = nullptr;
+  std::move(pending_get_status_callback_).Run(GetStatus());
 }
 
-void AppCacheHost::StartUpdateWithCallback(StartUpdateCallback callback,
-                                           void* callback_param) {
+void AppCacheHost::StartUpdateWithCallback(StartUpdateCallback callback) {
   DCHECK(pending_start_update_callback_.is_null() &&
          pending_swap_cache_callback_.is_null() &&
          pending_get_status_callback_.is_null());
 
   pending_start_update_callback_ = std::move(callback);
-  pending_callback_param_ = callback_param;
   if (is_selection_pending())
     return;
 
@@ -243,19 +234,16 @@
     }
   }
 
-  std::move(pending_start_update_callback_)
-      .Run(success, pending_callback_param_);
-  pending_callback_param_ = nullptr;
+  std::move(pending_start_update_callback_).Run(success);
 }
 
-void AppCacheHost::SwapCacheWithCallback(SwapCacheCallback callback,
-                                         void* callback_param) {
+void AppCacheHost::SwapCacheWithCallback(SwapCacheCallback callback) {
   DCHECK(pending_start_update_callback_.is_null() &&
          pending_swap_cache_callback_.is_null() &&
          pending_get_status_callback_.is_null());
 
   pending_swap_cache_callback_ = std::move(callback);
-  pending_callback_param_ = callback_param;
+
   if (is_selection_pending())
     return;
 
@@ -279,8 +267,7 @@
     }
   }
 
-  std::move(pending_swap_cache_callback_).Run(success, pending_callback_param_);
-  pending_callback_param_ = nullptr;
+  std::move(pending_swap_cache_callback_).Run(success);
 }
 
 void AppCacheHost::SetSpawningHostId(
diff --git a/content/browser/appcache/appcache_host.h b/content/browser/appcache/appcache_host.h
index 27f31ab..288d636 100644
--- a/content/browser/appcache/appcache_host.h
+++ b/content/browser/appcache/appcache_host.h
@@ -53,9 +53,9 @@
 class AppCacheTest;
 class AppCacheUpdateJobTest;
 
-typedef base::OnceCallback<void(AppCacheStatus, void*)> GetStatusCallback;
-typedef base::OnceCallback<void(bool, void*)> StartUpdateCallback;
-typedef base::OnceCallback<void(bool, void*)> SwapCacheCallback;
+typedef base::OnceCallback<void(AppCacheStatus)> GetStatusCallback;
+typedef base::OnceCallback<void(bool)> StartUpdateCallback;
+typedef base::OnceCallback<void(bool)> SwapCacheCallback;
 
 // Server-side representation of an application cache host.
 class CONTENT_EXPORT AppCacheHost
@@ -91,10 +91,9 @@
   bool SelectCacheForSharedWorker(int64_t appcache_id);
   bool MarkAsForeignEntry(const GURL& document_url,
                           int64_t cache_document_was_loaded_from);
-  void GetStatusWithCallback(GetStatusCallback callback, void* callback_param);
-  void StartUpdateWithCallback(StartUpdateCallback callback,
-                               void* callback_param);
-  void SwapCacheWithCallback(SwapCacheCallback callback, void* callback_param);
+  void GetStatusWithCallback(GetStatusCallback callback);
+  void StartUpdateWithCallback(StartUpdateCallback callback);
+  void SwapCacheWithCallback(SwapCacheCallback callback);
 
   // Called prior to the main resource load. When the system contains multiple
   // candidates for a main resource load, the appcache preferred by the host
@@ -326,7 +325,6 @@
   GetStatusCallback pending_get_status_callback_;
   StartUpdateCallback pending_start_update_callback_;
   SwapCacheCallback pending_swap_cache_callback_;
-  void* pending_callback_param_;
 
   // True if an intercept or fallback namespace resource was
   // delivered as the main resource.
diff --git a/content/browser/appcache/appcache_host_unittest.cc b/content/browser/appcache/appcache_host_unittest.cc
index 3db3424..aaad1a4 100644
--- a/content/browser/appcache/appcache_host_unittest.cc
+++ b/content/browser/appcache/appcache_host_unittest.cc
@@ -130,20 +130,13 @@
     ~MockQuotaManagerProxy() override {}
   };
 
-  void GetStatusCallback(AppCacheStatus status, void* param) {
+  void GetStatusCallback(AppCacheStatus status) {
     last_status_result_ = status;
-    last_callback_param_ = param;
   }
 
-  void StartUpdateCallback(bool result, void* param) {
-    last_start_result_ = result;
-    last_callback_param_ = param;
-  }
+  void StartUpdateCallback(bool result) { last_start_result_ = result; }
 
-  void SwapCacheCallback(bool result, void* param) {
-    last_swap_result_ = result;
-    last_callback_param_ = param;
-  }
+  void SwapCacheCallback(bool result) { last_swap_result_ = result; }
 
   base::test::ScopedTaskEnvironment scoped_task_environment_;
 
@@ -157,7 +150,6 @@
   AppCacheStatus last_status_result_;
   bool last_swap_result_;
   bool last_start_result_;
-  void* last_callback_param_;
 };
 
 TEST_F(AppCacheHostTest, Basic) {
@@ -172,26 +164,18 @@
   // See that the callbacks are delivered immediately
   // and respond as if there is no cache selected.
   last_status_result_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
-  host.GetStatusWithCallback(std::move(get_status_callback_),
-                             reinterpret_cast<void*>(1));
+  host.GetStatusWithCallback(std::move(get_status_callback_));
   EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED, last_status_result_);
-  EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
 
   last_start_result_ = true;
-  host.StartUpdateWithCallback(
-      base::BindOnce(&AppCacheHostTest::StartUpdateCallback,
-                     base::Unretained(this)),
-      reinterpret_cast<void*>(2));
+  host.StartUpdateWithCallback(base::BindOnce(
+      &AppCacheHostTest::StartUpdateCallback, base::Unretained(this)));
   EXPECT_FALSE(last_start_result_);
-  EXPECT_EQ(reinterpret_cast<void*>(2), last_callback_param_);
 
   last_swap_result_ = true;
-  host.SwapCacheWithCallback(
-      base::BindOnce(&AppCacheHostTest::SwapCacheCallback,
-                     base::Unretained(this)),
-      reinterpret_cast<void*>(3));
+  host.SwapCacheWithCallback(base::BindOnce(
+      &AppCacheHostTest::SwapCacheCallback, base::Unretained(this)));
   EXPECT_FALSE(last_swap_result_);
-  EXPECT_EQ(reinterpret_cast<void*>(3), last_callback_param_);
 }
 
 TEST_F(AppCacheHostTest, SelectNoCache) {
@@ -304,11 +288,8 @@
 
   // The callback should not occur until we finish cache selection.
   last_status_result_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
-  last_callback_param_ = reinterpret_cast<void*>(-1);
-  host.GetStatusWithCallback(std::move(get_status_callback_),
-                             reinterpret_cast<void*>(1));
+  host.GetStatusWithCallback(std::move(get_status_callback_));
   EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_OBSOLETE, last_status_result_);
-  EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
 
   // Satisfy the load with NULL, a failure.
   host.OnCacheLoaded(nullptr, kMockCacheId);
@@ -322,7 +303,6 @@
 
   // Callback should have fired upon completing the cache load too.
   EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED, last_status_result_);
-  EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
 }
 
 TEST_F(AppCacheHostTest, FailedGroupLoad) {
@@ -337,11 +317,8 @@
 
   // The callback should not occur until we finish cache selection.
   last_status_result_ = AppCacheStatus::APPCACHE_STATUS_OBSOLETE;
-  last_callback_param_ = reinterpret_cast<void*>(-1);
-  host.GetStatusWithCallback(std::move(get_status_callback_),
-                             reinterpret_cast<void*>(1));
+  host.GetStatusWithCallback(std::move(get_status_callback_));
   EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_OBSOLETE, last_status_result_);
-  EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
 
   // Satisfy the load will NULL, a failure.
   host.OnGroupLoaded(nullptr, kMockManifestUrl);
@@ -355,7 +332,6 @@
 
   // Callback should have fired upon completing the group load.
   EXPECT_EQ(AppCacheStatus::APPCACHE_STATUS_UNCACHED, last_status_result_);
-  EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
 }
 
 TEST_F(AppCacheHostTest, SetSwappableCache) {
diff --git a/content/browser/bad_message.cc b/content/browser/bad_message.cc
index 34007f1e..94b6c46 100644
--- a/content/browser/bad_message.cc
+++ b/content/browser/bad_message.cc
@@ -5,7 +5,6 @@
 #include "content/browser/bad_message.h"
 
 #include "base/bind.h"
-#include "base/debug/crash_logging.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
@@ -20,10 +19,12 @@
 namespace {
 
 void LogBadMessage(BadMessageReason reason) {
+  static auto* bad_message_reason = base::debug::AllocateCrashKeyString(
+      "bad_message_reason", base::debug::CrashKeySize::Size32);
+
   LOG(ERROR) << "Terminating renderer for bad IPC message, reason " << reason;
   UMA_HISTOGRAM_SPARSE_SLOWLY("Stability.BadMessageTerminated.Content", reason);
-  base::debug::SetCrashKeyValue("bad_message_reason",
-                                base::IntToString(reason));
+  base::debug::SetCrashKeyString(bad_message_reason, base::IntToString(reason));
 }
 
 void ReceivedBadMessageOnUIThread(int render_process_id,
@@ -66,5 +67,11 @@
   filter->ShutdownForBadMessage();
 }
 
+base::debug::CrashKeyString* GetMojoErrorCrashKey() {
+  static auto* crash_key = base::debug::AllocateCrashKeyString(
+      "mojo-message-error", base::debug::CrashKeySize::Size256);
+  return crash_key;
+}
+
 }  // namespace bad_message
 }  // namespace content
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 7c9123c..c0fbefd 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_BAD_MESSAGE_H_
 #define CONTENT_BROWSER_BAD_MESSAGE_H_
 
+#include "base/debug/crash_logging.h"
 #include "content/common/content_export.h"
 
 namespace content {
@@ -235,6 +236,10 @@
 // for the |reason|, and terminates the process for |filter|.
 void ReceivedBadMessage(BrowserMessageFilter* filter, BadMessageReason reason);
 
+// Returns a crash key named "mojo-message-error" for storing Mojo error
+// messages.
+base::debug::CrashKeyString* GetMojoErrorCrashKey();
+
 }  // namespace bad_message
 }  // namespace content
 
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index ff2ab2cb..11f3f2c 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -26,6 +26,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "components/tracing/common/tracing_switches.h"
+#include "content/browser/bad_message.h"
 #include "content/browser/histogram_controller.h"
 #include "content/browser/loader/resource_message_filter.h"
 #include "content/browser/service_manager/service_manager_context.h"
@@ -599,7 +600,8 @@
   // Create a memory dump with the error message captured in a crash key value.
   // This will make it easy to determine details about what interface call
   // failed.
-  base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
+  base::debug::ScopedCrashKeyString scoped_error_key(
+      bad_message::GetMojoErrorCrashKey(), error);
   base::debug::DumpWithoutCrashing();
   process->child_process_->GetProcess().Terminate(
       RESULT_CODE_KILLED_BAD_MESSAGE, false);
diff --git a/content/browser/browser_side_navigation_browsertest.cc b/content/browser/browser_side_navigation_browsertest.cc
index 4a3e30e..d33c5e9 100644
--- a/content/browser/browser_side_navigation_browsertest.cc
+++ b/content/browser/browser_side_navigation_browsertest.cc
@@ -11,6 +11,7 @@
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/frame_host/navigation_handle_impl.h"
 #include "content/browser/frame_host/navigation_request.h"
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/frame_messages.h"
 #include "content/common/site_isolation_policy.h"
@@ -23,6 +24,7 @@
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/controllable_http_response.h"
 #include "content/public/test/navigation_handle_observer.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/shell/browser/shell.h"
@@ -38,10 +40,11 @@
 
 namespace content {
 
-class BrowserSideNavigationBrowserTest : public ContentBrowserTest {
- public:
-  BrowserSideNavigationBrowserTest() {}
-
+// Test with BrowserSideNavigation enabled (aka PlzNavigate).
+// If you don't need a custom embedded test server, please use the next class
+// below (BrowserSideNavigationBrowserTest), it will automatically start the
+// default server.
+class BrowserSideNavigationBaseBrowserTest : public ContentBrowserTest {
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     command_line->AppendSwitch(switches::kEnableBrowserSideNavigation);
@@ -49,6 +52,14 @@
 
   void SetUpOnMainThread() override {
     host_resolver()->AddRule("*", "127.0.0.1");
+  }
+};
+
+class BrowserSideNavigationBrowserTest
+    : public BrowserSideNavigationBaseBrowserTest {
+ protected:
+  void SetUpOnMainThread() override {
+    BrowserSideNavigationBaseBrowserTest::SetUpOnMainThread();
     ASSERT_TRUE(embedded_test_server()->Start());
   }
 };
@@ -514,4 +525,61 @@
   EXPECT_EQ(url2, shell()->web_contents()->GetLastCommittedURL());
 }
 
+// Navigation are started in the browser process. After the headers are
+// received, the URLLoaderClient is transfered from the browser process to the
+// renderer process. This test ensures that when the the URLLoader is deleted
+// (in the browser process), the URLLoaderClient (in the renderer process) stops
+// properly.
+IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+                       CancelRequestAfterReadyToCommit) {
+  // This test cancels the request using the ResourceDispatchHost. With the
+  // NetworkService, it is not used so the request is not canceled.
+  // TODO(arthursonzogni): Find a way to cancel a request from the browser
+  // with the NetworkService.
+  if (base::FeatureList::IsEnabled(features::kNetworkService))
+    return;
+
+  ControllableHttpResponse response(embedded_test_server(), "/main_document");
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // 1) Load a new document. Commit the navigation but do not send the full
+  //    response's body.
+  GURL url(embedded_test_server()->GetURL("/main_document"));
+  TestNavigationManager navigation_manager(shell()->web_contents(), url);
+  shell()->LoadURL(url);
+
+  // Let the navigation start.
+  EXPECT_TRUE(navigation_manager.WaitForRequestStart());
+  navigation_manager.ResumeNavigation();
+
+  // The server sends the first part of the response and waits.
+  response.WaitForRequest();
+  response.Send(
+      "HTTP/1.1 200 OK\r\n"
+      "Content-Type: text/html; charset=utf-8\r\n"
+      "\r\n"
+      "<html><body> ... ");
+
+  EXPECT_TRUE(navigation_manager.WaitForResponse());
+  GlobalRequestID global_id =
+      navigation_manager.GetNavigationHandle()->GetGlobalRequestID();
+  navigation_manager.ResumeNavigation();
+
+  // The navigation commits successfully. The renderer is waiting for the
+  // response's body.
+  navigation_manager.WaitForNavigationFinished();
+
+  // 2) The ResourceDispatcherHost cancels the request.
+  auto cancel_request = [](GlobalRequestID global_id) {
+    ResourceDispatcherHostImpl* rdh =
+        static_cast<ResourceDispatcherHostImpl*>(ResourceDispatcherHost::Get());
+    rdh->CancelRequest(global_id.child_id, global_id.request_id);
+  };
+  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+                          base::BindOnce(cancel_request, global_id));
+
+  // 3) Check that the load stops properly.
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+}
+
 }  // namespace content
diff --git a/content/browser/browsing_data/clear_site_data_throttle.cc b/content/browser/browsing_data/clear_site_data_throttle.cc
index 6ae2bec..f05e690 100644
--- a/content/browser/browsing_data/clear_site_data_throttle.cc
+++ b/content/browser/browsing_data/clear_site_data_throttle.cc
@@ -473,10 +473,7 @@
     } else if (input_types[i] == kDatatypeStorage) {
       data_type = clear_storage;
     } else if (input_types[i] == kDatatypeCache) {
-      delegate->AddMessage(
-          current_url, "The \"cache\" datatype is temporarily not supported.",
-          CONSOLE_MESSAGE_LEVEL_ERROR);
-      continue;
+      data_type = clear_cache;
     } else {
       delegate->AddMessage(
           current_url,
diff --git a/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
index 3173fde8..c466e67 100644
--- a/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
+++ b/content/browser/browsing_data/clear_site_data_throttle_browsertest.cc
@@ -760,15 +760,11 @@
   } test_cases[] = {
       {"\"cookies\"", true, false, false},
       {"\"storage\"", false, true, false},
-
-      // TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
-      {"\"cache\"", false, false, false},
+      {"\"cache\"", false, false, true},
       {"\"cookies\", \"storage\"", true, true, false},
-
-      // TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
-      {"\"cookies\", \"cache\"", true, false, false},
-      {"\"storage\", \"cache\"", false, true, false},
-      {"\"cookies\", \"storage\", \"cache\"", true, true, false},
+      {"\"cookies\", \"cache\"", true, false, true},
+      {"\"storage\", \"cache\"", false, true, true},
+      {"\"cookies\", \"storage\", \"cache\"", true, true, true},
   };
 
   for (const TestCase& test_case : test_cases) {
@@ -855,9 +851,7 @@
 // entries are actually written to the disk. Other tests using CacheTestUtil
 // show that a timeout of around 1s between cache operations is necessary to
 // avoid flakiness.
-// TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
-IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest,
-                       DISABLED_CacheIntegrationTest) {
+IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, CacheIntegrationTest) {
   const int kTimeoutMs = 1000;
 
   CacheTestUtil util(
diff --git a/content/browser/browsing_data/clear_site_data_throttle_unittest.cc b/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
index 6406afa..408dbd1 100644
--- a/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
+++ b/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
@@ -179,24 +179,17 @@
       // One data type.
       {"\"cookies\"", true, false, false},
       {"\"storage\"", false, true, false},
-
-      // TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
-      // Therefore, a header consisting solely of the "cache" parameter is
-      // invalid. As this test verifies the behavior of Clear-Site-Data with
-      // valid headers, we will omit such test case.
+      {"\"cache\"", false, false, true},
 
       // Two data types.
       {"\"cookies\", \"storage\"", true, true, false},
-
-      // TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
-      {"\"cookies\", \"cache\"", true, false, false},
-      {"\"storage\", \"cache\"", false, true, false},
+      {"\"cookies\", \"cache\"", true, false, true},
+      {"\"storage\", \"cache\"", false, true, true},
 
       // Three data types.
-      // TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
-      {"\"storage\", \"cache\", \"cookies\"", true, true, false},
-      {"\"cache\", \"cookies\", \"storage\"", true, true, false},
-      {"\"cookies\", \"storage\", \"cache\"", true, true, false},
+      {"\"storage\", \"cache\", \"cookies\"", true, true, true},
+      {"\"cache\", \"cookies\", \"storage\"", true, true, true},
+      {"\"cookies\", \"storage\", \"cache\"", true, true, true},
 
       // The wildcard datatype is not yet shipped.
       {"\"*\", \"storage\"", false, true, false},
@@ -214,16 +207,15 @@
 
       // Unknown types are ignored, but we still proceed with the deletion for
       // those that we recognize.
-      {"\"storage\", \"foo\"", false, true, false},
+      {"\"cache\", \"foo\"", false, false, true},
   };
 
   std::vector<TestCase> experimental_test_cases = {
       // Wildcard.
-      // TODO(crbug.com/762417): The "cache" parameter is temporarily disabled.
-      {"\"*\"", true, true, false},
-      {"\"*\", \"storage\"", true, true, false},
-      {"\"cache\", \"*\", \"storage\"", true, true, false},
-      {"\"*\", \"cookies\", \"*\"", true, true, false},
+      {"\"*\"", true, true, true},
+      {"\"*\", \"storage\"", true, true, true},
+      {"\"cache\", \"*\", \"storage\"", true, true, true},
+      {"\"*\", \"cookies\", \"*\"", true, true, true},
   };
 
   const std::vector<TestCase>* test_case_sets[] = {&standard_test_cases,
@@ -290,9 +282,6 @@
                     {"\"passwords\"",
                      "Unrecognized type: \"passwords\".\n"
                      "No recognized types specified.\n"},
-                    {"\"cache\"",
-                     "The \"cache\" datatype is temporarily not supported.\n"
-                     "No recognized types specified.\n"},
                     // The wildcard datatype is not yet shipped.
                     {"[ \"*\" ]",
                      "Unrecognized type: [ \"*\" ].\n"
@@ -589,9 +578,9 @@
        "No recognized types specified.\n"},
 
       // Successful deletion on the same URL.
-      {"\"cookies\"", "https://origin3.com/bar",
+      {"\"cache\"", "https://origin3.com/bar",
        "Clear-Site-Data header on 'https://origin3.com/bar': "
-       "Cleared data types: \"cookies\".\n"},
+       "Cleared data types: \"cache\".\n"},
 
       // Redirect to the original URL.
       // Successful deletion outputs one line.
diff --git a/content/browser/compositor/gpu_output_surface_mac.mm b/content/browser/compositor/gpu_output_surface_mac.cc
similarity index 66%
rename from content/browser/compositor/gpu_output_surface_mac.mm
rename to content/browser/compositor/gpu_output_surface_mac.cc
index 3f56a464..5411945e 100644
--- a/content/browser/compositor/gpu_output_surface_mac.mm
+++ b/content/browser/compositor/gpu_output_surface_mac.cc
@@ -10,31 +10,12 @@
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/common/swap_buffers_complete_params.h"
 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
-#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
-#include "ui/base/cocoa/remote_layer_api.h"
+#include "ui/accelerated_widget_mac/ca_layer_frame_sink.h"
 #include "ui/compositor/compositor.h"
 #include "ui/display/types/display_snapshot.h"
-#include "ui/gfx/mac/io_surface.h"
 
 namespace content {
 
-struct GpuOutputSurfaceMac::RemoteLayers {
-  void UpdateLayers(CAContextID content_ca_context_id) {
-    if (content_ca_context_id) {
-      if ([content_layer contextId] != content_ca_context_id) {
-        content_layer.reset([[CALayerHost alloc] init]);
-        [content_layer setContextId:content_ca_context_id];
-        [content_layer
-            setAutoresizingMask:kCALayerMaxXMargin | kCALayerMaxYMargin];
-      }
-    } else {
-      content_layer.reset();
-    }
-  }
-
-  base::scoped_nsobject<CALayerHost> content_layer;
-};
-
 GpuOutputSurfaceMac::GpuOutputSurfaceMac(
     gfx::AcceleratedWidget widget,
     scoped_refptr<ui::ContextProviderCommandBuffer> context,
@@ -52,43 +33,30 @@
           GL_RGBA,
           gfx::BufferFormat::RGBA_8888,
           gpu_memory_buffer_manager),
-      widget_(widget),
-      remote_layers_(new RemoteLayers) {}
+      widget_(widget) {}
 
 GpuOutputSurfaceMac::~GpuOutputSurfaceMac() {}
 
 void GpuOutputSurfaceMac::SwapBuffers(viz::OutputSurfaceFrame frame) {
   GpuSurfacelessBrowserCompositorOutputSurface::SwapBuffers(std::move(frame));
-
   if (should_show_frames_state_ ==
       SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED) {
     should_show_frames_state_ = SHOULD_SHOW_FRAMES;
+    ui::CALayerFrameSink* ca_layer_frame_sink =
+        ui::CALayerFrameSink::FromAcceleratedWidget(widget_);
+    if (ca_layer_frame_sink)
+      ca_layer_frame_sink->SetSuspended(false);
   }
 }
 
 void GpuOutputSurfaceMac::OnGpuSwapBuffersCompleted(
     const gpu::SwapBuffersCompleteParams& params) {
-  const gfx::CALayerParams& ca_layer_params = params.ca_layer_params;
-  remote_layers_->UpdateLayers(ca_layer_params.ca_context_id);
-  if (should_show_frames_state_ == SHOULD_SHOW_FRAMES) {
-    ui::AcceleratedWidgetMac* widget = ui::AcceleratedWidgetMac::Get(widget_);
-    if (widget) {
-      if (remote_layers_->content_layer) {
-        widget->GotCALayerFrame(
-            base::scoped_nsobject<CALayer>(remote_layers_->content_layer.get(),
-                                           base::scoped_policy::RETAIN),
-            ca_layer_params.pixel_size, ca_layer_params.scale_factor);
-      } else {
-        base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
-            IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
-        if (!io_surface) {
-          LOG(ERROR) << "Unable to open IOSurface for frame.";
-        }
-        widget->GotIOSurfaceFrame(io_surface, ca_layer_params.pixel_size,
-                                  ca_layer_params.scale_factor);
-      }
-    }
-  }
+  DCHECK(!params.ca_layer_params.is_empty);
+  // TODO(ccameron): Push the call to CALayerFrameSink into |client_|.
+  ui::CALayerFrameSink* ca_layer_frame_sink =
+      ui::CALayerFrameSink::FromAcceleratedWidget(widget_);
+  if (ca_layer_frame_sink)
+    ca_layer_frame_sink->UpdateCALayerTree(params.ca_layer_params);
   client_->DidReceiveTextureInUseResponses(params.texture_in_use_responses);
   GpuSurfacelessBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
       params);
@@ -101,6 +69,10 @@
     // them in GpuProcessHostUIShim, until the browser issues a SwapBuffers for
     // the new content.
     should_show_frames_state_ = SHOULD_NOT_SHOW_FRAMES_SUSPENDED;
+    ui::CALayerFrameSink* ca_layer_frame_sink =
+        ui::CALayerFrameSink::FromAcceleratedWidget(widget_);
+    if (ca_layer_frame_sink)
+      ca_layer_frame_sink->SetSuspended(true);
   } else {
     // Discard the backbuffer before drawing the new frame. This is necessary
     // only when using a ImageTransportSurfaceFBO with a
diff --git a/content/browser/compositor/gpu_output_surface_mac.h b/content/browser/compositor/gpu_output_surface_mac.h
index 48040e13..e6efca4 100644
--- a/content/browser/compositor/gpu_output_surface_mac.h
+++ b/content/browser/compositor/gpu_output_surface_mac.h
@@ -36,11 +36,6 @@
  private:
   gfx::AcceleratedWidget widget_;
 
-  // Store remote layers in a separate structure, so that non-Objective-C files
-  // may include this header.
-  struct RemoteLayers;
-  std::unique_ptr<RemoteLayers> remote_layers_;
-
   enum ShouldShowFramesState {
     // Frames that come from the GPU process should appear on-screen.
     SHOULD_SHOW_FRAMES,
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index d414fb7..3da036b 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -960,7 +960,7 @@
     return shared_main_thread_contexts_;
 
   scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
-      gpu_channel_factory_->EstablishGpuChannelSync(nullptr);
+      gpu_channel_factory_->EstablishGpuChannelSync();
   if (!gpu_channel_host ||
       gpu_channel_host->gpu_feature_info()
               .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 3dd4390..bb9d0265 100644
--- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -514,11 +514,19 @@
 
 class SyntheticMouseEventTest : public DevToolsProtocolTest {
  protected:
-  void SendMouseEvent(const std::string& type, int x, int y, bool wait) {
+  void SendMouseEvent(const std::string& type,
+                      int x,
+                      int y,
+                      const std::string& button,
+                      bool wait) {
     std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
     params->SetString("type", type);
     params->SetInteger("x", x);
     params->SetInteger("y", y);
+    if (!button.empty()) {
+      params->SetString("button", button);
+      params->SetInteger("clickCount", 1);
+    }
     SendCommand("Input.dispatchMouseEvent", std::move(params), wait);
   }
 };
@@ -582,20 +590,20 @@
   EXPECT_EQ(3u, result_ids_.size());
 }
 
-IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, DISABLED_MouseEventAck) {
+IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, MouseEventAck) {
   NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
   Attach();
   ASSERT_TRUE(content::ExecuteScript(
       shell()->web_contents()->GetRenderViewHost(),
-      "document.body.addEventListener('mousemove', () => {debugger;});"));
+      "document.body.addEventListener('mousedown', () => {debugger;});"));
 
   auto filter = std::make_unique<InputMsgWatcher>(
       RenderWidgetHostImpl::From(
           shell()->web_contents()->GetRenderViewHost()->GetWidget()),
-      blink::WebInputEvent::kMouseMove);
+      blink::WebInputEvent::kMouseDown);
 
   SendCommand("Debugger.enable", nullptr);
-  SendMouseEvent("mouseMoved", 15, 15, false);
+  SendMouseEvent("mousePressed", 15, 15, "left", false);
 
   // We expect that the debugger message event arrives *before* the input
   // event ack, and the subsequent command response for
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc
index c8a746b7..af425ccb 100644
--- a/content/browser/devtools/protocol/input_handler.cc
+++ b/content/browser/devtools/protocol/input_handler.cc
@@ -66,7 +66,7 @@
                       bool auto_repeat,
                       bool is_keypad,
                       int location) {
-  int result = 0;
+  int result = blink::WebInputEvent::kFromDebugger;
   if (auto_repeat)
     result |= blink::WebInputEvent::kIsAutoRepeat;
   if (is_keypad)
@@ -293,6 +293,9 @@
 void InputHandler::OnInputEventAck(InputEventAckSource source,
                                    InputEventAckState state,
                                    const blink::WebInputEvent& event) {
+  if ((event.GetModifiers() & blink::WebInputEvent::kFromDebugger) == 0)
+    return;
+
   if (blink::WebInputEvent::IsKeyboardEventType(event.GetType()) &&
       !pending_key_callbacks_.empty()) {
     pending_key_callbacks_.front()->sendSuccess();
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index fb1b0aa..0f5c706 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -208,45 +208,6 @@
           .release());
 }
 
-// Creates a ResourceDownloader to own the URLLoader and intercept the response,
-// and passes it back to the DownloadManager.
-void InterceptNavigationResponse(
-    base::WeakPtr<DownloadManagerImpl> download_manager,
-    const scoped_refptr<ResourceResponse>& response,
-    mojo::ScopedDataPipeConsumerHandle consumer_handle,
-    net::CertStatus cert_status,
-    int frame_tree_node_id,
-    std::unique_ptr<ResourceRequest> resource_request,
-    std::unique_ptr<ThrottlingURLLoader> url_loader,
-    std::vector<GURL> url_chain,
-    base::Optional<network::URLLoaderCompletionStatus> status) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  GURL url = resource_request->url;
-  std::string method = resource_request->method;
-  ResourceRequestInfo::WebContentsGetter getter =
-      base::Bind(&GetWebContents, ChildProcessHost::kInvalidUniqueID,
-                 MSG_ROUTING_NONE, frame_tree_node_id);
-  std::unique_ptr<ResourceDownloader> resource_downloader =
-      ResourceDownloader::CreateWithURLLoader(
-          download_manager, std::move(resource_request), getter,
-          std::move(url_loader), std::move(status));
-
-  // Use Unretained() is safe as |resource_downloader| will be deleted on
-  // the IO thread.
-  base::OnceClosure start_interception_cb = base::BindOnce(
-      &ResourceDownloader::StartNavigationInterception,
-      base::Unretained(resource_downloader.get()), response,
-      std::move(consumer_handle), cert_status, std::move(url_chain));
-
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::BindOnce(&DownloadManagerImpl::CheckDownloadAllowed,
-                     download_manager, getter, url, method,
-                     DownloadManagerImpl::UniqueUrlDownloadHandlerPtr(
-                         resource_downloader.release()),
-                     std::move(start_interception_cb)));
-}
-
 class DownloadItemFactoryImpl : public DownloadItemFactory {
  public:
   DownloadItemFactoryImpl() {}
@@ -731,6 +692,7 @@
 
 void DownloadManagerImpl::AddUrlDownloadHandler(
     UniqueUrlDownloadHandlerPtr downloader) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (downloader)
     url_download_handlers_.push_back(std::move(downloader));
 }
@@ -791,40 +753,33 @@
   return DOWNLOAD_INTERRUPT_REASON_NONE;
 }
 
-NavigationURLLoader::NavigationInterceptionCB
-DownloadManagerImpl::GetNavigationInterceptionCB(
-    const scoped_refptr<ResourceResponse>& response,
-    mojo::ScopedDataPipeConsumerHandle consumer_handle,
+void DownloadManagerImpl::InterceptNavigation(
+    std::unique_ptr<ResourceRequest> resource_request,
+    std::vector<GURL> url_chain,
+    scoped_refptr<ResourceResponse> response,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     net::CertStatus cert_status,
     int frame_tree_node_id) {
-  return base::BindOnce(
-      &InterceptNavigationResponse, weak_factory_.GetWeakPtr(), response,
-      std::move(consumer_handle), cert_status, frame_tree_node_id);
-}
-
-void DownloadManagerImpl::CheckDownloadAllowed(
-    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
-    const GURL& url,
-    const std::string& request_method,
-    UniqueUrlDownloadHandlerPtr downloader,
-    base::OnceClosure callback) {
-  if (delegate_) {
-    delegate_->CheckDownloadAllowed(
-        web_contents_getter, url, request_method,
-        base::BindOnce(&DownloadManagerImpl::OnDownloadAllowedCheckComplete,
-                       weak_factory_.GetWeakPtr(), std::move(downloader),
-                       std::move(callback)));
-  }
-}
-
-void DownloadManagerImpl::OnDownloadAllowedCheckComplete(
-    UniqueUrlDownloadHandlerPtr downloader,
-    base::OnceClosure callback,
-    bool allow) {
-  if (!allow)
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (!delegate_)
     return;
-  AddUrlDownloadHandler(std::move(downloader));
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, std::move(callback));
+
+  const GURL& url = resource_request->url;
+  const std::string& method = resource_request->method;
+  ResourceRequestInfo::WebContentsGetter web_contents_getter =
+      base::BindRepeating(&GetWebContents, ChildProcessHost::kInvalidUniqueID,
+                          MSG_ROUTING_NONE, frame_tree_node_id);
+
+  base::OnceCallback<void(bool /* download allowed */)>
+      on_download_checks_done = base::BindOnce(
+          &DownloadManagerImpl::InterceptNavigationOnChecksComplete,
+          weak_factory_.GetWeakPtr(), web_contents_getter,
+          std::move(resource_request), std::move(url_chain),
+          std::move(response), cert_status,
+          std::move(url_loader_client_endpoints));
+
+  delegate_->CheckDownloadAllowed(web_contents_getter, url, method,
+                                  std::move(on_download_checks_done));
 }
 
 int DownloadManagerImpl::RemoveDownloadsByURLAndTime(
@@ -1024,6 +979,52 @@
     delegate_->ShowDownloadInShell(download);
 }
 
+void DownloadManagerImpl::InterceptNavigationOnChecksComplete(
+    ResourceRequestInfo::WebContentsGetter web_contents_getter,
+    std::unique_ptr<ResourceRequest> resource_request,
+    std::vector<GURL> url_chain,
+    scoped_refptr<ResourceResponse> response,
+    net::CertStatus cert_status,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    bool is_download_allowed) {
+  if (!is_download_allowed)
+    return;
+
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::BindOnce(&DownloadManagerImpl::CreateDownloadHandlerForNavigation,
+                     weak_factory_.GetWeakPtr(), web_contents_getter,
+                     std::move(resource_request), std::move(url_chain),
+                     std::move(response), std::move(cert_status),
+                     std::move(url_loader_client_endpoints)));
+}
+
+// static
+void DownloadManagerImpl::CreateDownloadHandlerForNavigation(
+    base::WeakPtr<DownloadManagerImpl> download_manager,
+    ResourceRequestInfo::WebContentsGetter web_contents_getter,
+    std::unique_ptr<ResourceRequest> resource_request,
+    std::vector<GURL> url_chain,
+    scoped_refptr<ResourceResponse> response,
+    net::CertStatus cert_status,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  std::unique_ptr<ResourceDownloader> resource_downloader =
+      ResourceDownloader::InterceptNavigationResponse(
+          download_manager, std::move(resource_request),
+          std::move(web_contents_getter), std::move(url_chain),
+          std::move(response), std::move(cert_status),
+          std::move(url_loader_client_endpoints));
+
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
+                     download_manager,
+                     DownloadManagerImpl::UniqueUrlDownloadHandlerPtr(
+                         resource_downloader.release())));
+}
+
 void DownloadManagerImpl::BeginDownloadInternal(
     std::unique_ptr<content::DownloadUrlParameters> params,
     uint32_t id) {
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index 776f92d..6007ada 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -143,22 +143,16 @@
       int render_frame_route_id,
       bool do_not_prompt_for_login);
 
-  // Returns the callback to intercept the navigation response.
-  NavigationURLLoader::NavigationInterceptionCB GetNavigationInterceptionCB(
-      const scoped_refptr<ResourceResponse>& response,
-      mojo::ScopedDataPipeConsumerHandle consumer_handle,
+  // Continue a navigation that ends up to be a download after it reaches the
+  // OnResponseStarted() step. It has to be called on the UI thread.
+  void InterceptNavigation(
+      std::unique_ptr<ResourceRequest> resource_request,
+      std::vector<GURL> url_chain,
+      scoped_refptr<ResourceResponse> response,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       net::CertStatus cert_status,
       int frame_tree_node_id);
 
-  // Checks if a download is allowed, |on_download_allowed_cb| is called if
-  // the download is allowed.
-  void CheckDownloadAllowed(
-      const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
-      const GURL& url,
-      const std::string& request_method,
-      UniqueUrlDownloadHandlerPtr downloader,
-      base::OnceClosure on_download_allowed_cb);
-
  private:
   using DownloadSet = std::set<DownloadItem*>;
   using DownloadGuidMap = std::unordered_map<std::string, DownloadItemImpl*>;
@@ -222,10 +216,26 @@
       std::unique_ptr<content::DownloadUrlParameters> params,
       uint32_t id);
 
-  // Called when download permission check is complete.
-  void OnDownloadAllowedCheckComplete(UniqueUrlDownloadHandlerPtr downloader,
-                                      base::OnceClosure callback,
-                                      bool allow);
+  void InterceptNavigationOnChecksComplete(
+      ResourceRequestInfo::WebContentsGetter web_contents_getter,
+      std::unique_ptr<ResourceRequest> resource_request,
+      std::vector<GURL> url_chain,
+      scoped_refptr<ResourceResponse> response,
+      net::CertStatus cert_status,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      bool is_download_allowed);
+
+  // Called when a navigation turns to be a download. Create a new
+  // DownloadHandler. It will be used to continue the loading instead of the
+  // regular document loader. Must be called on the IO thread.
+  static void CreateDownloadHandlerForNavigation(
+      base::WeakPtr<DownloadManagerImpl> download_manager,
+      ResourceRequestInfo::WebContentsGetter web_contents_getter,
+      std::unique_ptr<ResourceRequest> resource_request,
+      std::vector<GURL> url_chain,
+      scoped_refptr<ResourceResponse> response,
+      net::CertStatus cert_status,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
 
   // Factory for creation of downloads items.
   std::unique_ptr<DownloadItemFactory> item_factory_;
diff --git a/content/browser/download/resource_downloader.cc b/content/browser/download/resource_downloader.cc
index 3ae46f6..b7cc98c9 100644
--- a/content/browser/download/resource_downloader.cc
+++ b/content/browser/download/resource_downloader.cc
@@ -8,7 +8,6 @@
 
 #include "content/browser/blob_storage/blob_url_loader_factory.h"
 #include "content/browser/download/download_utils.h"
-#include "content/common/throttling_url_loader.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "storage/browser/fileapi/file_system_context.h"
@@ -98,16 +97,21 @@
 }
 
 // static
-std::unique_ptr<ResourceDownloader> ResourceDownloader::CreateWithURLLoader(
+std::unique_ptr<ResourceDownloader>
+ResourceDownloader::InterceptNavigationResponse(
     base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
     std::unique_ptr<ResourceRequest> resource_request,
     const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
-    std::unique_ptr<ThrottlingURLLoader> url_loader,
-    base::Optional<network::URLLoaderCompletionStatus> status) {
+    std::vector<GURL> url_chain,
+    const scoped_refptr<ResourceResponse>& response,
+    net::CertStatus cert_status,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints) {
   auto downloader = std::make_unique<ResourceDownloader>(
       delegate, std::move(resource_request), web_contents_getter,
       DownloadItem::kInvalidId);
-  downloader->InitializeURLLoader(std::move(url_loader), std::move(status));
+  downloader->InterceptResponse(std::move(response), std::move(url_chain),
+                                cert_status,
+                                std::move(url_loader_client_endpoints));
   return downloader;
 }
 
@@ -131,6 +135,8 @@
     bool is_parallel_request) {
   callback_ = download_url_parameters->callback();
   guid_ = download_url_parameters->guid();
+
+  // Set up the URLLoaderClient.
   url_loader_client_ = std::make_unique<DownloadResponseHandler>(
       resource_request_.get(), this,
       std::make_unique<DownloadSaveInfo>(
@@ -138,70 +144,57 @@
       is_parallel_request, download_url_parameters->is_transient(),
       download_url_parameters->fetch_error_body(),
       std::vector<GURL>(1, resource_request_->url));
+  mojom::URLLoaderClientPtr url_loader_client_ptr;
+  url_loader_client_binding_ =
+      std::make_unique<mojo::Binding<mojom::URLLoaderClient>>(
+          url_loader_client_.get(), mojo::MakeRequest(&url_loader_client_ptr));
 
+  // Set up the URLLoader
+  mojom::URLLoaderRequest url_loader_request = mojo::MakeRequest(&url_loader_);
   if (download_url_parameters->url().SchemeIs(url::kBlobScheme)) {
-    // To avoid race conditions with blob URL being immediately revoked after
-    // the download starting (which ThrottlingURLLoader doesn't handle), call
-    // directly into BlobURLLoaderFactory for blob URLs.
-    mojom::URLLoaderRequest url_loader_request;
-    mojom::URLLoaderClientPtr client;
-    blob_client_binding_ =
-        std::make_unique<mojo::Binding<mojom::URLLoaderClient>>(
-            url_loader_client_.get());
-    blob_client_binding_->Bind(mojo::MakeRequest(&client));
     BlobURLLoaderFactory::CreateLoaderAndStart(
         std::move(url_loader_request), *(resource_request_.get()),
-        std::move(client), download_url_parameters->GetBlobDataHandle());
+        std::move(url_loader_client_ptr),
+        download_url_parameters->GetBlobDataHandle());
   } else {
-    url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
-        url_loader_factory_getter->GetNetworkFactory(),
-        std::vector<std::unique_ptr<URLLoaderThrottle>>(),
+    url_loader_factory_getter->GetNetworkFactory()->CreateLoaderAndStart(
+        std::move(url_loader_request),
         0,  // routing_id
         0,  // request_id
         mojom::kURLLoadOptionSendSSLInfoWithResponse |
             mojom::kURLLoadOptionSniffMimeType,
-        *(resource_request_.get()), url_loader_client_.get(),
-        download_url_parameters->GetNetworkTrafficAnnotation(),
-        base::ThreadTaskRunnerHandle::Get());
+        *(resource_request_.get()), std::move(url_loader_client_ptr),
+        net::MutableNetworkTrafficAnnotationTag(
+            download_url_parameters->GetNetworkTrafficAnnotation()));
     url_loader_->SetPriority(net::RequestPriority::IDLE,
                              0 /* intra_priority_value */);
   }
 }
 
-void ResourceDownloader::InitializeURLLoader(
-    std::unique_ptr<ThrottlingURLLoader> url_loader,
-    base::Optional<network::URLLoaderCompletionStatus> status) {
-  url_loader_status_ = std::move(status);
-  url_loader_ = std::move(url_loader);
-  url_loader_client_ = std::make_unique<URLLoaderStatusMonitor>(
-      base::Bind(&ResourceDownloader::OnURLLoaderStatusChanged,
-                 weak_ptr_factory_.GetWeakPtr()));
-  url_loader_->set_forwarding_client(url_loader_client_.get());
-}
-
-void ResourceDownloader::OnURLLoaderStatusChanged(
-    const network::URLLoaderCompletionStatus& status) {
-  DCHECK(!url_loader_status_);
-  url_loader_status_ = status;
-}
-
-void ResourceDownloader::StartNavigationInterception(
+void ResourceDownloader::InterceptResponse(
     const scoped_refptr<ResourceResponse>& response,
-    mojo::ScopedDataPipeConsumerHandle consumer_handle,
+    std::vector<GURL> url_chain,
     net::CertStatus cert_status,
-    std::vector<GURL> url_chain) {
+    mojom::URLLoaderClientEndpointsPtr endpoints) {
+  // Set the URLLoader.
+  url_loader_.Bind(std::move(endpoints->url_loader));
+
+  // Create the new URLLoaderClient that will intercept the navigation.
   url_loader_client_ = std::make_unique<DownloadResponseHandler>(
       resource_request_.get(), this, std::make_unique<DownloadSaveInfo>(),
-      false, false, false, url_chain);
-  url_loader_->set_forwarding_client(url_loader_client_.get());
+      false, false, false, std::move(url_chain));
+
+  // Simulate on the new URLLoaderClient calls that happened on the old client.
   net::SSLInfo info;
   info.cert_status = cert_status;
   url_loader_client_->OnReceiveResponse(response->head,
                                         base::Optional<net::SSLInfo>(info),
                                         mojom::DownloadedTempFilePtr());
-  url_loader_client_->OnStartLoadingResponseBody(std::move(consumer_handle));
-  if (url_loader_status_)
-    url_loader_client_->OnComplete(url_loader_status_.value());
+
+  // Bind the new client.
+  url_loader_client_binding_ =
+      base::MakeUnique<mojo::Binding<mojom::URLLoaderClient>>(
+          url_loader_client_.get(), std::move(endpoints->url_loader_client));
 }
 
 void ResourceDownloader::OnResponseStarted(
diff --git a/content/browser/download/resource_downloader.h b/content/browser/download/resource_downloader.h
index 3c4e130..bba7316 100644
--- a/content/browser/download/resource_downloader.h
+++ b/content/browser/download/resource_downloader.h
@@ -20,8 +20,6 @@
 
 namespace content {
 
-class ThrottlingURLLoader;
-
 // Class for handing the download of a url.
 class ResourceDownloader : public UrlDownloadHandler,
                            public DownloadResponseHandler::Delegate {
@@ -37,13 +35,17 @@
       uint32_t download_id,
       bool is_parallel_request);
 
-  // Create the object with a URLLoader.
-  static std::unique_ptr<ResourceDownloader> CreateWithURLLoader(
+  // Create a ResourceDownloader from a navigation that turns to be a download.
+  // No URLLoader is created, but the URLLoaderClient implementation is
+  // transferred.
+  static std::unique_ptr<ResourceDownloader> InterceptNavigationResponse(
       base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
       std::unique_ptr<ResourceRequest> resource_request,
       const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
-      std::unique_ptr<ThrottlingURLLoader> url_loader,
-      base::Optional<network::URLLoaderCompletionStatus> status);
+      std::vector<GURL> url_chain,
+      const scoped_refptr<ResourceResponse>& response,
+      net::CertStatus cert_status,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
 
   ResourceDownloader(
       base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
@@ -58,13 +60,6 @@
       mojom::DownloadStreamHandlePtr stream_handle) override;
   void OnReceiveRedirect() override;
 
-  // Helper method to start the navigation interception.
-  void StartNavigationInterception(
-      const scoped_refptr<ResourceResponse>& response,
-      mojo::ScopedDataPipeConsumerHandle consumer_handle,
-      net::CertStatus cert_status,
-      std::vector<GURL> url_chain);
-
  private:
   // Helper method to start the network request.
   void Start(scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
@@ -72,39 +67,27 @@
              std::unique_ptr<DownloadUrlParameters> download_url_parameters,
              bool is_parallel_request);
 
-  // Initializes |url_loader_| to take ownership of the |url_loader|.
-  void InitializeURLLoader(
-      std::unique_ptr<ThrottlingURLLoader> url_loader,
-      base::Optional<network::URLLoaderCompletionStatus> status);
-
-  // Intercepts the navigation response and takes ownership of the |url_loader|.
+  // Intercepts the navigation response.
   void InterceptResponse(
-      std::unique_ptr<ThrottlingURLLoader> url_loader,
       const scoped_refptr<ResourceResponse>& response,
-      mojo::ScopedDataPipeConsumerHandle consumer_handle,
-      const SSLStatus& ssl_status,
-      int frame_tree_node_id,
       std::vector<GURL> url_chain,
-      base::Optional<network::URLLoaderCompletionStatus> status);
-
-  // Called when URLLoader status is changed.
-  void OnURLLoaderStatusChanged(
-      const network::URLLoaderCompletionStatus& status);
+      net::CertStatus cert_status,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
 
   base::WeakPtr<UrlDownloadHandler::Delegate> delegate_;
 
-  // URLLoader for sending out the request.
-  std::unique_ptr<ThrottlingURLLoader> url_loader_;
-
   // The ResourceRequest for this object.
   std::unique_ptr<ResourceRequest> resource_request_;
 
-  // Object for handing the server response.
+  // Object that will handle the response.
   std::unique_ptr<mojom::URLLoaderClient> url_loader_client_;
 
-  // URLLoaderClient binding for loading a blob.
-  std::unique_ptr<mojo::Binding<mojom::URLLoaderClient>> blob_client_binding_;
-  // mojo::Binding<mojom::URLLoaderClient> blob_client_binding_;
+  // URLLoaderClient binding. It sends any requests to the |url_loader_client_|.
+  std::unique_ptr<mojo::Binding<mojom::URLLoaderClient>>
+      url_loader_client_binding_;
+
+  // URLLoader for sending out the request.
+  mojom::URLLoaderPtr url_loader_;
 
   // ID of the download, or DownloadItem::kInvalidId if this is a new
   // download.
diff --git a/content/browser/file_url_loader_factory.cc b/content/browser/file_url_loader_factory.cc
index 28b6cd8..9a52132 100644
--- a/content/browser/file_url_loader_factory.cc
+++ b/content/browser/file_url_loader_factory.cc
@@ -255,8 +255,13 @@
       completion_status = net::ERR_FAILED;
     }
 
+    // All the data has been written now. Close the data pipe. The consumer will
+    // be notified that there will be no more data to read from now.
+    data_producer_.reset();
+
     client_->OnComplete(network::URLLoaderCompletionStatus(completion_status));
     client_.reset();
+
     MaybeDeleteSelf();
   }
 
@@ -517,6 +522,10 @@
   }
 
   void OnFileWritten(MojoResult result) {
+    // All the data has been written now. Close the data pipe. The consumer will
+    // be notified that there will be no more data to read from now.
+    data_producer_.reset();
+
     if (result == MOJO_RESULT_OK)
       client_->OnComplete(network::URLLoaderCompletionStatus(net::OK));
     else
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index a5ac096..fdcabe4 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -1288,12 +1288,14 @@
         entry->GetSSL() = last_entry->GetSSL();
       }
     } else {
-      // When restoring a tab, the serialized NavigationEntry doesn't have the
-      // SSL state.
-      // Only copy in the restore case since this code path can be taken during
-      // navigation. See http://crbug.com/727892
-      if (was_restored)
+      // In rapid back/forward navigations |handle| sometimes won't have a cert
+      // (http://crbug.com/727892). So we use the handle's cert if it exists,
+      // otherwise we only reuse the existing cert if the origins match.
+      if (handle->GetSSLInfo().is_valid()) {
         entry->GetSSL() = SSLStatus(handle->GetSSLInfo());
+      } else if (entry->GetURL().GetOrigin() != handle->GetURL().GetOrigin()) {
+        entry->GetSSL() = SSLStatus();
+      }
     }
 
     if (params.url.SchemeIs(url::kHttpsScheme) && !rfh->GetParent() &&
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index b8faea8..6fc37beb 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -449,8 +449,7 @@
 
 NavigationThrottle::ThrottleCheckResult
 NavigationHandleImpl::CallWillFailRequestForTesting(
-    base::Optional<net::SSLInfo> ssl_info,
-    bool should_ssl_errors_be_fatal) {
+    base::Optional<net::SSLInfo> ssl_info) {
   NavigationThrottle::ThrottleCheckResult result = NavigationThrottle::DEFER;
   WillFailRequest(ssl_info, base::Bind(&UpdateThrottleCheckResult, &result));
 
@@ -926,6 +925,8 @@
   DCHECK(state_ != DEFERRING_START || next_index_ != 0);
   base::WeakPtr<NavigationHandleImpl> weak_ref = weak_factory_.GetWeakPtr();
   for (size_t i = next_index_; i < throttles_.size(); ++i) {
+    TRACE_EVENT1("navigation", "NavigationThrottle::WillStartRequest",
+                 "throttle", throttles_[i]->GetNameForLogging());
     NavigationThrottle::ThrottleCheckResult result =
         throttles_[i]->WillStartRequest();
     if (!weak_ref) {
@@ -933,6 +934,9 @@
       // Return immediately.
       return NavigationThrottle::DEFER;
     }
+    // TODO(csharrison): It would be nice if the Check* traces also included
+    // synchronous time in the throttle's respective method, and did not include
+    // time spent in the next throttle's method.
     TRACE_EVENT_ASYNC_STEP_INTO0(
         "navigation", "NavigationHandle", this,
         base::StringPrintf("CheckWillStartRequest: %s: %d",
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index 7d2d9c5..9c3f20d 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -158,8 +158,7 @@
       const GURL& new_referrer_url,
       bool new_is_external_protocol) override;
   NavigationThrottle::ThrottleCheckResult CallWillFailRequestForTesting(
-      base::Optional<net::SSLInfo> ssl_info,
-      bool should_ssl_errors_be_fatal) override;
+      base::Optional<net::SSLInfo> ssl_info) override;
   NavigationThrottle::ThrottleCheckResult CallWillProcessResponseForTesting(
       RenderFrameHost* render_frame_host,
       const std::string& raw_response_header) override;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index f423eb5..a5a5bfb 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -41,6 +41,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/stream_handle.h"
 #include "content/public/common/appcache_info.h"
+#include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
@@ -739,8 +740,8 @@
 
 void NavigationRequest::OnResponseStarted(
     const scoped_refptr<ResourceResponse>& response,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     std::unique_ptr<StreamHandle> body,
-    mojo::ScopedDataPipeConsumerHandle consumer_handle,
     const net::SSLInfo& ssl_info,
     std::unique_ptr<NavigationData> navigation_data,
     const GlobalRequestID& request_id,
@@ -817,7 +818,7 @@
   // Store the response and the StreamHandle until checks have been processed.
   response_ = response;
   body_ = std::move(body);
-  handle_ = std::move(consumer_handle);
+  url_loader_client_endpoints_ = std::move(url_loader_client_endpoints);
   ssl_info_ = ssl_info;
   is_download_ = is_download;
 
@@ -971,17 +972,12 @@
       result.action() == NavigationThrottle::CANCEL ||
       result.action() == NavigationThrottle::BLOCK_REQUEST ||
       result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
-#if DCHECK_IS_ON()
-    if (result.action() == NavigationThrottle::BLOCK_REQUEST) {
-      DCHECK(result.net_error_code() == net::ERR_BLOCKED_BY_CLIENT ||
-             result.net_error_code() == net::ERR_BLOCKED_BY_ADMINISTRATOR);
-    }
     // TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
-    else if ((result.action() == NavigationThrottle::CANCEL ||
-              result.action() == NavigationThrottle::CANCEL_AND_IGNORE)) {
-      DCHECK_EQ(result.net_error_code(), net::ERR_ABORTED);
-    }
-#endif
+    DCHECK_EQ((result.action() == NavigationThrottle::CANCEL ||
+               result.action() == NavigationThrottle::CANCEL_AND_IGNORE)
+                  ? net::ERR_ABORTED
+                  : net::ERR_BLOCKED_BY_CLIENT,
+              result.net_error_code());
 
     // If the start checks completed synchronously, which could happen if there
     // is no onbeforeunload handler or if a NavigationThrottle cancelled it,
@@ -1138,14 +1134,23 @@
     // DownloadManager, and cancel the navigation.
     if (is_download_ &&
         base::FeatureList::IsEnabled(features::kNetworkService)) {
+      // TODO(arthursonzogni): Pass the real ResourceRequest. For the moment
+      // only these 4 parameters will be used, but it may evolve quickly.
+      auto resource_request = std::make_unique<ResourceRequest>();
+      resource_request->url = common_params_.url;
+      resource_request->method = common_params_.method;
+      resource_request->request_initiator = begin_params_->initiator_origin;
+      resource_request->referrer = common_params_.referrer.url;
+
       BrowserContext* browser_context =
           frame_tree_node_->navigator()->GetController()->GetBrowserContext();
       DownloadManagerImpl* download_manager = static_cast<DownloadManagerImpl*>(
           BrowserContext::GetDownloadManager(browser_context));
-      loader_->InterceptNavigation(
-          download_manager->GetNavigationInterceptionCB(
-              response_, std::move(handle_), ssl_info_.cert_status,
-              frame_tree_node_->frame_tree_node_id()));
+      download_manager->InterceptNavigation(
+          std::move(resource_request), navigation_handle_->GetRedirectChain(),
+          response_, std::move(url_loader_client_endpoints_),
+          ssl_info_.cert_status, frame_tree_node_->frame_tree_node_id());
+
       OnRequestFailed(false, net::ERR_ABORTED, base::nullopt);
       return;
     }
@@ -1212,9 +1217,9 @@
   TransferNavigationHandleOwnership(render_frame_host);
 
   render_frame_host->CommitNavigation(
-      response_.get(), std::move(body_), std::move(handle_), common_params_,
-      request_params_, is_view_source_, std::move(subresource_loader_params_),
-      devtools_navigation_token_);
+      response_.get(), std::move(url_loader_client_endpoints_),
+      std::move(body_), common_params_, request_params_, is_view_source_,
+      std::move(subresource_loader_params_), devtools_navigation_token_);
 
   frame_tree_node_->ResetNavigationRequest(true, true);
 }
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 7b1cccab..e9cba4a2 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -21,7 +21,6 @@
 #include "content/common/navigation_subresource_loader_params.h"
 #include "content/public/browser/navigation_throttle.h"
 #include "content/public/common/previews_state.h"
-#include "mojo/public/cpp/system/data_pipe.h"
 
 namespace content {
 
@@ -222,16 +221,17 @@
   void OnRequestRedirected(
       const net::RedirectInfo& redirect_info,
       const scoped_refptr<ResourceResponse>& response) override;
-  void OnResponseStarted(const scoped_refptr<ResourceResponse>& response,
-                         std::unique_ptr<StreamHandle> body,
-                         mojo::ScopedDataPipeConsumerHandle consumer_handle,
-                         const net::SSLInfo& ssl_info,
-                         std::unique_ptr<NavigationData> navigation_data,
-                         const GlobalRequestID& request_id,
-                         bool is_download,
-                         bool is_stream,
-                         base::Optional<SubresourceLoaderParams>
-                             subresource_loader_params) override;
+  void OnResponseStarted(
+      const scoped_refptr<ResourceResponse>& response,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      std::unique_ptr<StreamHandle> body,
+      const net::SSLInfo& ssl_info,
+      std::unique_ptr<NavigationData> navigation_data,
+      const GlobalRequestID& request_id,
+      bool is_download,
+      bool is_stream,
+      base::Optional<SubresourceLoaderParams> subresource_loader_params)
+      override;
   void OnRequestFailed(bool has_stale_copy_in_cache,
                        int net_error,
                        const base::Optional<net::SSLInfo>& ssl_info) override;
@@ -347,12 +347,14 @@
 
   std::unique_ptr<NavigationHandleImpl> navigation_handle_;
 
-  // Holds the ResourceResponse and the StreamHandle (or
-  // DataPipeConsumerHandle) for the navigation while the WillProcessResponse
-  // checks are performed by the NavigationHandle.
+  // Holds objects received from OnResponseStarted while the WillProcessResponse
+  // checks are performed by the NavigationHandle. Once the checks have been
+  // completed, these objects will be used to continue the navigation.
+  // The URLLoaderClientEndpointsPtr is used when the Network Service or
+  // NavigationMojoResponse is enabled. Otherwise the StreamHandle is used.
   scoped_refptr<ResourceResponse> response_;
   std::unique_ptr<StreamHandle> body_;
-  mojo::ScopedDataPipeConsumerHandle handle_;
+  mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints_;
   net::SSLInfo ssl_info_;
   bool is_download_;
 
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index c6f7420..69f9b05 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -1159,10 +1159,11 @@
             *scoped_request.get());
     render_frame_host->CommitNavigation(
         nullptr,  // response
+        mojom::URLLoaderClientEndpointsPtr(),
         nullptr,  // body
-        mojo::ScopedDataPipeConsumerHandle(), scoped_request->common_params(),
-        scoped_request->request_params(), scoped_request->is_view_source(),
-        base::nullopt, scoped_request->devtools_navigation_token());
+        scoped_request->common_params(), scoped_request->request_params(),
+        scoped_request->is_view_source(), base::nullopt,
+        scoped_request->devtools_navigation_token());
     return;
   }
 
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 3e91634..c0794a4 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -3316,9 +3316,9 @@
       CSPDisposition::CHECK /* should_check_main_world_csp */,
       false /* started_from_context_menu */, false /* has_user_gesture */);
   if (IsBrowserSideNavigationEnabled()) {
-    CommitNavigation(nullptr, nullptr, mojo::ScopedDataPipeConsumerHandle(),
-                     common_params, RequestNavigationParams(), false,
-                     base::nullopt,
+    CommitNavigation(nullptr, mojom::URLLoaderClientEndpointsPtr(),
+                     std::unique_ptr<StreamHandle>(), common_params,
+                     RequestNavigationParams(), false, base::nullopt,
                      base::UnguessableToken::Create() /* not traced */);
   } else {
     Navigate(common_params, StartNavigationParams(), RequestNavigationParams());
@@ -3465,8 +3465,8 @@
 // PlzNavigate
 void RenderFrameHostImpl::CommitNavigation(
     ResourceResponse* response,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     std::unique_ptr<StreamHandle> body,
-    mojo::ScopedDataPipeConsumerHandle handle,
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
     bool is_view_source,
@@ -3475,8 +3475,9 @@
   TRACE_EVENT2("navigation", "RenderFrameHostImpl::CommitNavigation",
                "frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url",
                common_params.url.possibly_invalid_spec());
+
   DCHECK(
-      (response && (body.get() || handle.is_valid())) ||
+      (response && (url_loader_client_endpoints || body)) ||
       common_params.url.SchemeIs(url::kDataScheme) ||
       !IsURLHandledByNetworkStack(common_params.url) ||
       FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type) ||
@@ -3490,9 +3491,10 @@
   // prevent us from doing inappropriate things with javascript-url.
   // See https://crbug.com/766149.
   if (common_params.url.SchemeIs(url::kJavaScriptScheme)) {
+    DCHECK(!url_loader_client_endpoints && !body);
     GetNavigationControl()->CommitNavigation(
         ResourceResponseHead(), GURL(), common_params, request_params,
-        mojo::ScopedDataPipeConsumerHandle(),
+        mojom::URLLoaderClientEndpointsPtr(),
         /*subresource_loader_factories=*/base::nullopt,
         devtools_navigation_token);
     return;
@@ -3614,7 +3616,8 @@
          subresource_loader_factories.has_value());
 
   GetNavigationControl()->CommitNavigation(
-      head, body_url, common_params, request_params, std::move(handle),
+      head, body_url, common_params, request_params,
+      std::move(url_loader_client_endpoints),
       std::move(subresource_loader_factories), devtools_navigation_token);
 
   // If a network request was made, update the Previews state.
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 0285f51..1f6a749 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -571,8 +571,8 @@
   // process, e.g. by AppCache etc.
   void CommitNavigation(
       ResourceResponse* response,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       std::unique_ptr<StreamHandle> body,
-      mojo::ScopedDataPipeConsumerHandle handle,
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
       bool is_view_source,
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
index be6b073..1894610 100644
--- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -21,6 +21,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/content_client.h"
+#include "content/public/common/content_features.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
@@ -521,9 +522,12 @@
 // After a renderer crash, the StreamHandle must be released.
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
                        StreamHandleReleasedOnRendererCrash) {
-  // |stream_handle_| is only used with PlzNavigate.
-  if (!IsBrowserSideNavigationEnabled())
+  // Disable this test when the |stream_handle_| is not used.
+  if (!IsBrowserSideNavigationEnabled() ||
+      base::FeatureList::IsEnabled(features::kNetworkService) ||
+      IsNavigationMojoResponseEnabled()) {
     return;
+  }
 
   GURL url_1(embedded_test_server()->GetURL("a.com", "/title1.html"));
   GURL url_2(embedded_test_server()->GetURL("a.com", "/title2.html"));
@@ -1036,33 +1040,33 @@
   injector.set_fake_request_for_next_commit(
       std::move(interface_provider_request_with_pending_request));
 
-  // Set up |dispatched_interface_request_callback| to be invoked when the
-  // interface request for FrameHostTestInterface is dispatched to the
-  // RenderFrameHostImpl.
-  base::MockCallback<base::RepeatingClosure>
-      dispatched_interface_request_callback;
+  // Expect that by the time the interface request for FrameHostTestInterface is
+  // dispatched to the RenderFrameHost, WebContentsObserver::DidFinishNavigation
+  // will have already been invoked.
+  bool did_finish_navigation = false;
   auto* main_rfh = shell()->web_contents()->GetMainFrame();
+  DidFinishNavigationObserver navigation_finish_observer(
+      main_rfh, base::BindLambdaForTesting([&did_finish_navigation]() {
+        did_finish_navigation = true;
+      }));
+
+  base::RunLoop wait_until_interface_request_is_dispatched;
   ScopedInterfaceRequestMonitor monitor(
       main_rfh, mojom::FrameHostTestInterface::Name_,
-      dispatched_interface_request_callback.Get());
-
-  // Set up |navigation_finished_callback| to be fired on
-  // WebContentsObserver::DidFinishNavigation.
-  base::MockCallback<base::RepeatingClosure> navigation_finished_callback;
-  DidFinishNavigationObserver navigation_finish_observer(
-      main_rfh, navigation_finished_callback.Get());
-
-  // Expect that DidFinishNavigation takes place first, and dispatching second.
-  testing::InSequence in_sequence;
-  EXPECT_CALL(navigation_finished_callback, Run());
-  EXPECT_CALL(dispatched_interface_request_callback, Run());
+      base::BindLambdaForTesting([&]() {
+        EXPECT_TRUE(did_finish_navigation);
+        wait_until_interface_request_is_dispatched.Quit();
+      }));
 
   // Start the same-process navigation.
   test::ScopedInterfaceFilterBypass filter_bypass;
   ASSERT_TRUE(NavigateToURL(shell(), second_url));
-  ASSERT_EQ(main_rfh, shell()->web_contents()->GetMainFrame());
-  ASSERT_EQ(second_url, injector.url_of_last_commit());
-  ASSERT_TRUE(injector.original_request_of_last_commit().is_pending());
+  EXPECT_EQ(main_rfh, shell()->web_contents()->GetMainFrame());
+  EXPECT_EQ(second_url, injector.url_of_last_commit());
+  EXPECT_TRUE(injector.original_request_of_last_commit().is_pending());
+
+  // Wait until the interface request for FrameHostTestInterface is dispatched.
+  wait_until_interface_request_is_dispatched.Run();
 }
 
 // The InterfaceProvider interface, which is used by the RenderFrame to access
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index ba8ac7b..961bee8 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -1244,16 +1244,13 @@
   // BrowserContext.
   DCHECK_EQ(new_instance->GetBrowserContext(), browser_context);
 
-  // If |new_instance| is a new SiteInstance for a subframe with an isolated
-  // origin, set its process reuse policy so that such subframes are
-  // consolidated into existing processes for that isolated origin.
+  // If |new_instance| is a new SiteInstance for a subframe that requires a
+  // dedicated process, set its process reuse policy so that such subframes are
+  // consolidated into existing processes for that site.
   SiteInstanceImpl* new_instance_impl =
       static_cast<SiteInstanceImpl*>(new_instance.get());
-  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
   if (!frame_tree_node_->IsMainFrame() && !new_instance_impl->HasProcess() &&
-      new_instance_impl->HasSite() &&
-      policy->IsIsolatedOrigin(
-          url::Origin::Create(new_instance_impl->GetSiteURL()))) {
+      new_instance_impl->RequiresDedicatedProcess()) {
     new_instance_impl->set_process_reuse_policy(
         SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE);
   }
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index 44577c74..2c74fa8 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -283,13 +283,11 @@
 // (Opening the initial channel to a child process involves handling a reply
 // task on the UI thread first, so we cannot block here.)
 scoped_refptr<gpu::GpuChannelHost>
-BrowserGpuChannelHostFactory::EstablishGpuChannelSync(bool* connection_error) {
+BrowserGpuChannelHostFactory::EstablishGpuChannelSync() {
 #if defined(OS_ANDROID)
   NOTREACHED();
   return nullptr;
 #endif
-  if (connection_error)
-    *connection_error = false;
   EstablishGpuChannel(gpu::GpuChannelEstablishedCallback());
 
   if (pending_request_.get())
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index b425c314..b83cb96d3 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -42,8 +42,7 @@
   // shutdown.
   void EstablishGpuChannel(
       const gpu::GpuChannelEstablishedCallback& callback) override;
-  scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync(
-      bool* connection_error) override;
+  scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override;
   gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
 
  private:
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc
index 5573fc78..5f4cefd1 100644
--- a/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -202,7 +202,7 @@
                        MAYBE_AlreadyEstablished) {
   DCHECK(!IsChannelEstablished());
   scoped_refptr<gpu::GpuChannelHost> gpu_channel =
-      GetFactory()->EstablishGpuChannelSync(nullptr);
+      GetFactory()->EstablishGpuChannelSync();
 
   // Expect established callback immediately.
   bool event = false;
diff --git a/content/browser/leveldb_wrapper_impl.cc b/content/browser/leveldb_wrapper_impl.cc
index 7708bda..d5173bf1 100644
--- a/content/browser/leveldb_wrapper_impl.cc
+++ b/content/browser/leveldb_wrapper_impl.cc
@@ -366,7 +366,8 @@
     storage_used_ -= key.size() + found->second;
     keys_only_map_.erase(found);
     memory_used_ -= key.size() + sizeof(size_t);
-    commit_batch_->changed_values[key] = std::vector<uint8_t>();
+    if (commit_batch_)
+      commit_batch_->changed_values[key] = std::vector<uint8_t>();
   } else {
     DCHECK_EQ(map_state_, MapState::LOADED_KEYS_AND_VALUES);
     ValueMap::iterator found = keys_values_map_.find(key);
@@ -378,7 +379,8 @@
     keys_values_map_.erase(found);
     memory_used_ -= key.size() + old_value.size();
     storage_used_ -= key.size() + old_value.size();
-    commit_batch_->changed_keys.insert(key);
+    if (commit_batch_)
+      commit_batch_->changed_keys.insert(key);
   }
 
   observers_.ForAllPtrs(
diff --git a/content/browser/loader/async_resource_handler_unittest.cc b/content/browser/loader/async_resource_handler_unittest.cc
index 6e5fdc4..ef8d97c 100644
--- a/content/browser/loader/async_resource_handler_unittest.cc
+++ b/content/browser/loader/async_resource_handler_unittest.cc
@@ -258,14 +258,16 @@
   StartRequestAndWaitWithResponseDataSize(kDataSize);
   const auto& messages = filter_->messages();
   ASSERT_EQ(4u, messages.size());
-  ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2]->type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+            messages[2]->type());
   ResourceMsg_DataReceived::Param params;
   ResourceMsg_DataReceived::Read(messages[2].get(), &params);
 
   int encoded_data_length = std::get<3>(params);
   EXPECT_EQ(kDataSize, encoded_data_length);
 
-  ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[3]->type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_RequestComplete::ID),
+            messages[3]->type());
   ResourceMsg_RequestComplete::Param completion_params;
   ResourceMsg_RequestComplete::Read(messages[3].get(), &completion_params);
   network::URLLoaderCompletionStatus status = std::get<1>(completion_params);
@@ -280,20 +282,23 @@
   StartRequestAndWaitWithResponseDataSize(kDataSize);
   const auto& messages = filter_->messages();
   ASSERT_EQ(5u, messages.size());
-  ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2]->type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+            messages[2]->type());
   ResourceMsg_DataReceived::Param params;
   ResourceMsg_DataReceived::Read(messages[2].get(), &params);
 
   int encoded_data_length = std::get<3>(params);
   EXPECT_EQ(32768, encoded_data_length);
 
-  ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[3]->type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+            messages[3]->type());
   ResourceMsg_DataReceived::Read(messages[3].get(), &params);
 
   encoded_data_length = std::get<3>(params);
   EXPECT_EQ(32768, encoded_data_length);
 
-  ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[4]->type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_RequestComplete::ID),
+            messages[4]->type());
   ResourceMsg_RequestComplete::Param completion_params;
   ResourceMsg_RequestComplete::Read(messages[4].get(), &completion_params);
   network::URLLoaderCompletionStatus status = std::get<1>(completion_params);
diff --git a/content/browser/loader/navigation_resource_handler.cc b/content/browser/loader/navigation_resource_handler.cc
index 6ce7751..054ada49 100644
--- a/content/browser/loader/navigation_resource_handler.cc
+++ b/content/browser/loader/navigation_resource_handler.cc
@@ -27,18 +27,6 @@
 #include "net/url_request/url_request_context.h"
 #include "url/gurl.h"
 
-namespace {
-
-// TODO(crbug.com/757633): Attach this information to net::SSLInfo instead of
-// calculating it here.
-bool ShouldSSLErrorsBeFatal(net::URLRequest* request) {
-  net::TransportSecurityState* state =
-      request->context()->transport_security_state();
-  return state->ShouldSSLErrorsBeFatal(request->url().host());
-}
-
-}  // namespace
-
 namespace content {
 
 NavigationResourceHandler::NavigationResourceHandler(
@@ -56,7 +44,7 @@
 
 NavigationResourceHandler::~NavigationResourceHandler() {
   if (core_) {
-    core_->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt, false);
+    core_->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt);
     DetachFromCore();
   }
 }
@@ -159,7 +147,7 @@
     }
 
     core_->NotifyRequestFailed(request()->response_info().was_cached, net_error,
-                               ssl_info, ShouldSSLErrorsBeFatal(request()));
+                               ssl_info);
     DetachFromCore();
   }
   next_handler_->OnResponseCompleted(status, std::move(controller));
diff --git a/content/browser/loader/navigation_url_loader.h b/content/browser/loader/navigation_url_loader.h
index bb784aa..e015126 100644
--- a/content/browser/loader/navigation_url_loader.h
+++ b/content/browser/loader/navigation_url_loader.h
@@ -6,15 +6,9 @@
 #define CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_H_
 
 #include <memory>
-#include <vector>
 
-#include "base/callback.h"
 #include "base/macros.h"
-#include "base/optional.h"
 #include "content/common/content_export.h"
-#include "services/network/public/cpp/url_loader_completion_status.h"
-
-class GURL;
 
 namespace content {
 
@@ -25,9 +19,7 @@
 class ResourceContext;
 class ServiceWorkerNavigationHandle;
 class StoragePartition;
-class ThrottlingURLLoader;
 struct NavigationRequestInfo;
-struct ResourceRequest;
 
 // PlzNavigate: The navigation logic's UI thread entry point into the resource
 // loading stack. It exposes an interface to control the request prior to
@@ -64,21 +56,6 @@
   // Called in response to OnResponseStarted to process the response.
   virtual void ProceedWithResponse() = 0;
 
-  // Callback to intercept the response from the URLLoader. Only used when
-  // network service is enabled. Args: the initial resource request,
-  // the URLLoader for sending the request, url chain, optional completion
-  // status if it has already been received.
-  using NavigationInterceptionCB = base::OnceCallback<void(
-      std::unique_ptr<ResourceRequest>,
-      std::unique_ptr<ThrottlingURLLoader>,
-      std::vector<GURL>,
-      base::Optional<network::URLLoaderCompletionStatus>)>;
-
-  // This method is called to intercept the url response. Caller is responsible
-  // for handling the URLLoader later on. The callback should be called on the
-  // same thread that URLLoader is constructed.
-  virtual void InterceptNavigation(NavigationInterceptionCB callback) = 0;
-
  protected:
   NavigationURLLoader() {}
 
diff --git a/content/browser/loader/navigation_url_loader_delegate.h b/content/browser/loader/navigation_url_loader_delegate.h
index cf6cc7e..49013ca 100644
--- a/content/browser/loader/navigation_url_loader_delegate.h
+++ b/content/browser/loader/navigation_url_loader_delegate.h
@@ -11,7 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/optional.h"
 #include "content/common/content_export.h"
-#include "mojo/public/cpp/system/data_pipe.h"
+#include "content/public/common/url_loader.mojom.h"
 
 namespace net {
 struct RedirectInfo;
@@ -38,16 +38,17 @@
   // Called when the request receives its response. No further calls will be
   // made to the delegate. The response body is returned as a stream in
   // |body_stream|. |navigation_data| is passed to the NavigationHandle.
-  // If --enable-network-service, then |consumer_handle| will be used,
-  // otherwise |body_stream|. Only one of these will ever be non-null.
-  // |subresource_loader_params| is used in the network service only
-  // for passing necessary info to create a custom subresource loader in
-  // the renderer process if the navigated context is controlled by a request
-  // interceptor like AppCache or ServiceWorker.
+  // If the Network Service or NavigationMojoResponse is enabled, then the
+  // |url_loader_client_endpoints| will be used, otherwise |body_stream|. Only
+  // one of these will ever be non-null.
+  // |subresource_loader_params| is used in the network service only for passing
+  // necessary info to create a custom subresource loader in the renderer
+  // process if the navigated context is controlled by a request interceptor
+  // like AppCache or ServiceWorker.
   virtual void OnResponseStarted(
       const scoped_refptr<ResourceResponse>& response,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       std::unique_ptr<StreamHandle> body_stream,
-      mojo::ScopedDataPipeConsumerHandle consumer_handle,
       const net::SSLInfo& ssl_info,
       std::unique_ptr<NavigationData> navigation_data,
       const GlobalRequestID& request_id,
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 3eb0d63..d61951d 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -87,9 +87,6 @@
       base::BindOnce(&NavigationURLLoaderImplCore::ProceedWithResponse, core_));
 }
 
-void NavigationURLLoaderImpl::InterceptNavigation(
-    NavigationURLLoader::NavigationInterceptionCB callback) {}
-
 void NavigationURLLoaderImpl::NotifyRequestRedirected(
     const net::RedirectInfo& redirect_info,
     const scoped_refptr<ResourceResponse>& response) {
@@ -108,16 +105,15 @@
     bool is_stream) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  delegate_->OnResponseStarted(response, std::move(body),
-                               mojo::ScopedDataPipeConsumerHandle(), ssl_info,
+  delegate_->OnResponseStarted(response, mojom::URLLoaderClientEndpointsPtr(),
+                               std::move(body), ssl_info,
                                std::move(navigation_data), request_id,
                                is_download, is_stream, base::nullopt);
 }
 void NavigationURLLoaderImpl::NotifyRequestFailed(
     bool in_cache,
     int net_error,
-    base::Optional<net::SSLInfo> ssl_info,
-    bool should_ssl_errors_be_fatal) {
+    base::Optional<net::SSLInfo> ssl_info) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   delegate_->OnRequestFailed(in_cache, net_error, ssl_info);
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index 49c745e..5a53fd2 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -44,7 +44,6 @@
   // NavigationURLLoader implementation.
   void FollowRedirect() override;
   void ProceedWithResponse() override;
-  void InterceptNavigation(NavigationInterceptionCB callback) override;
 
  private:
   friend class NavigationURLLoaderImplCore;
@@ -65,11 +64,10 @@
   // Notifies the delegate the the request has failed. If |net_error| is a
   // certificate error, the caller must pass valid values for |ssl_info| and
   // |fatal_cert_error|. If |net_error| is not a certificate error, |ssl_info|
-  // and |fatal_cert_error| are ignored.
+  // is ignored.
   void NotifyRequestFailed(bool in_cache,
                            int net_error,
-                           base::Optional<net::SSLInfo> ssl_info,
-                           bool should_ssl_errors_be_fatal);
+                           base::Optional<net::SSLInfo> ssl_info);
 
   // Notifies the delegate the begin navigation request was handled and a
   // potential first network request is about to be made.
diff --git a/content/browser/loader/navigation_url_loader_impl_core.cc b/content/browser/loader/navigation_url_loader_impl_core.cc
index db3ebec..c5f19e8 100644
--- a/content/browser/loader/navigation_url_loader_impl_core.cc
+++ b/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -146,8 +146,7 @@
 void NavigationURLLoaderImplCore::NotifyRequestFailed(
     bool in_cache,
     int net_error,
-    const base::Optional<net::SSLInfo>& ssl_info,
-    bool should_ssl_errors_be_fatal) {
+    const base::Optional<net::SSLInfo>& ssl_info) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   TRACE_EVENT_ASYNC_END0("navigation", "Navigation redirectDelay", this);
   TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
@@ -157,8 +156,7 @@
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::BindOnce(&NavigationURLLoaderImpl::NotifyRequestFailed, loader_,
-                     in_cache, net_error, ssl_info,
-                     should_ssl_errors_be_fatal));
+                     in_cache, net_error, ssl_info));
 }
 
 }  // namespace content
diff --git a/content/browser/loader/navigation_url_loader_impl_core.h b/content/browser/loader/navigation_url_loader_impl_core.h
index 72310d8..64fa6b0 100644
--- a/content/browser/loader/navigation_url_loader_impl_core.h
+++ b/content/browser/loader/navigation_url_loader_impl_core.h
@@ -84,8 +84,7 @@
   // Notifies |loader_| on the UI thread that the request failed.
   void NotifyRequestFailed(bool in_cache,
                            int net_error,
-                           const base::Optional<net::SSLInfo>& ssl_info,
-                           bool should_ssl_errors_be_fatal);
+                           const base::Optional<net::SSLInfo>& ssl_info);
 
  private:
   friend class base::RefCountedThreadSafe<NavigationURLLoaderImplCore>;
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index 5c6e9b6..4cbb900 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -115,6 +115,40 @@
         "combination of both) limits the scope of these requests."
       )");
 
+// TODO(arthursonzogni): IsDownload can't be determined only by the response's
+// headers. The response's body might contain information to guess it.
+// See MimeSniffingResourceHandler.
+bool IsDownload(const ResourceResponse& response, const GURL& url) {
+  if (response.head.headers) {
+    std::string disposition;
+    if (response.head.headers->GetNormalizedHeader("content-disposition",
+                                                   &disposition) &&
+        !disposition.empty() &&
+        net::HttpContentDisposition(disposition, std::string())
+            .is_attachment()) {
+      return true;
+    } else if (GetContentClient()->browser()->ShouldForceDownloadResource(
+                   url, response.head.mime_type)) {
+      return true;
+    } else if (response.head.mime_type == "multipart/related") {
+      // TODO(https://crbug.com/790734): retrieve the new NavigationUIData from
+      // the request and and pass it to AllowRenderingMhtmlOverHttp().
+      return !GetContentClient()->browser()->AllowRenderingMhtmlOverHttp(
+          nullptr);
+    }
+    // TODO(qinmin): Check whether this is special-case user script that needs
+    // to be downloaded.
+  }
+
+  if (blink::IsSupportedMimeType(response.head.mime_type))
+    return false;
+
+  // TODO(qinmin): Check whether there is a plugin handler.
+
+  return (!response.head.headers ||
+          response.head.headers->response_code() / 100 == 2);
+}
+
 }  // namespace
 
 // Kept around during the lifetime of the navigation request, and is
@@ -356,16 +390,6 @@
     Restart();
   }
 
-  // Navigation is intercepted, transfer the |resource_request_|, |url_loader_|
-  // and the |status_| to the new owner. The new owner is responsible for
-  // handling all the mojom::URLLoaderClient callbacks from now on.
-  void InterceptNavigation(
-      NavigationURLLoader::NavigationInterceptionCB callback) {
-    std::move(callback).Run(std::move(resource_request_),
-                            std::move(url_loader_), std::move(url_chain_),
-                            std::move(status_));
-  }
-
   base::Optional<SubresourceLoaderParams> TakeSubresourceLoaderParams() {
     return std::move(subresource_loader_params_);
   }
@@ -382,6 +406,16 @@
     // for the response. e.g. AppCache.
     if (MaybeCreateLoaderForResponse(head))
       return;
+
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
+    if (url_loader_) {
+      url_loader_client_endpoints = url_loader_->Unbind();
+    } else {
+      url_loader_client_endpoints = mojom::URLLoaderClientEndpoints::New(
+          response_url_loader_.PassInterface(),
+          response_loader_binding_.Unbind());
+    }
+
     scoped_refptr<ResourceResponse> response(new ResourceResponse());
     response->head = head;
 
@@ -394,7 +428,8 @@
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
         base::BindOnce(&NavigationURLLoaderNetworkService::OnReceiveResponse,
-                       owner_, response->DeepCopy(), ssl_info,
+                       owner_, std::move(url_loader_client_endpoints),
+                       response->DeepCopy(), ssl_info,
                        base::Passed(&downloaded_file)));
   }
 
@@ -432,13 +467,10 @@
   void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {}
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
 
-  void OnStartLoadingResponseBody(
-      mojo::ScopedDataPipeConsumerHandle body) override {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::BindOnce(
-            &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody,
-            owner_, base::Passed(&body)));
+  void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle) override {
+    // Not reached. At this point, the loader and client endpoints must have
+    // been unbound and forwarded to the renderer.
+    CHECK(false);
   }
 
   void OnComplete(const network::URLLoaderCompletionStatus& status) override {
@@ -670,25 +702,32 @@
 
 void NavigationURLLoaderNetworkService::ProceedWithResponse() {}
 
-void NavigationURLLoaderNetworkService::InterceptNavigation(
-    NavigationURLLoader::NavigationInterceptionCB callback) {
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&URLLoaderRequestController::InterceptNavigation,
-                     base::Unretained(request_controller_.get()),
-                     std::move(callback)));
-}
-
 void NavigationURLLoaderNetworkService::OnReceiveResponse(
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     scoped_refptr<ResourceResponse> response,
-    const base::Optional<net::SSLInfo>& ssl_info,
+    const base::Optional<net::SSLInfo>& maybe_ssl_info,
     mojom::DownloadedTempFilePtr downloaded_file) {
+  TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
+                         "&NavigationURLLoaderNetworkService", this, "success",
+                         true);
+
   // TODO(scottmg): This needs to do more of what
-  // NavigationResourceHandler::OnResponseStarted() does. Or maybe in
-  // OnStartLoadingResponseBody().
-  response_ = std::move(response);
-  if (ssl_info.has_value())
-    ssl_info_ = ssl_info.value();
+  // NavigationResourceHandler::OnResponseStarted() does.
+  net::SSLInfo ssl_info;
+  if (maybe_ssl_info.has_value())
+    ssl_info = maybe_ssl_info.value();
+
+  // TODO(arthursonzogni): In NavigationMojoResponse, this is false. The info
+  // coming from the MimeSniffingResourceHandler must be used.
+  DCHECK(response);
+  bool is_download = allow_download_ && IsDownload(*response.get(), url_);
+
+  delegate_->OnResponseStarted(
+      std::move(response), std::move(url_loader_client_endpoints), nullptr,
+      std::move(ssl_info), std::unique_ptr<NavigationData>(),
+      GlobalRequestID(-1, g_next_request_id), is_download,
+      false /* is_stream */,
+      request_controller_->TakeSubresourceLoaderParams());
 }
 
 void NavigationURLLoaderNetworkService::OnReceiveRedirect(
@@ -699,24 +738,6 @@
   delegate_->OnRequestRedirected(redirect_info, std::move(response));
 }
 
-void NavigationURLLoaderNetworkService::OnStartLoadingResponseBody(
-    mojo::ScopedDataPipeConsumerHandle body) {
-  DCHECK(response_);
-
-  TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
-                         "&NavigationURLLoaderNetworkService", this, "success",
-                         true);
-
-  // Temporarily, we pass both a stream (null) and the data pipe to the
-  // delegate until PlzNavigate has shipped and we can be comfortable fully
-  // switching to the data pipe.
-  delegate_->OnResponseStarted(
-      response_, nullptr, std::move(body), ssl_info_,
-      std::unique_ptr<NavigationData>(), GlobalRequestID(-1, g_next_request_id),
-      IsDownload(), false /* is_stream */,
-      request_controller_->TakeSubresourceLoaderParams());
-}
-
 void NavigationURLLoaderNetworkService::OnComplete(
     const network::URLLoaderCompletionStatus& status) {
   if (status.error_code == net::OK)
@@ -730,42 +751,6 @@
                              status.ssl_info);
 }
 
-bool NavigationURLLoaderNetworkService::IsDownload() const {
-  DCHECK(response_);
-
-  if (!allow_download_)
-    return false;
-
-  if (response_->head.headers) {
-    std::string disposition;
-    if (response_->head.headers->GetNormalizedHeader("content-disposition",
-                                                     &disposition) &&
-        !disposition.empty() &&
-        net::HttpContentDisposition(disposition, std::string())
-            .is_attachment()) {
-      return true;
-    } else if (GetContentClient()->browser()->ShouldForceDownloadResource(
-                   url_, response_->head.mime_type)) {
-      return true;
-    } else if (response_->head.mime_type == "multipart/related") {
-      // TODO(https://crbug.com/790734): retrieve the new NavigationUIData from
-      // the request and and pass it to AllowRenderingMhtmlOverHttp().
-      return !GetContentClient()->browser()->AllowRenderingMhtmlOverHttp(
-          nullptr);
-    }
-    // TODO(qinmin): Check whether this is special-case user script that needs
-    // to be downloaded.
-  }
-
-  if (blink::IsSupportedMimeType(response_->head.mime_type))
-    return false;
-
-  // TODO(qinmin): Check whether there is a plugin handler.
-
-  return (!response_->head.headers ||
-          response_->head.headers->response_code() / 100 == 2);
-}
-
 void NavigationURLLoaderNetworkService::BindNonNetworkURLLoaderFactoryRequest(
     const GURL& url,
     mojom::URLLoaderFactoryRequest factory) {
diff --git a/content/browser/loader/navigation_url_loader_network_service.h b/content/browser/loader/navigation_url_loader_network_service.h
index 893e5e3..3c39e6d 100644
--- a/content/browser/loader/navigation_url_loader_network_service.h
+++ b/content/browser/loader/navigation_url_loader_network_service.h
@@ -45,30 +45,25 @@
   // NavigationURLLoader implementation:
   void FollowRedirect() override;
   void ProceedWithResponse() override;
-  void InterceptNavigation(NavigationInterceptionCB callback) override;
 
-  void OnReceiveResponse(scoped_refptr<ResourceResponse> response,
-                         const base::Optional<net::SSLInfo>& ssl_info,
-                         mojom::DownloadedTempFilePtr downloaded_file);
+  void OnReceiveResponse(
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      scoped_refptr<ResourceResponse> response,
+      const base::Optional<net::SSLInfo>& ssl_info,
+      mojom::DownloadedTempFilePtr downloaded_file);
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          scoped_refptr<ResourceResponse> response);
-  void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body);
   void OnComplete(const network::URLLoaderCompletionStatus& status);
 
  private:
   class URLLoaderRequestController;
 
-  bool IsDownload() const;
-
   void BindNonNetworkURLLoaderFactoryRequest(
       const GURL& url,
       mojom::URLLoaderFactoryRequest factory);
 
   NavigationURLLoaderDelegate* delegate_;
 
-  scoped_refptr<ResourceResponse> response_;
-  net::SSLInfo ssl_info_;
-
   // Lives on the IO thread.
   std::unique_ptr<URLLoaderRequestController> request_controller_;
 
diff --git a/content/browser/loader/resource_dispatcher_host_browsertest.cc b/content/browser/loader/resource_dispatcher_host_browsertest.cc
index 10f566e..dc1fffc 100644
--- a/content/browser/loader/resource_dispatcher_host_browsertest.cc
+++ b/content/browser/loader/resource_dispatcher_host_browsertest.cc
@@ -47,9 +47,12 @@
 #include "net/test/url_request/url_request_failed_job.h"
 #include "net/test/url_request/url_request_mock_http_job.h"
 #include "net/url_request/url_request.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "url/gurl.h"
 
 using base::ASCIIToUTF16;
+using testing::HasSubstr;
+using testing::Not;
 
 namespace content {
 
@@ -67,6 +70,7 @@
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
         base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
+    host_resolver()->AddRule("*", "127.0.0.1");
   }
 
   void OnDownloadCreated(DownloadManager* manager,
@@ -890,26 +894,17 @@
 
   EXPECT_EQ(8u, delegate_->data().size());
 
-  // All resources loaded directly by the top-level document (including the
-  // top-level document itself) should have a |first_party| and |initiator|
-  // that match the URL of the top-level document.
-  // PlzNavigate: the document itself should have an empty initiator.
-  if (IsBrowserSideNavigationEnabled()) {
-    const RequestDataForDelegate* first_request = delegate_->data()[0].get();
-    EXPECT_EQ(top_url, first_request->first_party);
-    EXPECT_FALSE(first_request->initiator.has_value());
-    for (size_t i = 1; i < delegate_->data().size(); i++) {
-      const RequestDataForDelegate* request = delegate_->data()[i].get();
-      EXPECT_EQ(top_url, request->first_party);
-      ASSERT_TRUE(request->initiator.has_value());
-      EXPECT_EQ(top_origin, request->initiator);
-    }
-  } else {
-    for (const auto& request : delegate_->data()) {
-      SCOPED_TRACE(request->url);
-      EXPECT_EQ(top_url, request->first_party);
-      EXPECT_EQ(top_origin, request->initiator);
-    }
+  // All resources loaded directly by the top-level document should have a
+  // |first_party| and |initiator| that match the URL of the top-level document.
+  // The top-level document itself doesn't have an |initiator|.
+  const RequestDataForDelegate* first_request = delegate_->data()[0].get();
+  EXPECT_EQ(top_url, first_request->first_party);
+  EXPECT_FALSE(first_request->initiator.has_value());
+  for (size_t i = 1; i < delegate_->data().size(); i++) {
+    const RequestDataForDelegate* request = delegate_->data()[i].get();
+    EXPECT_EQ(top_url, request->first_party);
+    ASSERT_TRUE(request->initiator.has_value());
+    EXPECT_EQ(top_origin, request->initiator);
   }
 }
 
@@ -931,16 +926,26 @@
                        LinkRelPrefetchReferrerPolicy) {
   GURL top_url(embedded_test_server()->GetURL(
       "/link_rel_prefetch_referrer_policy.html"));
+  GURL img_url(embedded_test_server()->GetURL("/image.jpg"));
   url::Origin top_origin = url::Origin::Create(top_url);
 
   NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
 
   EXPECT_EQ(2u, delegate_->data().size());
-  auto* request = delegate_->data()[1].get();
-  EXPECT_EQ(top_origin, request->initiator);
+  auto* main_frame_request = delegate_->data()[0].get();
+  auto* image_request = delegate_->data()[1].get();
+
+  // Check the main frame request.
+  EXPECT_EQ(top_url, main_frame_request->url);
+  EXPECT_FALSE(main_frame_request->initiator.has_value());
+
+  // Check the image request.
+  EXPECT_EQ(img_url, image_request->url);
+  EXPECT_TRUE(image_request->initiator.has_value());
+  EXPECT_EQ(top_origin, image_request->initiator);
   // Respect the "origin" policy set by the <meta> tag.
-  EXPECT_EQ(top_url.GetOrigin().spec(), request->referrer);
-  EXPECT_TRUE(request->load_flags & net::LOAD_PREFETCH);
+  EXPECT_EQ(top_url.GetOrigin().spec(), image_request->referrer);
+  EXPECT_TRUE(image_request->load_flags & net::LOAD_PREFETCH);
 }
 
 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
@@ -957,17 +962,12 @@
   EXPECT_EQ(9u, delegate_->data().size());
 
   // The first items loaded are the top-level and nested documents. These should
-  // both have a |first_party| and |initiator| that match the URL of the
-  // top-level document.
-  // PlzNavigate: the top-level initiator is null.
+  // both have a |first_party| that match the URL of the top-level document.
+  // The top-level document has no initiator and the nested frame is initiated
+  // by the top-level document.
   EXPECT_EQ(top_url, delegate_->data()[0]->url);
   EXPECT_EQ(top_url, delegate_->data()[0]->first_party);
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
-  } else {
-    ASSERT_TRUE(delegate_->data()[0]->initiator.has_value());
-    EXPECT_EQ(top_origin, delegate_->data()[0]->initiator);
-  }
+  EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
 
   EXPECT_EQ(nested_url, delegate_->data()[1]->url);
   EXPECT_EQ(top_url, delegate_->data()[1]->first_party);
@@ -994,17 +994,12 @@
 
   EXPECT_EQ(3u, delegate_->data().size());
 
-  // User-initiated top-level navigations have a first-party and initiator that
-  // matches the URL to which they navigate.
-  // PlzNavigate: the top-level initiator is null.
+  // User-initiated top-level navigations have a first-party that matches the
+  // URL to which they navigate. The navigation was initiated outside of a
+  // document, so there is no |initiator|.
   EXPECT_EQ(top_url, delegate_->data()[0]->url);
   EXPECT_EQ(top_url, delegate_->data()[0]->first_party);
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
-  } else {
-    ASSERT_TRUE(delegate_->data()[0]->initiator.has_value());
-    EXPECT_EQ(top_origin, delegate_->data()[0]->initiator);
-  }
+  EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
 
   // Subresource requests have a first-party and initiator that matches the
   // document in which they're embedded.
@@ -1039,17 +1034,12 @@
 
   EXPECT_EQ(2u, delegate_->data().size());
 
-  // User-initiated top-level navigations have a first-party and initiator that
-  // matches the URL to which they navigate, even if they fail to load.
-  // PlzNavigate: the top-level initiator is null.
+  // User-initiated top-level navigations have a first-party that matches the
+  // URL to which they navigate, even if they fail to load. The navigation was
+  // initiated outside of a document, so there is no |initiator|.
   EXPECT_EQ(top_url, delegate_->data()[0]->url);
   EXPECT_EQ(top_url, delegate_->data()[0]->first_party);
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
-  } else {
-    ASSERT_TRUE(delegate_->data()[0]->initiator.has_value());
-    EXPECT_EQ(top_origin, delegate_->data()[0]->initiator);
-  }
+  EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
 
   // Auxiliary navigations have a first-party that matches the URL to which they
   // navigate, and an initiator that matches the document that triggered them.
@@ -1086,17 +1076,12 @@
 
   EXPECT_EQ(2u, delegate_->data().size());
 
-  // User-initiated top-level navigations have a first-party and initiator that
-  // matches the URL to which they navigate, even if they fail to load.
-  // PlzNavigate: the top-level initiator is null.
+  // User-initiated top-level navigations have a first-party that matches the
+  // URL to which they navigate, even if they fail to load. The navigation was
+  // initiated outside of a document, so there is no initiator.
   EXPECT_EQ(top_url, delegate_->data()[0]->url);
   EXPECT_EQ(top_url, delegate_->data()[0]->first_party);
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
-  } else {
-    ASSERT_TRUE(delegate_->data()[0]->initiator.has_value());
-    EXPECT_EQ(top_origin, delegate_->data()[0]->initiator);
-  }
+  EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
 
   // Auxiliary navigations have a first-party that matches the URL to which they
   // navigate, and an initiator that matches the document that triggered them.
@@ -1116,17 +1101,12 @@
 
   EXPECT_EQ(1u, delegate_->data().size());
 
-  // User-initiated top-level navigations have a first-party and initiator that
-  // matches the URL to which they navigate, even if they fail to load.
-  // PlzNavigate: the top-level initiator is null.
+  // User-initiated top-level navigations have a first-party that matches the
+  // URL to which they navigate, even if they fail to load. The navigation was
+  // initiated outside of a document, so there is no initiator.
   EXPECT_EQ(top_url, delegate_->data()[0]->url);
   EXPECT_EQ(top_url, delegate_->data()[0]->first_party);
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
-  } else {
-    ASSERT_TRUE(delegate_->data()[0]->initiator.has_value());
-    EXPECT_EQ(top_origin, delegate_->data()[0]->initiator);
-  }
+  EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
 }
 
 IN_PROC_BROWSER_TEST_F(RequestDataResourceDispatcherHostBrowserTest,
@@ -1146,17 +1126,11 @@
 
   EXPECT_EQ(4u, delegate_->data().size());
 
-  // User-initiated top-level navigations have a first-party and initiator that
-  // matches the URL to which they navigate.
-  // PlzNavigate: the top-level initiator is null.
+  // User-initiated top-level navigations have a |first-party|. The navigation
+  // was initiated outside of a document, so there are no initiator.
   EXPECT_EQ(top_url, delegate_->data()[0]->url);
   EXPECT_EQ(top_url, delegate_->data()[0]->first_party);
-  if (IsBrowserSideNavigationEnabled()) {
-    EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
-  } else {
-    ASSERT_TRUE(delegate_->data()[0]->initiator.has_value());
-    EXPECT_EQ(top_origin, delegate_->data()[0]->initiator);
-  }
+  EXPECT_FALSE(delegate_->data()[0]->initiator.has_value());
 
   EXPECT_EQ(top_js_url, delegate_->data()[1]->url);
   EXPECT_EQ(top_url, delegate_->data()[1]->first_party);
@@ -1175,4 +1149,61 @@
   EXPECT_EQ(nested_origin, delegate_->data()[3]->initiator);
 }
 
+// Regression test for https://crbug.com/648608. An attacker could trivially
+// bypass cookies SameSite=Strict protections by navigating a new window twice.
+IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
+                       CookieSameSiteStrictOpenNewNamedWindowTwice) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // 1) Add cookies for 'a.com', one of them with the "SameSite=Strict" option.
+  BrowserContext* context = shell()->web_contents()->GetBrowserContext();
+  GURL a_url("http://a.com");
+  EXPECT_TRUE(SetCookie(context, a_url, "cookie_A=A; SameSite=Strict;"));
+  EXPECT_TRUE(SetCookie(context, a_url, "cookie_B=B"));
+
+  // 2) Navigate to malicious.com.
+  EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL(
+                                         "malicious.com", "/title1.html")));
+
+  // 2.1) malicious.com opens a new window to 'http://a.com/echoall'.
+  GURL echoall_url = embedded_test_server()->GetURL("a.com", "/echoall");
+  std::string script = base::StringPrintf("window.open('%s', 'named_frame');",
+                                          echoall_url.spec().c_str());
+  {
+    TestNavigationObserver new_tab_observer(shell()->web_contents(), 1);
+    new_tab_observer.StartWatchingNewWebContents();
+    EXPECT_TRUE(ExecuteScript(shell(), script));
+    new_tab_observer.Wait();
+    ASSERT_EQ(2u, Shell::windows().size());
+    Shell* new_shell = Shell::windows()[1];
+    EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));
+
+    // Only the cookie without "SameSite=Strict" should be sent.
+    std::string html_content;
+    EXPECT_TRUE(ExecuteScriptAndExtractString(
+        new_shell, "domAutomationController.send(document.body.textContent)",
+        &html_content));
+    EXPECT_THAT(html_content.c_str(), Not(HasSubstr("cookie_A=A")));
+    EXPECT_THAT(html_content.c_str(), HasSubstr("cookie_B=B"));
+  }
+
+  // 2.2) Same as in 2.1). The difference is that the new tab will be reused.
+  {
+    Shell* new_shell = Shell::windows()[1];
+    TestNavigationObserver new_tab_observer(new_shell->web_contents(), 1);
+    EXPECT_TRUE(ExecuteScript(shell(), script));
+    new_tab_observer.Wait();
+    ASSERT_EQ(2u, Shell::windows().size());
+    EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));
+
+    // Only the cookie without "SameSite=Strict" should be sent.
+    std::string html_content;
+    EXPECT_TRUE(ExecuteScriptAndExtractString(
+        new_shell, "domAutomationController.send(document.body.textContent)",
+        &html_content));
+    EXPECT_THAT(html_content.c_str(), Not(HasSubstr("cookie_A=A")));
+    EXPECT_THAT(html_content.c_str(), HasSubstr("cookie_B=B"));
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index a016c7db..96a9e2c 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1213,14 +1213,13 @@
     }
 
     new_request->set_method(request_data.method);
-
     new_request->set_site_for_cookies(request_data.site_for_cookies);
 
-    // The initiator should normally be present, unless this is a navigation in
-    // a top-level frame. It may be null for some top-level navigations (eg:
-    // browser-initiated ones).
+    // The initiator should normally be present, unless this is a navigation.
+    // Browser-initiated navigations don't have an initiator document, the
+    // others have one.
     DCHECK(request_data.request_initiator.has_value() ||
-           request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME);
+           IsResourceTypeFrame(request_data.resource_type));
     new_request->set_initiator(request_data.request_initiator);
 
     if (request_data.originated_from_service_worker) {
@@ -2015,7 +2014,7 @@
           info.common_params.url,
           resource_type,
           resource_context))) {
-    loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt, false);
+    loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt);
     return;
   }
 
@@ -2061,8 +2060,7 @@
   if (body) {
     if (!GetBodyBlobDataHandles(body, resource_context, &blob_handles)) {
       new_request->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
-      loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt,
-                                  false);
+      loader->NotifyRequestFailed(false, net::ERR_ABORTED, base::nullopt);
       return;
     }
     new_request->set_upload(UploadDataStreamBuilder::Build(
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 0fcb0638..998635c 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -104,7 +104,8 @@
   ASSERT_GE(messages.size(), 2U);
 
   // The first messages should be received response.
-  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            messages[0].type());
 
   base::PickleIterator iter(messages[0]);
   int request_id;
@@ -810,7 +811,8 @@
   int request_id;
   int error_code;
 
-  ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_RequestComplete::ID),
+            message.type());
 
   base::PickleIterator iter(message);
   ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
@@ -1006,7 +1008,7 @@
   }
 
   void GenerateDataReceivedACK(const IPC::Message& msg) {
-    EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
+    EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID), msg.type());
 
     int request_id = -1;
     bool result = base::PickleIterator(msg).ReadInt(&request_id);
@@ -1083,7 +1085,8 @@
     // We should have gotten one RequestComplete message.
     ASSERT_EQ(1U, msgs.size());
     ASSERT_EQ(1U, msgs[0].size());
-    EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
+    EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_RequestComplete::ID),
+              msgs[0][0].type());
 
     // The RequestComplete message should have had the expected error code.
     CheckRequestCompleteErrorCode(msgs[0][0], expected_error_code);
@@ -1275,9 +1278,11 @@
   ASSERT_EQ(4U, messages.size());
 
   // The first messages should be received response
-  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            messages[0].type());
 
-  ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_SetDataBuffer::ID),
+            messages[1].type());
 
   base::PickleIterator iter(messages[1]);
   int request_id;
@@ -1289,7 +1294,8 @@
 
   // Followed by the data, currently we only do the data in one chunk, but
   // should probably test multiple chunks later
-  ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+            messages[2].type());
 
   int data_offset;
   int data_length;
@@ -1316,7 +1322,8 @@
 void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages,
                              const std::string& reference_data) {
   ASSERT_EQ(5U, messages.size());
-  ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedRedirect::ID),
+            messages[0].type());
 
   const std::vector<IPC::Message> second_req_msgs =
       std::vector<IPC::Message>(messages.begin() + 1, messages.end());
@@ -1331,7 +1338,8 @@
   size_t failure_index = messages.size() - 1;
 
   if (messages.size() == 2) {
-    EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
+    EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+              messages[0].type());
   }
 
   CheckRequestCompleteErrorCode(messages[failure_index], expected_error);
@@ -1411,10 +1419,12 @@
   // Check that request 2 and 4 got canceled, as far as the renderer is
   // concerned.  Request 2 will have been deleted.
   ASSERT_EQ(1U, msgs[1].size());
-  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[1][0].type());
 
   ASSERT_EQ(2U, msgs[3].size());
-  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[3][0].type());
   CheckRequestCompleteErrorCode(msgs[3][1], net::ERR_ABORTED);
 
   // However, request 4 should have actually gone to completion. (Only request 2
@@ -1493,7 +1503,8 @@
   accum_.GetClassifiedMessages(&msgs);
   ASSERT_EQ(1U, msgs.size());
   ASSERT_EQ(2U, msgs[0].size());
-  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[0][0].type());
   CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
 
   // But it continues detached.
@@ -1967,7 +1978,8 @@
   // The detachable request was cancelled by the renderer before it
   // finished. From the perspective of the renderer, it should have cancelled.
   ASSERT_EQ(2U, msgs[1].size());
-  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[1][0].type());
   CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED);
   // But it completed anyway. For the network stack, no requests were canceled.
   EXPECT_EQ(4, network_delegate()->completed_requests());
@@ -2069,7 +2081,8 @@
 
   // The request should have cancelled.
   ASSERT_EQ(2U, msgs[0].size());
-  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
+  ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[0][0].type());
   CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
   // And not run to completion.
   EXPECT_EQ(1, network_delegate()->completed_requests());
@@ -2815,7 +2828,8 @@
   accum_.GetClassifiedMessages(&msgs);
 
   ASSERT_EQ(2U, msgs.size());
-  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedRedirect::ID),
+            msgs[0][0].type());
   CheckSuccessfulRequest(msgs[1], kResponseBody);
 
   second_filter->OnChannelClosing();
@@ -2969,7 +2983,8 @@
   accum_.GetClassifiedMessages(&msgs);
 
   ASSERT_EQ(2U, msgs.size());
-  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedRedirect::ID),
+            msgs[0][0].type());
   CheckSuccessfulRequest(msgs[1], kResponseBody);
 
   second_filter->OnChannelClosing();
@@ -3055,7 +3070,8 @@
   accum_.GetClassifiedMessages(&msgs);
 
   ASSERT_EQ(2U, msgs.size());
-  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedRedirect::ID),
+            msgs[0][0].type());
   CheckSuccessfulRequest(msgs[1], kResponseBody);
 
   second_filter->OnChannelClosing();
@@ -3144,7 +3160,8 @@
   accum_.GetClassifiedMessages(&msgs);
 
   ASSERT_EQ(2U, msgs.size());
-  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedRedirect::ID),
+            msgs[0][0].type());
   CheckSuccessfulRequest(msgs[1], kResponseBody);
 
   second_filter->OnChannelClosing();
@@ -3178,11 +3195,15 @@
 
   size_t size = msgs[0].size();
 
-  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
-  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[0][0].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_SetDataBuffer::ID),
+            msgs[0][1].type());
   for (size_t i = 2; i < size - 1; ++i)
-    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
-  EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
+    EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+              msgs[0][i].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_RequestComplete::ID),
+            msgs[0][size - 1].type());
 }
 
 // Request a very large detachable resource and cancel part way. Some of the
@@ -3256,10 +3277,13 @@
   accum_.GetClassifiedMessages(&msgs);
 
   // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
-  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
-  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[0][0].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_SetDataBuffer::ID),
+            msgs[0][1].type());
   for (size_t i = 2; i < msgs[0].size(); ++i)
-    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
+    EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+              msgs[0][i].type());
 
   // NOTE: If we fail the above checks then it means that we probably didn't
   // load a big enough response to trigger the delay mechanism we are trying to
@@ -3277,7 +3301,8 @@
         break;
       }
 
-      EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
+      EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+                msgs[0][i].type());
 
       ResourceHostMsg_DataReceived_ACK msg(1);
       OnMessageReceived(msg, filter_.get());
@@ -3305,10 +3330,13 @@
   accum_.GetClassifiedMessages(&msgs);
 
   // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
-  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
-  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_ReceivedResponse::ID),
+            msgs[0][0].type());
+  EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_SetDataBuffer::ID),
+            msgs[0][1].type());
   for (size_t i = 2; i < msgs[0].size(); ++i)
-    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
+    EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+              msgs[0][i].type());
 
   // NOTE: If we fail the above checks then it means that we probably didn't
   // load a big enough response to trigger the delay mechanism.
@@ -3331,7 +3359,8 @@
         break;
       }
 
-      EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
+      EXPECT_EQ(static_cast<uint32_t>(ResourceMsg_DataReceived::ID),
+                msgs[0][i].type());
 
       ResourceHostMsg_DataReceived_ACK msg(1);
       OnMessageReceived(msg, filter_.get());
@@ -3510,7 +3539,8 @@
   // DataDownloaded
   size_t total_len = 0;
   for (size_t i = 1; i < messages.size() - 1; i++) {
-    ASSERT_EQ(ResourceMsg_DataDownloaded::ID, messages[i].type());
+    ASSERT_EQ(static_cast<uint32_t>(ResourceMsg_DataDownloaded::ID),
+              messages[i].type());
     base::PickleIterator iter(messages[i]);
     int request_id, data_len;
     ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &request_id));
diff --git a/content/browser/locks/OWNERS b/content/browser/locks/OWNERS
new file mode 100644
index 0000000..6581c5ee
--- /dev/null
+++ b/content/browser/locks/OWNERS
@@ -0,0 +1,5 @@
+jsbell@chromium.org
+pwnall@chromium.org
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage
diff --git a/content/browser/locks/lock_manager.cc b/content/browser/locks/lock_manager.cc
new file mode 100644
index 0000000..f2613ef6b
--- /dev/null
+++ b/content/browser/locks/lock_manager.cc
@@ -0,0 +1,200 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/locks/lock_manager.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/stl_util.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace content {
+
+namespace {
+
+template <typename T>
+bool Intersects(const std::vector<T>& a, const std::unordered_set<T>& b) {
+  for (const auto& k : a) {
+    if (b.find(k) != b.end())
+      return true;
+  }
+  return false;
+}
+
+// A LockHandle is passed to the client when a lock is granted. As long as the
+// handle is held, the lock is held. Dropping the handle - either explicitly
+// by script or by process termination - causes the lock to be released.
+class LockHandleImpl final : public blink::mojom::LockHandle {
+ public:
+  static blink::mojom::LockHandlePtr Create(base::WeakPtr<LockManager> context,
+                                            const url::Origin& origin,
+                                            int64_t lock_id) {
+    blink::mojom::LockHandlePtr ptr;
+    mojo::MakeStrongBinding(
+        base::MakeUnique<LockHandleImpl>(std::move(context), origin, lock_id),
+        mojo::MakeRequest(&ptr));
+    return ptr;
+  }
+
+  LockHandleImpl(base::WeakPtr<LockManager> context,
+                 const url::Origin& origin,
+                 int64_t lock_id)
+      : context_(context), origin_(origin), lock_id_(lock_id) {}
+
+  ~LockHandleImpl() override {
+    if (context_)
+      context_->ReleaseLock(origin_, lock_id_);
+  }
+
+ private:
+  base::WeakPtr<LockManager> context_;
+  const url::Origin origin_;
+  const int64_t lock_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(LockHandleImpl);
+};
+
+}  // namespace
+
+// A requested or held lock. When granted, a LockHandle will be minted
+// and passed to the held callback. Eventually the client will drop the
+// handle, which will notify the context and remove this.
+struct LockManager::Lock {
+  Lock(std::vector<std::string> scope,
+       LockMode mode,
+       int64_t id,
+       blink::mojom::LockRequestPtr request)
+      : scope(std::move(scope)),
+        mode(mode),
+        id(id),
+        request(std::move(request)) {}
+
+  ~Lock() = default;
+
+  const std::vector<std::string> scope;
+  const LockMode mode;
+  const int64_t id;
+  blink::mojom::LockRequestPtr request;
+};
+
+LockManager::LockManager() : weak_ptr_factory_(this) {}
+
+LockManager::~LockManager() = default;
+
+LockManager::OriginState::OriginState() = default;
+LockManager::OriginState::~OriginState() = default;
+
+bool LockManager::OriginState::IsGrantable(
+    const std::vector<std::string>& scope,
+    LockMode mode) const {
+  if (mode == LockMode::EXCLUSIVE) {
+    return !Intersects(scope, shared) && !Intersects(scope, exclusive);
+  } else {
+    return !Intersects(scope, exclusive);
+  }
+}
+
+void LockManager::OriginState::MergeLockState(
+    const std::vector<std::string>& scope,
+    LockMode mode) {
+  (mode == LockMode::SHARED ? shared : exclusive)
+      .insert(scope.begin(), scope.end());
+}
+
+void LockManager::CreateService(blink::mojom::LockManagerRequest request) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  bindings_.AddBinding(this, std::move(request));
+}
+
+void LockManager::RequestLock(const url::Origin& origin,
+                              const std::vector<std::string>& scope,
+                              LockMode mode,
+                              WaitMode wait,
+                              blink::mojom::LockRequestPtr request) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (wait == WaitMode::NO_WAIT && !IsGrantable(origin, scope, mode)) {
+    request->Failed();
+    return;
+  }
+
+  int64_t lock_id = next_lock_id++;
+
+  request.set_connection_error_handler(base::BindOnce(
+      &LockManager::ReleaseLock, base::Unretained(this), origin, lock_id));
+
+  origins_[origin].requested.emplace(std::make_pair(
+      lock_id, std::make_unique<Lock>(std::move(scope), mode, lock_id,
+                                      std::move(request))));
+
+  ProcessRequests(origin);
+}
+
+void LockManager::ReleaseLock(const url::Origin& origin, int64_t id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!base::ContainsKey(origins_, origin))
+    return;
+  OriginState& state = origins_[origin];
+
+  bool dirty = state.requested.erase(id) || state.held.erase(id);
+
+  if (state.requested.empty() && state.held.empty())
+    origins_.erase(origin);
+  else if (dirty)
+    ProcessRequests(origin);
+}
+
+bool LockManager::IsGrantable(const url::Origin& origin,
+                              const std::vector<std::string>& scope,
+                              LockMode mode) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!base::ContainsKey(origins_, origin))
+    return true;
+
+  return origins_[origin].IsGrantable(scope, mode);
+}
+
+void LockManager::ProcessRequests(const url::Origin& origin) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!base::ContainsKey(origins_, origin))
+    return;
+
+  OriginState& state = origins_[origin];
+
+  if (state.requested.empty())
+    return;
+
+  state.shared.clear();
+  state.exclusive.clear();
+  for (const auto& id_lock_pair : state.held) {
+    const auto& lock = id_lock_pair.second;
+    state.MergeLockState(lock->scope, lock->mode);
+  }
+
+  for (auto it = state.requested.begin(); it != state.requested.end();) {
+    auto& lock = it->second;
+
+    bool granted = state.IsGrantable(lock->scope, lock->mode);
+
+    state.MergeLockState(lock->scope, lock->mode);
+
+    if (granted) {
+      std::unique_ptr<Lock> grantee = std::move(lock);
+      it = state.requested.erase(it);
+      grantee->request->Granted(LockHandleImpl::Create(
+          weak_ptr_factory_.GetWeakPtr(), origin, grantee->id));
+      grantee->request = nullptr;
+      state.held.insert(std::make_pair(grantee->id, std::move(grantee)));
+    } else {
+      ++it;
+    }
+  }
+
+  DCHECK(!(state.requested.empty() && state.held.empty()));
+}
+
+}  // namespace content
diff --git a/content/browser/locks/lock_manager.h b/content/browser/locks/lock_manager.h
new file mode 100644
index 0000000..9453a3e
--- /dev/null
+++ b/content/browser/locks/lock_manager.h
@@ -0,0 +1,91 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOCKS_LOCK_CONTEXT_H_
+#define CONTENT_BROWSER_LOCKS_LOCK_CONTEXT_H_
+
+#include <memory>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
+#include "content/public/browser/browser_context.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "third_party/WebKit/public/platform/modules/locks/lock_manager.mojom.h"
+#include "url/origin.h"
+
+namespace content {
+
+// One instance of this exists per StoragePartition, and services multiple
+// child processes/origins. An instance must only be used on the sequence
+// it was created on.
+class LockManager : public base::RefCountedThreadSafe<LockManager>,
+                    public blink::mojom::LockManager {
+ public:
+  LockManager();
+
+  void CreateService(blink::mojom::LockManagerRequest request);
+
+  // Request a lock. When the lock is acquired, |callback| will be invoked with
+  // a LockHandle.
+  void RequestLock(const url::Origin& origin,
+                   const std::vector<std::string>& scope,
+                   LockMode mode,
+                   WaitMode wait,
+                   blink::mojom::LockRequestPtr request) override;
+
+  // Called by a LockHandle's implementation when destructed.
+  void ReleaseLock(const url::Origin& origin, int64_t id);
+
+ protected:
+  friend class base::RefCountedThreadSafe<LockManager>;
+  ~LockManager() override;
+
+ private:
+  // Internal representation of a lock request or held lock.
+  struct Lock;
+
+  // State for a particular origin.
+  struct OriginState {
+    OriginState();
+    ~OriginState();
+
+    bool IsGrantable(const std::vector<std::string>& scope,
+                     LockMode mode) const;
+    void MergeLockState(const std::vector<std::string>& scope, LockMode mode);
+
+    std::map<int64_t, std::unique_ptr<Lock>> requested;
+    std::map<int64_t, std::unique_ptr<Lock>> held;
+
+    // These sets represent what is held or requested, so that "IsGrantable"
+    // tests are simple.
+    std::unordered_set<std::string> shared;
+    std::unordered_set<std::string> exclusive;
+  };
+
+  bool IsGrantable(const url::Origin& origin,
+                   const std::vector<std::string>& scope,
+                   LockMode mode);
+
+  // Called when a lock is requested and optionally when a lock is released,
+  // to process outstanding requests within the origin.
+  void ProcessRequests(const url::Origin& origin);
+
+  mojo::BindingSet<blink::mojom::LockManager> bindings_;
+
+  int64_t next_lock_id = 1;
+  std::map<url::Origin, OriginState> origins_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+  base::WeakPtrFactory<LockManager> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(LockManager);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_LOCKS_LOCK_CONTEXT_H
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc
index 59f548f0..52901f2c 100644
--- a/content/browser/network_service_restart_browsertest.cc
+++ b/content/browser/network_service_restart_browsertest.cc
@@ -4,7 +4,10 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/network_service_instance.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/network_service.mojom.h"
 #include "content/public/common/network_service_test.mojom.h"
@@ -13,6 +16,7 @@
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/public/test/simple_url_loader_test_helper.h"
+#include "content/shell/browser/shell.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/service_manager/public/cpp/connector.h"
 
@@ -44,18 +48,28 @@
     mojom::NetworkServiceTestPtr network_service_test;
     ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
         mojom::kNetworkServiceName, &network_service_test);
+
+    base::RunLoop run_loop;
+    network_service_test.set_connection_error_handler(run_loop.QuitClosure());
+
     network_service_test->SimulateCrash();
-    network_service_test.FlushForTesting();
+    run_loop.Run();
   }
 
   int LoadBasicRequest(mojom::NetworkContext* network_context) {
     mojom::URLLoaderFactoryPtr url_loader_factory;
     network_context->CreateURLLoaderFactory(MakeRequest(&url_loader_factory),
                                             0);
+    // |url_loader_factory| will receive error notification asynchronously if
+    // |network_context| has already encountered error. However it's still false
+    // at this point.
+    EXPECT_FALSE(url_loader_factory.encountered_error());
 
     std::unique_ptr<ResourceRequest> request =
         std::make_unique<ResourceRequest>();
-    request->url = embedded_test_server()->GetURL("/echo");
+    // Use '/echoheader' instead of '/echo' to avoid a disk_cache bug.
+    // See https://crbug.com/792255.
+    request->url = embedded_test_server()->GetURL("/echoheader");
 
     content::SimpleURLLoaderTestHelper simple_loader_helper;
     std::unique_ptr<content::SimpleURLLoader> simple_loader =
@@ -81,12 +95,17 @@
   EXPECT_TRUE(network_context.is_bound());
   EXPECT_FALSE(network_context.encountered_error());
 
-  // Crash the NetworkService process. Existing interfaces should observe
-  // connection errors.
+  // Crash the NetworkService process. Existing interfaces should receive error
+  // notifications at some point.
   SimulateNetworkServiceCrash();
-  EXPECT_EQ(net::ERR_FAILED, LoadBasicRequest(network_context.get()));
+  // |network_context| will receive an error notification, but it's not
+  // guaranteed to have arrived at this point. Flush the pointer to make sure
+  // the notification has been received.
+  network_context.FlushForTesting();
   EXPECT_TRUE(network_context.is_bound());
   EXPECT_TRUE(network_context.encountered_error());
+  // Make sure we could get |net::ERR_FAILED| with an invalid |network_context|.
+  EXPECT_EQ(net::ERR_FAILED, LoadBasicRequest(network_context.get()));
 
   // NetworkService should restart automatically and return valid interface.
   mojom::NetworkContextPtr network_context2 = CreateNetworkContext();
@@ -95,4 +114,27 @@
   EXPECT_FALSE(network_context2.encountered_error());
 }
 
+// Make sure |StoragePartitionImpl::GetNetworkContext()| returns valid interface
+// after crash.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
+                       StoragePartitionImplGetNetworkContext) {
+  StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+      BrowserContext::GetDefaultStoragePartition(
+          shell()->web_contents()->GetBrowserContext()));
+
+  mojom::NetworkContext* old_network_context = partition->GetNetworkContext();
+  EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context));
+
+  // Crash the NetworkService process. Existing interfaces should receive error
+  // notifications at some point.
+  SimulateNetworkServiceCrash();
+  // Flush the interface to make sure the error notification was received.
+  partition->FlushNetworkInterfaceForTesting();
+
+  // |partition->GetNetworkContext()| should return a valid new pointer after
+  // crash.
+  EXPECT_NE(old_network_context, partition->GetNetworkContext());
+  EXPECT_EQ(net::OK, LoadBasicRequest(partition->GetNetworkContext()));
+}
+
 }  // namespace content
diff --git a/content/browser/notifications/blink_notification_service_impl.cc b/content/browser/notifications/blink_notification_service_impl.cc
index fd3420da..eca495e 100644
--- a/content/browser/notifications/blink_notification_service_impl.cc
+++ b/content/browser/notifications/blink_notification_service_impl.cc
@@ -5,11 +5,13 @@
 #include "content/browser/notifications/blink_notification_service_impl.h"
 
 #include "base/logging.h"
+#include "base/strings/string16.h"
 #include "content/browser/notifications/platform_notification_context_impl.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/platform_notification_service.h"
 #include "content/public/common/content_client.h"
+#include "content/public/common/notification_resources.h"
 #include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h"
 #include "url/gurl.h"
 
@@ -26,22 +28,25 @@
 
 BlinkNotificationServiceImpl::BlinkNotificationServiceImpl(
     PlatformNotificationContextImpl* notification_context,
+    BrowserContext* browser_context,
     ResourceContext* resource_context,
     int render_process_id,
     const url::Origin& origin,
     mojo::InterfaceRequest<blink::mojom::NotificationService> request)
     : notification_context_(notification_context),
+      browser_context_(browser_context),
       resource_context_(resource_context),
       render_process_id_(render_process_id),
       origin_(origin),
       binding_(this, std::move(request)) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(notification_context_);
+  DCHECK(browser_context_);
   DCHECK(resource_context_);
 
   binding_.set_connection_error_handler(base::BindOnce(
       &BlinkNotificationServiceImpl::OnConnectionError,
-      base::Unretained(this) /* the channel is owned by this */));
+      base::Unretained(this) /* the channel is owned by |this| */));
 }
 
 BlinkNotificationServiceImpl::~BlinkNotificationServiceImpl() {
@@ -68,4 +73,22 @@
   // |this| has now been deleted.
 }
 
+void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
+    const base::string16& title) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!Service())
+    return;
+  PlatformNotificationData platform_notification_data;
+  platform_notification_data.title = title;
+  // TODO(crbug.com/595685): Plumb through the rest of the notification data and
+  // the notification resources from blink.
+  // Using base::Unretained is safe because Service() returns a singleton.
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&PlatformNotificationService::DisplayNotification,
+                     base::Unretained(Service()), browser_context_, "",
+                     origin_.GetURL(), platform_notification_data,
+                     NotificationResources()));
+}
+
 }  // namespace content
diff --git a/content/browser/notifications/blink_notification_service_impl.h b/content/browser/notifications/blink_notification_service_impl.h
index 140784d..75bb1a83 100644
--- a/content/browser/notifications/blink_notification_service_impl.h
+++ b/content/browser/notifications/blink_notification_service_impl.h
@@ -6,6 +6,7 @@
 #define CONTENT_BROWSER_NOTIFICATIONS_BLINK_NOTIFICATION_SERVICE_IMPL_H_
 
 #include "base/macros.h"
+#include "content/public/browser/browser_context.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "third_party/WebKit/public/platform/modules/notifications/notification_service.mojom.h"
@@ -23,6 +24,7 @@
  public:
   BlinkNotificationServiceImpl(
       PlatformNotificationContextImpl* notification_context,
+      BrowserContext* browser_context,
       ResourceContext* resource_context,
       int render_process_id,
       const url::Origin& origin,
@@ -31,6 +33,7 @@
 
   // blink::mojom::NotificationService implementation.
   void GetPermissionStatus(GetPermissionStatusCallback callback) override;
+  void DisplayNonPersistentNotification(const base::string16& title) override;
 
  private:
   // Called when an error is detected on binding_.
@@ -39,6 +42,8 @@
   // The notification context that owns this service instance.
   PlatformNotificationContextImpl* notification_context_;
 
+  BrowserContext* browser_context_;
+
   ResourceContext* resource_context_;
 
   int render_process_id_;
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc
index f9be0328..60d9514 100644
--- a/content/browser/notifications/platform_notification_context_impl.cc
+++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -142,7 +142,8 @@
     mojo::InterfaceRequest<blink::mojom::NotificationService> request) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   services_.push_back(std::make_unique<BlinkNotificationServiceImpl>(
-      this, resource_context, render_process_id, origin, std::move(request)));
+      this, browser_context_, resource_context, render_process_id, origin,
+      std::move(request)));
 }
 
 void PlatformNotificationContextImpl::RemoveService(
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.h b/content/browser/renderer_host/browser_compositor_view_mac.h
index fbcad2d..5634790 100644
--- a/content/browser/renderer_host/browser_compositor_view_mac.h
+++ b/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -15,7 +15,6 @@
 #include "ui/compositor/compositor_observer.h"
 
 namespace ui {
-class AcceleratedWidgetMac;
 class AcceleratedWidgetMacNSView;
 }
 
@@ -57,10 +56,7 @@
   // potentially visible).
   void ClearCompositorFrame();
 
-  // This may return nullptr, if this has detached itself from its
-  // ui::Compositor.
-  ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac();
-
+  gfx::AcceleratedWidget GetAcceleratedWidget();
   void DidCreateNewRendererCompositorFrameSink(
       viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink);
   void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
@@ -69,6 +65,7 @@
   void SetBackgroundColor(SkColor background_color);
   void SetDisplayColorSpace(const gfx::ColorSpace& color_space);
   void WasResized();
+  bool HasFrameOfSize(const gfx::Size& desired_size);
   void UpdateVSyncParameters(const base::TimeTicks& timebase,
                              const base::TimeDelta& interval);
   void SetNeedsBeginFrames(bool needs_begin_frames);
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm
index 0b07a42..6cb6a6a50 100644
--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -215,10 +215,12 @@
     g_spare_recyclable_compositors.Get().clear();
 }
 
-ui::AcceleratedWidgetMac* BrowserCompositorMac::GetAcceleratedWidgetMac() {
-  if (recyclable_compositor_)
-    return recyclable_compositor_->accelerated_widget_mac();
-  return nullptr;
+gfx::AcceleratedWidget BrowserCompositorMac::GetAcceleratedWidget() {
+  if (recyclable_compositor_) {
+    return recyclable_compositor_->accelerated_widget_mac()
+        ->accelerated_widget();
+  }
+  return gfx::kNullAcceleratedWidget;
 }
 
 DelegatedFrameHost* BrowserCompositorMac::GetDelegatedFrameHost() {
@@ -350,6 +352,14 @@
   }
 }
 
+bool BrowserCompositorMac::HasFrameOfSize(const gfx::Size& desired_size) {
+  if (recyclable_compositor_) {
+    return recyclable_compositor_->accelerated_widget_mac()->HasFrameOfSize(
+        desired_size);
+  }
+  return false;
+}
+
 void BrowserCompositorMac::UpdateVSyncParameters(
     const base::TimeTicks& timebase,
     const base::TimeDelta& interval) {
diff --git a/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc b/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc
index a85f9fe..b4d593b1 100644
--- a/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc
+++ b/content/browser/renderer_host/input/legacy_input_router_impl_unittest.cc
@@ -104,7 +104,7 @@
 
 template <typename MSG_T, typename ARG_T1>
 void ExpectIPCMessageWithArg1(const IPC::Message* msg, const ARG_T1& arg1) {
-  ASSERT_EQ(MSG_T::ID, msg->type());
+  ASSERT_EQ(static_cast<uint32_t>(MSG_T::ID), msg->type());
   typename MSG_T::Schema::Param param;
   ASSERT_TRUE(MSG_T::Read(msg, &param));
   EXPECT_EQ(arg1, std::get<0>(param));
@@ -114,7 +114,7 @@
 void ExpectIPCMessageWithArg2(const IPC::Message* msg,
                               const ARG_T1& arg1,
                               const ARG_T2& arg2) {
-  ASSERT_EQ(MSG_T::ID, msg->type());
+  ASSERT_EQ(static_cast<uint32_t>(MSG_T::ID), msg->type());
   typename MSG_T::Schema::Param param;
   ASSERT_TRUE(MSG_T::Read(msg, &param));
   EXPECT_EQ(arg1, std::get<0>(param));
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
index e70df7a4..b5ea6943c 100644
--- a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
@@ -32,6 +32,7 @@
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/socket/tcp_client_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "ppapi/host/dispatch_host_message.h"
 #include "ppapi/host/error_conversion.h"
 #include "ppapi/host/ppapi_host.h"
@@ -684,12 +685,12 @@
   int net_result = net::ERR_FAILED;
   if (socket_) {
     DCHECK_EQ(state_.state(), TCPSocketState::CONNECTED);
+    // TODO(crbug.com/656607): Add proper annotation.
     net_result = socket_->Write(
-        write_buffer_.get(),
-        write_buffer_->BytesRemaining(),
+        write_buffer_.get(), write_buffer_->BytesRemaining(),
         base::Bind(&PepperTCPSocketMessageFilter::OnWriteCompleted,
-                   base::Unretained(this),
-                   context));
+                   base::Unretained(this), context),
+        NO_TRAFFIC_ANNOTATION_BUG_656607);
   } else if (ssl_socket_) {
     DCHECK_EQ(state_.state(), TCPSocketState::SSL_CONNECTED);
     net_result = ssl_socket_->Write(
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 548de2a..3d38968 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1734,8 +1734,6 @@
   }
   AddFilter(
       new MidiHost(GetID(), BrowserMainLoop::GetInstance()->midi_service()));
-  AddFilter(new AppCacheDispatcherHost(
-      storage_partition_impl_->GetAppCacheService(), GetID()));
   AddFilter(new DOMStorageMessageFilter(
       storage_partition_impl_->GetDOMStorageContext()));
 
@@ -1932,6 +1930,11 @@
   registry->AddInterface(
       base::Bind(&CreateReportingServiceProxy, storage_partition_impl_));
 
+  registry->AddInterface(base::BindRepeating(
+      &AppCacheDispatcherHost::Create,
+      base::Unretained(storage_partition_impl_->GetAppCacheService()), GetID(),
+      instance_weak_factory_->GetWeakPtr()));
+
   AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create));
 
   associated_interfaces_.reset(new AssociatedInterfaceRegistryImpl());
@@ -4145,7 +4148,8 @@
 
   // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
   // Capture the error message in a crash key value.
-  base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
+  base::debug::ScopedCrashKeyString error_key_value(
+      bad_message::GetMojoErrorCrashKey(), error);
   bad_message::ReceivedBadMessage(render_process_id,
                                   bad_message::RPH_MOJO_PROCESS_ERROR);
 }
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index f195187..a353da1a 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2662,7 +2662,7 @@
     uint64_t submit_time) {
   // TODO(gklassen): Route hit-test data to appropriate HitTestAggregator.
   TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
-                        "SubmitCompositorFrame", local_surface_id.parent_id());
+                        "SubmitCompositorFrame", local_surface_id.hash());
   bool tracing_enabled;
   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
                                      &tracing_enabled);
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 9b9d8f9..429dff66 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -1196,9 +1196,9 @@
 
   // Make sure we sent commands and key event to the renderer.
   EXPECT_EQ(2U, process_->sink().message_count());
-  EXPECT_EQ(InputMsg_SetEditCommandsForNextKeyEvent::ID,
+  EXPECT_EQ(static_cast<uint32_t>(InputMsg_SetEditCommandsForNextKeyEvent::ID),
             process_->sink().GetMessageAt(0)->type());
-  EXPECT_EQ(InputMsg_HandleInputEvent::ID,
+  EXPECT_EQ(static_cast<uint32_t>(InputMsg_HandleInputEvent::ID),
             process_->sink().GetMessageAt(1)->type());
   process_->sink().ClearMessages();
 
@@ -1255,7 +1255,7 @@
   // Simulate a new RawKeyDown event.
   SimulateKeyboardEvent(WebInputEvent::kRawKeyDown);
   EXPECT_EQ(1U, process_->sink().message_count());
-  EXPECT_EQ(InputMsg_HandleInputEvent::ID,
+  EXPECT_EQ(static_cast<uint32_t>(InputMsg_HandleInputEvent::ID),
             process_->sink().GetMessageAt(0)->type());
   process_->sink().ClearMessages();
 
@@ -2348,7 +2348,8 @@
   EXPECT_EQ(process->sink().message_count(), 1U);
 
   const IPC::Message* message = process->sink().GetMessageAt(0);
-  EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
+  EXPECT_EQ(static_cast<uint32_t>(InputMsg_HandleInputEvent::ID),
+            message->type());
   InputMsg_HandleInputEvent::Param params;
   EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
 
@@ -2367,7 +2368,8 @@
     int64_t component_id) {
   EXPECT_EQ(process->sink().message_count(), 2U);
   const IPC::Message* message = process->sink().GetMessageAt(0);
-  EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
+  EXPECT_EQ(static_cast<uint32_t>(InputMsg_HandleInputEvent::ID),
+            message->type());
   InputMsg_HandleInputEvent::Param params;
   EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
 
@@ -2377,7 +2379,8 @@
   EXPECT_TRUE(event->GetType() == WebInputEvent::kTouchScrollStarted);
 
   message = process->sink().GetMessageAt(1);
-  EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
+  EXPECT_EQ(static_cast<uint32_t>(InputMsg_HandleInputEvent::ID),
+            message->type());
   EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
 
   event = std::get<0>(params);
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 3adf96ed..46a5b64 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2079,18 +2079,6 @@
   return root_window->GetHost()->GetInputMethod();
 }
 
-RenderWidgetHostViewBase*
-RenderWidgetHostViewAura::GetFocusedViewForTextSelection() {
-  // We obtain the TextSelection from focused RWH which is obtained from the
-  // frame tree. BrowserPlugin-based guests' RWH is not part of the frame tree
-  // and the focused RWH will be that of the embedder which is incorrect. In
-  // this case we should use TextSelection for |this| since RWHV for guest
-  // forwards text selection information to its platform view.
-  return is_guest_view_hack_
-             ? this
-             : GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
-}
-
 void RenderWidgetHostViewAura::Shutdown() {
   if (!in_shutdown_) {
     in_shutdown_ = true;
@@ -2418,28 +2406,6 @@
     RenderWidgetHostViewBase* updated_view) {
   if (GetInputMethod())
     GetInputMethod()->OnCaretBoundsChanged(this);
-
-#if defined(OS_WIN)
-  RenderWidgetHostViewBase* focused_view = GetFocusedViewForTextSelection();
-  if (!focused_view)
-    return;
-
-  // Some assistive software need to track the location of the caret.
-  if (!GetRenderWidgetHost() || !legacy_render_widget_host_HWND_)
-    return;
-
-  // Not using |GetCaretBounds| because it includes the whole of the selection,
-  // not just the focus.
-  const TextInputManager::SelectionRegion* region =
-      GetTextInputManager()->GetSelectionRegion(focused_view);
-  if (!region)
-    return;
-
-  const gfx::Rect caret_rect = ConvertRectToScreen(gfx::Rect(
-      region->focus.edge_top_rounded().x(),
-      region->focus.edge_top_rounded().y(), 1, region->focus.GetHeight()));
-  legacy_render_widget_host_HWND_->MoveCaretTo(caret_rect);
-#endif  // defined(OS_WIN)
 }
 
 void RenderWidgetHostViewAura::OnTextSelectionChanged(
@@ -2454,9 +2420,9 @@
   // this case we should use TextSelection for |this| since RWHV for guest
   // forwards text selection information to its platform view.
   RenderWidgetHostViewBase* focused_view =
-      is_guest_view_hack_
-          ? this
-          : GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
+      is_guest_view_hack_ ? this : GetFocusedWidget()
+                                       ? GetFocusedWidget()->GetView()
+                                       : nullptr;
 
   if (!focused_view)
     return;
@@ -2469,7 +2435,23 @@
     ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_SELECTION);
     clipboard_writer.WriteText(selection->selected_text());
   }
-#endif  // defined(USE_X11)
+
+#elif defined(OS_WIN)
+  // Some assistive software need to track the location of the caret.
+  if (!GetRenderWidgetHost() || !legacy_render_widget_host_HWND_)
+    return;
+
+  // Not using |GetCaretBounds| because it includes the whole of the selection,
+  // not just the focus.
+  const TextInputManager::SelectionRegion* region =
+      GetTextInputManager()->GetSelectionRegion(focused_view);
+  if (!region)
+    return;
+  const gfx::Rect caret_rect = ConvertRectToScreen(gfx::Rect(
+      region->focus.edge_top_rounded().x(),
+      region->focus.edge_top_rounded().y(), 1, region->focus.GetHeight()));
+  legacy_render_widget_host_HWND_->MoveCaretTo(caret_rect);
+#endif  // defined(OS_WIN)
 }
 
 void RenderWidgetHostViewAura::SetPopupChild(
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 93b47a86..8e29d81 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -448,9 +448,6 @@
 
   ui::InputMethod* GetInputMethod() const;
 
-  // Get the focused view that should be used for retrieving the text selection.
-  RenderWidgetHostViewBase* GetFocusedViewForTextSelection();
-
   // Returns whether the widget needs an input grab to work properly.
   bool NeedsInputGrab();
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 914967a0e..a75f6aa0 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -28,7 +28,7 @@
 #include "components/viz/common/gl_helper.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/quads/compositor_frame_metadata.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
@@ -903,7 +903,7 @@
   base::test::ScopedFeatureList vsync_feature_list_;
   base::test::ScopedFeatureList feature_list_;
 
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraTest);
@@ -1490,7 +1490,7 @@
   parent2->SetBounds(gfx::Rect(20, 20, 200, 200));
   ASSERT_EQ(1U, sink_->message_count());
   const IPC::Message* msg = sink_->GetMessageAt(0);
-  ASSERT_EQ(ViewMsg_UpdateScreenRects::ID, msg->type());
+  ASSERT_EQ(static_cast<uint32_t>(ViewMsg_UpdateScreenRects::ID), msg->type());
   ViewMsg_UpdateScreenRects::Param params;
   ViewMsg_UpdateScreenRects::Read(msg, &params);
   EXPECT_EQ(gfx::Rect(24, 24, 100, 100), std::get<0>(params));
@@ -1504,7 +1504,7 @@
   parent1->SetBounds(gfx::Rect(10, 10, 300, 300));
   ASSERT_EQ(1U, sink_->message_count());
   msg = sink_->GetMessageAt(0);
-  ASSERT_EQ(ViewMsg_UpdateScreenRects::ID, msg->type());
+  ASSERT_EQ(static_cast<uint32_t>(ViewMsg_UpdateScreenRects::ID), msg->type());
   ViewMsg_UpdateScreenRects::Read(msg, &params);
   EXPECT_EQ(gfx::Rect(33, 33, 100, 100), std::get<0>(params));
   EXPECT_EQ(gfx::Rect(10, 10, 300, 300), std::get<1>(params));
@@ -2277,10 +2277,11 @@
   view_->SetSize(gfx::Size(100, 100));
   EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString());
   EXPECT_EQ(1u, sink_->message_count());
-  EXPECT_EQ(ViewMsg_Resize::ID, sink_->GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ViewMsg_Resize::ID),
+            sink_->GetMessageAt(0)->type());
   {
     const IPC::Message* msg = sink_->GetMessageAt(0);
-    EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewMsg_Resize::ID), msg->type());
     ViewMsg_Resize::Param params;
     ViewMsg_Resize::Read(msg, &params);
     EXPECT_EQ("100x100", std::get<0>(params).new_size.ToString());  // dip size
@@ -2299,7 +2300,8 @@
   // RenderWidgetHostViewAura::OnDisplayMetricsChanged() observer callback,
   // which sends a ViewMsg_Resize::ID message to the renderer.
   EXPECT_EQ(1u, sink_->message_count());
-  EXPECT_EQ(ViewMsg_Resize::ID, sink_->GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ViewMsg_Resize::ID),
+            sink_->GetMessageAt(0)->type());
   auto* view_delegate = static_cast<MockRenderWidgetHostDelegate*>(
       static_cast<RenderWidgetHostImpl*>(view_->GetRenderWidgetHost())
           ->delegate());
@@ -2311,7 +2313,8 @@
   aura_test_helper_->test_screen()->SetDeviceScaleFactor(1.0f);
   // Extra ScreenInfoChanged message for |parent_view_|.
   EXPECT_EQ(1u, sink_->message_count());
-  EXPECT_EQ(ViewMsg_Resize::ID, sink_->GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ViewMsg_Resize::ID),
+            sink_->GetMessageAt(0)->type());
   EXPECT_EQ(1.0f, view_delegate->get_last_device_scale_factor());
   EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString());
 }
@@ -2341,7 +2344,8 @@
   EXPECT_EQ(1u, sink_->message_count());
   {
     const IPC::Message* msg = sink_->GetMessageAt(0);
-    EXPECT_EQ(ViewMsg_SetLocalSurfaceIdForAutoResize::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SetLocalSurfaceIdForAutoResize::ID),
+              msg->type());
     ViewMsg_SetLocalSurfaceIdForAutoResize::Param params;
     ViewMsg_SetLocalSurfaceIdForAutoResize::Read(msg, &params);
     EXPECT_EQ(1u, std::get<0>(params));  // sequence_number
@@ -2356,7 +2360,8 @@
   EXPECT_EQ(2u, sink_->message_count());
   {
     const IPC::Message* msg = sink_->GetMessageAt(1);
-    EXPECT_EQ(ViewMsg_SetLocalSurfaceIdForAutoResize::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SetLocalSurfaceIdForAutoResize::ID),
+              msg->type());
     ViewMsg_SetLocalSurfaceIdForAutoResize::Param params;
     ViewMsg_SetLocalSurfaceIdForAutoResize::Read(msg, &params);
     EXPECT_EQ(1u, std::get<0>(params));  // sequence_number
@@ -2575,7 +2580,7 @@
 
   // Submit another frame. The resources for the previous frame belong to the
   // old RendererCompositorFrameSink and should not be returned.
-  view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
+  view_->SubmitCompositorFrame(parent_local_surface_id_allocator_.GenerateId(),
                                MakeDelegatedFrame(1.f, view_size, view_rect),
                                nullptr);
   EXPECT_EQ(0u, sink_->message_count());
@@ -2606,7 +2611,7 @@
   {
     // 0 is CreatingNew message.
     const IPC::Message* msg = sink_->GetMessageAt(0);
-    EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewMsg_Resize::ID), msg->type());
     ViewMsg_Resize::Param params;
     ViewMsg_Resize::Read(msg, &params);
     EXPECT_EQ(
@@ -2633,7 +2638,7 @@
   EXPECT_EQ(1u, sink_->message_count());
   {
     const IPC::Message* msg = sink_->GetMessageAt(0);
-    EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewMsg_Resize::ID), msg->type());
     ViewMsg_Resize::Param params;
     ViewMsg_Resize::Read(msg, &params);
     EXPECT_EQ(
@@ -2656,8 +2661,10 @@
   gfx::Size large_size(100, 100);
   gfx::Size small_size(40, 45);
   gfx::Size medium_size(40, 95);
-  viz::LocalSurfaceId small_id = local_surface_id_allocator_.GenerateId();
-  viz::LocalSurfaceId medium_id = local_surface_id_allocator_.GenerateId();
+  viz::LocalSurfaceId small_id =
+      parent_local_surface_id_allocator_.GenerateId();
+  viz::LocalSurfaceId medium_id =
+      parent_local_surface_id_allocator_.GenerateId();
 
   // Prevent the DelegatedFrameHost from skipping frames.
   view_->DisableResizeLock();
@@ -2710,9 +2717,9 @@
   gfx::Size size1(100, 100);
   gfx::Size size2(200, 200);
   gfx::Size size3(300, 300);
-  viz::LocalSurfaceId id1 = local_surface_id_allocator_.GenerateId();
-  viz::LocalSurfaceId id2 = local_surface_id_allocator_.GenerateId();
-  viz::LocalSurfaceId id3 = local_surface_id_allocator_.GenerateId();
+  viz::LocalSurfaceId id1 = parent_local_surface_id_allocator_.GenerateId();
+  viz::LocalSurfaceId id2 = parent_local_surface_id_allocator_.GenerateId();
+  viz::LocalSurfaceId id3 = parent_local_surface_id_allocator_.GenerateId();
 
   aura::Window* root_window = parent_view_->GetNativeView()->GetRootWindow();
   view_->InitAsChild(nullptr);
@@ -2739,7 +2746,7 @@
   EXPECT_EQ(1u, sink_->message_count());
   {
     const IPC::Message* msg = sink_->GetMessageAt(0);
-    EXPECT_EQ(ViewMsg_Resize::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewMsg_Resize::ID), msg->type());
     ViewMsg_Resize::Param params;
     ViewMsg_Resize::Read(msg, &params);
     EXPECT_EQ(size2.ToString(), std::get<0>(params).new_size.ToString());
@@ -2816,7 +2823,7 @@
   gfx::Rect view_rect(100, 100);
   gfx::Size frame_size = view_rect.size();
   viz::LocalSurfaceId local_surface_id =
-      local_surface_id_allocator_.GenerateId();
+      parent_local_surface_id_allocator_.GenerateId();
 
   view_->InitAsChild(nullptr);
   aura::client::ParentWindowWithContext(
@@ -2871,7 +2878,7 @@
 
   // Unlock the compositor. This frame should damage everything.
   frame_size = view_rect.size();
-  local_surface_id = local_surface_id_allocator_.GenerateId();
+  local_surface_id = parent_local_surface_id_allocator_.GenerateId();
 
   gfx::Rect new_damage_rect(5, 6, 10, 10);
   view_->SubmitCompositorFrame(
@@ -2907,7 +2914,7 @@
   // We're never expecting empty frames, resize to something non-empty.
   view_rect = gfx::Rect(100, 100);
   frame_size = view_rect.size();
-  local_surface_id = local_surface_id_allocator_.GenerateId();
+  local_surface_id = parent_local_surface_id_allocator_.GenerateId();
   view_->SetSize(view_rect.size());
   EXPECT_TRUE(view_->resize_locked());
   EXPECT_TRUE(view_->compositor_locked());
@@ -2930,7 +2937,7 @@
   gfx::Rect view_rect(100, 100);
   gfx::Size frame_size = view_rect.size();
   viz::LocalSurfaceId local_surface_id =
-      local_surface_id_allocator_.GenerateId();
+      parent_local_surface_id_allocator_.GenerateId();
 
   view_->InitAsChild(nullptr);
   aura::client::ParentWindowWithContext(
@@ -2982,7 +2989,7 @@
 
   // A frame arrives of the new size, which will be accepted.
   frame_size = view_rect.size();
-  local_surface_id = local_surface_id_allocator_.GenerateId();
+  local_surface_id = parent_local_surface_id_allocator_.GenerateId();
   view_->SubmitCompositorFrame(
       local_surface_id,
       MakeDelegatedFrame(1.f, frame_size, gfx::Rect(frame_size)), nullptr);
@@ -3070,7 +3077,7 @@
   view_->CreateNewRendererCompositorFrameSink();
 
   // Submit a frame from the new RendererCompositorFrameSink.
-  view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
+  view_->SubmitCompositorFrame(parent_local_surface_id_allocator_.GenerateId(),
                                MakeDelegatedFrame(1.f, frame_size, view_rect),
                                nullptr);
   EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
@@ -3082,7 +3089,7 @@
 
   // Submit a frame from the new RendererCompositorFrameSink.
   view_->SubmitCompositorFrame(
-      local_surface_id_allocator_.GenerateId(),
+      parent_local_surface_id_allocator_.GenerateId(),
       MakeDelegatedFrame(1.f, gfx::Size(), gfx::Rect()), nullptr);
   EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
   EXPECT_EQ(view_rect, DamageRectForView(view_));
@@ -3092,7 +3099,7 @@
   view_->CreateNewRendererCompositorFrameSink();
 
   // Swap another frame, with a different surface id.
-  view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
+  view_->SubmitCompositorFrame(parent_local_surface_id_allocator_.GenerateId(),
                                MakeDelegatedFrame(1.f, frame_size, view_rect),
                                nullptr);
   EXPECT_EQ(kFrameIndexStart + 1, FrameIndexForView(view_));
@@ -3211,7 +3218,7 @@
   view_->CreateNewRendererCompositorFrameSink();
 
   // Submit a frame from the new RendererCompositorFrameSink.
-  view_->SubmitCompositorFrame(local_surface_id_allocator_.GenerateId(),
+  view_->SubmitCompositorFrame(parent_local_surface_id_allocator_.GenerateId(),
                                MakeDelegatedFrame(1.f, frame_size, view_rect),
                                nullptr);
   view_->RunOnCompositingDidCommit();
@@ -3454,7 +3461,7 @@
   views[1]->Hide();
   EXPECT_TRUE(views[1]->HasPrimarySurface());
   gfx::Size size2(200, 200);
-  viz::LocalSurfaceId id2 = local_surface_id_allocator_.GenerateId();
+  viz::LocalSurfaceId id2 = parent_local_surface_id_allocator_.GenerateId();
   views[1]->SetSize(size2);
   EXPECT_FALSE(views[1]->HasPrimarySurface());
   // Show it, it should block until we give it a frame.
@@ -3508,7 +3515,8 @@
   for (size_t i = 0; i < renderer_count; ++i) {
     views[i]->Show();
     views[i]->SubmitCompositorFrame(
-        i ? local_surface_id_allocator_.GenerateId() : kArbitraryLocalSurfaceId,
+        i ? parent_local_surface_id_allocator_.GenerateId()
+          : kArbitraryLocalSurfaceId,
         MakeDelegatedFrame(1.f, frame_size, view_rect), nullptr);
     EXPECT_TRUE(views[i]->HasPrimarySurface());
   }
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
index ded662d..595d68d6 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -821,11 +821,6 @@
 }
 
 #if defined(OS_MACOSX)
-ui::AcceleratedWidgetMac*
-RenderWidgetHostViewChildFrame::GetAcceleratedWidgetMac() const {
-  return nullptr;
-}
-
 void RenderWidgetHostViewChildFrame::SetActive(bool active) {}
 
 void RenderWidgetHostViewChildFrame::ShowDefinitionForSelection() {
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h
index 743ca2b..5fc184a 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.h
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -166,7 +166,6 @@
 
 #if defined(OS_MACOSX)
   // RenderWidgetHostView implementation.
-  ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const override;
   void SetActive(bool active) override;
   void ShowDefinitionForSelection() override;
   bool SupportsSpeech() const override;
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 32943d4..edb0706 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -23,7 +23,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "components/viz/common/surfaces/local_surface_id.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/common/surfaces/surface_id.h"
 #include "content/browser/renderer_host/browser_compositor_view_mac.h"
 #include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
@@ -326,7 +326,6 @@
   void BeginFrameSubscription(
       std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override;
   void EndFrameSubscription() override;
-  ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const override;
   void FocusedNodeChanged(bool is_editable_node,
                           const gfx::Rect& node_bounds_in_screen) override;
   void DidCreateNewRendererCompositorFrameSink(
@@ -630,7 +629,7 @@
   float last_device_scale_factor_ = 0.f;
 
   viz::LocalSurfaceId local_surface_id_;
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
 
   // Factory used to safely scope delayed calls to ShutdownHost().
   base::WeakPtrFactory<RenderWidgetHostViewMac> weak_factory_;
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 d080dd0..e00956e 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -457,7 +457,7 @@
 
   viz::FrameSinkId frame_sink_id =
       render_widget_host_->AllocateFrameSinkId(is_guest_view_hack_);
-  local_surface_id_ = local_surface_id_allocator_.GenerateId();
+  local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
   browser_compositor_.reset(
       new BrowserCompositorMac(this, this, render_widget_host_->is_hidden(),
                                [cocoa_view_ window], frame_sink_id));
@@ -803,7 +803,7 @@
     return;
 
   if (rect.size() != last_size_) {
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
     last_size_ = rect.size();
   }
 
@@ -1107,7 +1107,7 @@
   if (!render_widget_host_ || !render_widget_host_->auto_resize_enabled())
     return;
 
-  local_surface_id_ = local_surface_id_allocator_.GenerateId();
+  local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
   render_widget_host_->DidAllocateLocalSurfaceIdForAutoResize(
       render_widget_host_->last_auto_resize_request_number());
   browser_compositor_->WasResized();
@@ -1210,11 +1210,6 @@
   browser_compositor_->GetDelegatedFrameHost()->EndFrameSubscription();
 }
 
-ui::AcceleratedWidgetMac* RenderWidgetHostViewMac::GetAcceleratedWidgetMac()
-    const {
-  return browser_compositor_->GetAcceleratedWidgetMac();
-}
-
 void RenderWidgetHostViewMac::ForwardMouseEvent(const WebMouseEvent& event) {
   if (render_widget_host_)
     render_widget_host_->ForwardMouseEvent(event);
@@ -1414,11 +1409,7 @@
 
 bool RenderWidgetHostViewMac::HasAcceleratedSurface(
       const gfx::Size& desired_size) {
-  ui::AcceleratedWidgetMac* accelerated_widget_mac =
-      browser_compositor_->GetAcceleratedWidgetMac();
-  if (accelerated_widget_mac)
-    return accelerated_widget_mac->HasFrameOfSize(desired_size);
-  return false;
+  return browser_compositor_->HasFrameOfSize(desired_size);
 }
 
 void RenderWidgetHostViewMac::FocusedNodeChanged(
@@ -1731,12 +1722,8 @@
 
 gfx::AcceleratedWidget
 RenderWidgetHostViewMac::AccessibilityGetAcceleratedWidget() {
-  if (browser_compositor_) {
-    ui::AcceleratedWidgetMac* accelerated_widget_mac =
-        browser_compositor_->GetAcceleratedWidgetMac();
-    if (accelerated_widget_mac)
-      return accelerated_widget_mac->accelerated_widget();
-  }
+  if (browser_compositor_)
+    return browser_compositor_->GetAcceleratedWidget();
   return gfx::kNullAcceleratedWidget;
 }
 
@@ -1787,7 +1774,7 @@
 
   if (changed_metrics & DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR) {
     if (display.device_scale_factor() != last_device_scale_factor_) {
-      local_surface_id_ = local_surface_id_allocator_.GenerateId();
+      local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
       last_device_scale_factor_ = display.device_scale_factor();
     }
     RenderWidgetHostImpl* host =
@@ -1856,11 +1843,12 @@
 
   // Debug key to check if the current input context still holds onto the view.
   NSTextInputContext* currentContext = [NSTextInputContext currentInputContext];
-  base::debug::ScopedCrashKey textInputContextCrashKey(
-      "text-input-context-client",
-      currentContext && [currentContext client] == self
-          ? "text input still held on"
-          : "text input no longer held on");
+  auto* crashKey = base::debug::AllocateCrashKeyString(
+      "text-input-context-client", base::debug::CrashKeySize::Size32);
+  base::debug::ScopedCrashKeyString textInputContextCrashKey(
+      crashKey, currentContext && [currentContext client] == self
+                    ? "text input still held on"
+                    : "text input no longer held on");
 
   [super dealloc];
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index 955d697..42d07f9d 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -2226,7 +2226,8 @@
 
 // Ensure RenderWidgetHostViewMac claims hotkeys when AppKit spams the UI with
 // -performKeyEquivalent:, but only when the window is key.
-TEST_F(RenderWidgetHostViewMacTest, ForwardKeyEquivalentsOnlyIfKey) {
+// Flaky: https://crbug.com/792907
+TEST_F(RenderWidgetHostViewMacTest, DISABLED_ForwardKeyEquivalentsOnlyIfKey) {
   MockRenderWidgetHostDelegate delegate;
   TestBrowserContext browser_context;
 
diff --git a/content/browser/renderer_interface_binders.cc b/content/browser/renderer_interface_binders.cc
index 082e5c9..bb4e0169 100644
--- a/content/browser/renderer_interface_binders.cc
+++ b/content/browser/renderer_interface_binders.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "content/browser/background_fetch/background_fetch_service_impl.h"
 #include "content/browser/dedicated_worker/dedicated_worker_host.h"
+#include "content/browser/locks/lock_manager.h"
 #include "content/browser/notifications/platform_notification_context_impl.h"
 #include "content/browser/payments/payment_manager.h"
 #include "content/browser/permissions/permission_service_context.h"
@@ -123,6 +124,13 @@
             ->permission_service_context()
             .CreateService(std::move(request));
       }));
+  parameterized_binder_registry_.AddInterface(base::BindRepeating(
+      [](blink::mojom::LockManagerRequest request, RenderProcessHost* host,
+         const url::Origin& origin) {
+        static_cast<StoragePartitionImpl*>(host->GetStoragePartition())
+            ->GetLockManager()
+            ->CreateService(std::move(request));
+      }));
   parameterized_binder_registry_.AddInterface(
       base::Bind(&CreateDedicatedWorkerHostFactory));
   parameterized_binder_registry_.AddInterface(
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index b56626c..45c29c53 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -1496,6 +1496,8 @@
 
 void ServiceWorkerVersion::StartWorkerInternal() {
   DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status());
+  DCHECK(pending_requests_.IsEmpty());
+  DCHECK(request_timeouts_.empty());
   DCHECK(start_worker_first_purpose_);
 
   if (!ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(site_for_uma_)) {
@@ -1932,6 +1934,7 @@
     iter.Advance();
   }
   pending_requests_.Clear();
+  request_timeouts_.clear();
   external_request_uuid_to_request_id_.clear();
   event_dispatcher_.reset();
   controller_ptr_.reset();
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 2e267780..9343ec5 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -450,6 +450,7 @@
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeout);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeoutKill);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestCustomizedTimeout);
+  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RestartWorker);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, MixedRequestTimeouts);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, EarlyResponse);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, CancelRequest);
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index 0e61c8a..5d9fd50 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -917,6 +917,37 @@
   version_->RemoveListener(&listener);
 }
 
+TEST_F(ServiceWorkerVersionTest, RestartWorker) {
+  StartWorker(version_.get(),
+              ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
+  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+
+  ServiceWorkerStatusCode event_status = SERVICE_WORKER_ERROR_MAX_VALUE;
+  version_->StartRequest(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
+                         CreateReceiverOnCurrentThread(&event_status));
+
+  // Restart the worker. The inflight event should have been failed.
+  bool has_stopped = false;
+  version_->StopWorker(base::BindOnce(&VerifyCalled, &has_stopped));
+  EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
+  ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_MAX_VALUE;
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&start_status));
+  base::RunLoop().RunUntilIdle();
+
+  // All inflight events should have been aborted.
+  EXPECT_EQ(event_status, SERVICE_WORKER_ERROR_FAILED);
+  // The worker should have been stopped.
+  EXPECT_TRUE(has_stopped);
+  // The worker should have been successfully re-started after stopped.
+  EXPECT_EQ(SERVICE_WORKER_OK, start_status);
+  EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+
+  // SetAllRequestExpirations() after restarting should not crash since all
+  // events should have been removed at this point: crbug.com/791451.
+  version_->SetAllRequestExpirations(base::TimeTicks());
+}
+
 class MessageReceiverControlEvents : public MessageReceiver {
  public:
   MessageReceiverControlEvents() : MessageReceiver() {}
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 223ab4b..5c3d589 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -12651,4 +12651,85 @@
   EXPECT_EQ(2u, Shell::windows().size());
 }
 
+// Check that a subframe that requires a dedicated process will attempt to
+// reuse an existing process for the same site, even across BrowsingInstances.
+// This helps consolidate processes when running under --site-per-process.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+                       SubframeReusesExistingProcess) {
+  GURL foo_url(
+      embedded_test_server()->GetURL("foo.com", "/page_with_iframe.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
+  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+  FrameTreeNode* child = root->child_at(0);
+
+  // Open an unrelated tab in a separate BrowsingInstance, and navigate it to
+  // to bar.com.  This SiteInstance should have a default process reuse
+  // policy - only subframes attempt process reuse.
+  GURL bar_url(
+      embedded_test_server()->GetURL("bar.com", "/page_with_iframe.html"));
+  Shell* second_shell = CreateBrowser();
+  EXPECT_TRUE(NavigateToURL(second_shell, bar_url));
+  scoped_refptr<SiteInstanceImpl> second_shell_instance =
+      static_cast<SiteInstanceImpl*>(
+          second_shell->web_contents()->GetMainFrame()->GetSiteInstance());
+  EXPECT_FALSE(second_shell_instance->IsRelatedSiteInstance(
+      root->current_frame_host()->GetSiteInstance()));
+  RenderProcessHost* bar_process = second_shell_instance->GetProcess();
+  EXPECT_EQ(SiteInstanceImpl::ProcessReusePolicy::DEFAULT,
+            second_shell_instance->process_reuse_policy());
+
+  // Now navigate the first tab's subframe to bar.com.  Confirm that it reuses
+  // |bar_process|.
+  NavigateIframeToURL(web_contents(), "test_iframe", bar_url);
+  EXPECT_EQ(bar_url, child->current_url());
+  EXPECT_EQ(bar_process, child->current_frame_host()->GetProcess());
+  EXPECT_EQ(
+      SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE,
+      child->current_frame_host()->GetSiteInstance()->process_reuse_policy());
+
+  EXPECT_TRUE(child->current_frame_host()->IsCrossProcessSubframe());
+  EXPECT_EQ(
+      bar_url.host(),
+      child->current_frame_host()->GetSiteInstance()->GetSiteURL().host());
+
+  // The subframe's SiteInstance should still be different from second_shell's
+  // SiteInstance, and they should be in separate BrowsingInstances.
+  EXPECT_NE(second_shell_instance,
+            child->current_frame_host()->GetSiteInstance());
+  EXPECT_FALSE(second_shell_instance->IsRelatedSiteInstance(
+      child->current_frame_host()->GetSiteInstance()));
+
+  // Navigate the second tab to a foo.com URL with a same-site subframe.  This
+  // leaves only the first tab's subframe in the bar.com process.
+  EXPECT_TRUE(NavigateToURL(second_shell, foo_url));
+  EXPECT_NE(bar_process,
+            second_shell->web_contents()->GetMainFrame()->GetProcess());
+
+  // Navigate the second tab's subframe to bar.com, and check that this
+  // new subframe reuses the process of the subframe in the first tab, even
+  // though the two are in separate BrowsingInstances.
+  NavigateIframeToURL(second_shell->web_contents(), "test_iframe", bar_url);
+  FrameTreeNode* second_subframe =
+      static_cast<WebContentsImpl*>(second_shell->web_contents())
+          ->GetFrameTree()
+          ->root()
+          ->child_at(0);
+  EXPECT_EQ(bar_process, second_subframe->current_frame_host()->GetProcess());
+  EXPECT_NE(child->current_frame_host()->GetSiteInstance(),
+            second_subframe->current_frame_host()->GetSiteInstance());
+
+  // Open a third, unrelated tab, navigate it to bar.com, and check that
+  // its main frame doesn't share a process with the existing bar.com
+  // subframes.
+  Shell* third_shell = CreateBrowser();
+  EXPECT_TRUE(NavigateToURL(third_shell, bar_url));
+  SiteInstanceImpl* third_shell_instance = static_cast<SiteInstanceImpl*>(
+      third_shell->web_contents()->GetMainFrame()->GetSiteInstance());
+  EXPECT_NE(third_shell_instance,
+            second_subframe->current_frame_host()->GetSiteInstance());
+  EXPECT_NE(third_shell_instance,
+            child->current_frame_host()->GetSiteInstance());
+  EXPECT_NE(third_shell_instance->GetProcess(), bar_process);
+}
+
 }  // namespace content
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 65e19e4..4c1dc5b 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -476,6 +476,9 @@
       base::WrapUnique(new StoragePartitionImpl(
           context, partition_path, context->GetSpecialStoragePolicy()));
 
+  partition->is_in_memory_ = in_memory;
+  partition->relative_partition_path_ = relative_partition_path;
+
   // All of the clients have to be created and registered with the
   // QuotaManager prior to the QuotaManger being used. We do them
   // all together here prior to handing out a reference to anything
@@ -503,6 +506,8 @@
       in_memory ? base::FilePath() : context->GetPath(),
       relative_partition_path, context->GetSpecialStoragePolicy());
 
+  partition->lock_manager_ = new LockManager();
+
   base::FilePath path = in_memory ? base::FilePath() : partition_path;
   partition->indexed_db_context_ = new IndexedDBContextImpl(
       path, context->GetSpecialStoragePolicy(), quota_manager_proxy);
@@ -545,10 +550,6 @@
   scoped_refptr<ChromeBlobStorageContext> blob_context =
       ChromeBlobStorageContext::GetFor(context);
 
-  partition->network_context_ =
-      GetContentClient()->browser()->CreateNetworkContext(
-          context, in_memory, relative_partition_path);
-
   if (base::FeatureList::IsEnabled(features::kNetworkService)) {
     BlobURLLoaderFactory::BlobContextGetter blob_getter =
         base::BindOnce(&BlobStorageContextGetter, blob_context);
@@ -589,8 +590,9 @@
 
 mojom::NetworkContext* StoragePartitionImpl::GetNetworkContext() {
   // Create the NetworkContext as needed, when the network service is disabled.
-  if (!network_context_) {
-    DCHECK(!base::FeatureList::IsEnabled(features::kNetworkService));
+  if (!base::FeatureList::IsEnabled(features::kNetworkService)) {
+    if (network_context_)
+      return network_context_.get();
     DCHECK(!network_context_owner_);
     network_context_owner_ = std::make_unique<NetworkContextOwner>();
     BrowserThread::PostTask(
@@ -598,6 +600,12 @@
         base::BindOnce(&NetworkContextOwner::Initialize,
                        base::Unretained(network_context_owner_.get()),
                        MakeRequest(&network_context_), url_request_context_));
+    return network_context_.get();
+  }
+
+  if (!network_context_.is_bound() || network_context_.encountered_error()) {
+    network_context_ = GetContentClient()->browser()->CreateNetworkContext(
+        browser_context_, is_in_memory_, relative_partition_path_);
   }
   return network_context_.get();
 }
@@ -632,6 +640,10 @@
   return dom_storage_context_.get();
 }
 
+LockManager* StoragePartitionImpl::GetLockManager() {
+  return lock_manager_.get();
+}
+
 IndexedDBContextImpl* StoragePartitionImpl::GetIndexedDBContext() {
   return indexed_db_context_.get();
 }
@@ -1017,6 +1029,10 @@
   bluetooth_allowed_devices_map_->Clear();
 }
 
+void StoragePartitionImpl::FlushNetworkInterfaceForTesting() {
+  network_context_.FlushForTesting();
+}
+
 BrowserContext* StoragePartitionImpl::browser_context() const {
   return browser_context_;
 }
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 9357f52..7ee0d9d 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -24,6 +24,7 @@
 #include "content/browser/cache_storage/cache_storage_context_impl.h"
 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
 #include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/browser/locks/lock_manager.h"
 #include "content/browser/notifications/platform_notification_context_impl.h"
 #include "content/browser/payments/payment_app_context_impl.h"
 #include "content/browser/push_messaging/push_messaging_context.h"
@@ -82,6 +83,7 @@
   storage::FileSystemContext* GetFileSystemContext() override;
   storage::DatabaseTracker* GetDatabaseTracker() override;
   DOMStorageContextWrapper* GetDOMStorageContext() override;
+  LockManager* GetLockManager();  // override; TODO: Add to interface
   IndexedDBContextImpl* GetIndexedDBContext() override;
   CacheStorageContextImpl* GetCacheStorageContext() override;
   ServiceWorkerContextWrapper* GetServiceWorkerContext() override;
@@ -117,6 +119,8 @@
       base::OnceClosure callback) override;
   void Flush() override;
   void ClearBluetoothAllowedDevicesMapForTesting() override;
+  void FlushNetworkInterfaceForTesting() override;
+
   BackgroundFetchContext* GetBackgroundFetchContext();
   BackgroundSyncContext* GetBackgroundSyncContext();
   PaymentAppContextImpl* GetPaymentAppContext();
@@ -239,6 +243,10 @@
   // storage configuration info.
   void GetQuotaSettings(storage::OptionalQuotaSettingsCallback callback);
 
+  // |is_in_memory_| and |relative_partition_path_| are cached from
+  // |StoragePartitionImpl::Create()| in order to re-create |NetworkContext|.
+  bool is_in_memory_;
+  base::FilePath relative_partition_path_;
   base::FilePath partition_path_;
   scoped_refptr<net::URLRequestContextGetter> url_request_context_;
   scoped_refptr<net::URLRequestContextGetter> media_url_request_context_;
@@ -248,6 +256,7 @@
   scoped_refptr<storage::FileSystemContext> filesystem_context_;
   scoped_refptr<storage::DatabaseTracker> database_tracker_;
   scoped_refptr<DOMStorageContextWrapper> dom_storage_context_;
+  scoped_refptr<LockManager> lock_manager_;
   scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
   scoped_refptr<CacheStorageContextImpl> cache_storage_context_;
   scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc
index 578fb413..bb1b48bc 100644
--- a/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -323,6 +323,9 @@
     return;
   }
 
+  if (!config_)
+    return;
+
   for (const auto& rule : config_->rules()) {
     if (rule->ShouldTriggerNamedEvent(histogram_name))
       OnRuleTriggered(rule.get(), StartedFinalizingCallback());
diff --git a/content/browser/tracing/memory_tracing_browsertest.cc b/content/browser/tracing/memory_tracing_browsertest.cc
index 3612d03..8f1736ab 100644
--- a/content/browser/tracing/memory_tracing_browsertest.cc
+++ b/content/browser/tracing/memory_tracing_browsertest.cc
@@ -185,10 +185,17 @@
   }
 };
 
+// https://crbug.com/788788
+#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+#define MAYBE_BrowserInitiatedSingleDump DISABLED_BrowserInitiatedSingleDump
+#else
+#define MAYBE_BrowserInitiatedSingleDump BrowserInitiatedSingleDump
+#endif  // defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
+
 // Checks that a memory dump initiated from a the main browser thread ends up in
 // a single dump even in single process mode.
 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest,
-                       BrowserInitiatedSingleDump) {
+                       MAYBE_BrowserInitiatedSingleDump) {
   Navigate(shell());
 
   EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true));
diff --git a/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc b/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc
index 1b0abc10c..5728d2f 100644
--- a/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc
+++ b/content/browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc
@@ -106,6 +106,12 @@
 // HTML and Javascript is bypassed since it would trigger a file picker dialog.
 // Instead, the dialog callback FileSelected() is invoked directly. In fact,
 // there's never a webrtc-internals page opened at all since that's not needed.
+// Note: Both stopping the streams (at hangup()) and disabling the recordings
+// are asynchronous without response when finished. This means that closing the
+// files is asynchronous and being able to delete the files in the test is
+// therefore timing dependent and flaky prone. If it becomes flaky, it's
+// probably good enough to change the test to retry deleting after a short
+// sleep.
 IN_PROC_BROWSER_TEST_F(WebRtcAudioDebugRecordingsBrowserTest,
                        MAYBE_CallWithAudioDebugRecordings) {
   if (!HasAudioOutputDevices()) {
@@ -138,27 +144,16 @@
 
   WebRTCInternals::GetInstance()->DisableAudioDebugRecordings();
 
-  // Verify that the expected AEC dump file exists and contains some data.
-  base::ProcessId render_process_id = base::kNullProcessId;
-  EXPECT_TRUE(GetRenderProcessHostId(&render_process_id));
-  base::FilePath file_path =
-      GetExpectedAecDumpFileName(base_file_path, render_process_id);
-  EXPECT_TRUE(base::PathExists(file_path));
-  int64_t file_size = 0;
-  EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
-  EXPECT_GT(file_size, 0);
-  EXPECT_TRUE(base::DeleteFile(file_path, false));
-
   // Verify that the expected input audio file exists and contains some data.
   std::vector<base::FilePath> input_files =
       GetRecordingFileNames(FILE_PATH_LITERAL("input"), base_file_path);
   EXPECT_EQ(input_files.size(), 1u);
-  file_size = 0;
+  int64_t file_size = 0;
   EXPECT_TRUE(base::GetFileSize(input_files[0], &file_size));
   EXPECT_GT(file_size, kWaveHeaderSizeBytes);
   EXPECT_TRUE(base::DeleteFile(input_files[0], false));
 
-  // Verify that the expected output audio files exists and contains some data.
+  // Verify that the expected output audio files exist and contain some data.
   // Two files are expected, one for each peer in the call.
   std::vector<base::FilePath> output_files =
       GetRecordingFileNames(FILE_PATH_LITERAL("output"), base_file_path);
@@ -170,6 +165,17 @@
     EXPECT_TRUE(base::DeleteFile(file_path, false));
   }
 
+  // Verify that the expected AEC dump file exists and contains some data.
+  base::ProcessId render_process_id = base::kNullProcessId;
+  EXPECT_TRUE(GetRenderProcessHostId(&render_process_id));
+  base::FilePath file_path =
+      GetExpectedAecDumpFileName(base_file_path, render_process_id);
+  EXPECT_TRUE(base::PathExists(file_path));
+  file_size = 0;
+  EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
+  EXPECT_GT(file_size, 0);
+  EXPECT_TRUE(base::DeleteFile(file_path, false));
+
   // Verify that no other files exist and remove temp dir.
   EXPECT_TRUE(base::IsDirectoryEmpty(temp_dir_path));
   EXPECT_TRUE(base::DeleteFile(temp_dir_path, false));
@@ -286,26 +292,9 @@
 
   WebRTCInternals::GetInstance()->DisableAudioDebugRecordings();
 
-  RenderProcessHost::iterator it =
-      content::RenderProcessHost::AllHostsIterator();
-  base::FilePath file_path;
   int64_t file_size = 0;
 
-  for (; !it.IsAtEnd(); it.Advance()) {
-    base::ProcessId render_process_id =
-        base::GetProcId(it.GetCurrentValue()->GetHandle());
-    EXPECT_NE(base::kNullProcessId, render_process_id);
-
-    // Verify that the expected AEC dump file exists and contains some data.
-    file_path = GetExpectedAecDumpFileName(base_file_path, render_process_id);
-    EXPECT_TRUE(base::PathExists(file_path));
-    file_size = 0;
-    EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
-    EXPECT_GT(file_size, 0);
-    EXPECT_TRUE(base::DeleteFile(file_path, false));
-  }
-
-  // Verify that the expected input audio files exist and contains some data.
+  // Verify that the expected input audio files exist and contain some data.
   std::vector<base::FilePath> input_files =
       GetRecordingFileNames(FILE_PATH_LITERAL("input"), base_file_path);
   EXPECT_EQ(input_files.size(), 2u);
@@ -316,7 +305,7 @@
     EXPECT_TRUE(base::DeleteFile(file_path, false));
   }
 
-  // Verify that the expected output audio files exists and contains some data.
+  // Verify that the expected output audio files exist and contain some data.
   // Four files are expected, one for each peer in each call. (Two calls * two
   // peers.)
   std::vector<base::FilePath> output_files =
@@ -329,6 +318,23 @@
     EXPECT_TRUE(base::DeleteFile(file_path, false));
   }
 
+  // Verify that the expected AEC dump files exist and contain some data.
+  RenderProcessHost::iterator it =
+      content::RenderProcessHost::AllHostsIterator();
+  base::FilePath file_path;
+  for (; !it.IsAtEnd(); it.Advance()) {
+    base::ProcessId render_process_id =
+        base::GetProcId(it.GetCurrentValue()->GetHandle());
+    EXPECT_NE(base::kNullProcessId, render_process_id);
+
+    file_path = GetExpectedAecDumpFileName(base_file_path, render_process_id);
+    EXPECT_TRUE(base::PathExists(file_path));
+    file_size = 0;
+    EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
+    EXPECT_GT(file_size, 0);
+    EXPECT_TRUE(base::DeleteFile(file_path, false));
+  }
+
   // Verify that no other files exist and remove temp dir.
   EXPECT_TRUE(base::IsDirectoryEmpty(temp_dir_path));
   EXPECT_TRUE(base::DeleteFile(temp_dir_path, false));
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
index f23b7e2..31937fc 100644
--- a/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
+++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
@@ -57,8 +57,6 @@
   FONT_PROXY_ERROR_MAX_VALUE
 };
 
-const char kFontKeyName[] = "font_key_name";
-
 void LogLoadFamilyResult(DirectWriteLoadFamilyResult result) {
   UMA_HISTOGRAM_ENUMERATION("DirectWrite.Fonts.Proxy.LoadFamilyResult", result,
                             LOAD_FAMILY_MAX_VALUE);
@@ -488,8 +486,10 @@
 
   SCOPED_UMA_HISTOGRAM_TIMER("DirectWrite.Fonts.Proxy.LoadFamilyTime");
 
-  base::debug::ScopedCrashKey crash_key(kFontKeyName,
-                                        base::WideToUTF8(family_name_));
+  auto* font_key_name = base::debug::AllocateCrashKeyString(
+      "font_key_name", base::debug::CrashKeySize::Size32);
+  base::debug::ScopedCrashKeyString crash_key(font_key_name,
+                                              base::WideToUTF8(family_name_));
 
   mswr::ComPtr<IDWriteFontCollection> collection;
   if (!proxy_collection_->LoadFamily(family_index_, &collection)) {
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc b/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc
index 002b683..aa2ffc6 100644
--- a/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc
+++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_win_unittest.cc
@@ -84,7 +84,7 @@
 
   EXPECT_EQ(3u, family_count);
   ASSERT_EQ(1u, fake_collection_->MessageCount());
-  EXPECT_EQ(DWriteFontProxyMsg_GetFamilyCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(DWriteFontProxyMsg_GetFamilyCount::ID),
             fake_collection_->GetMessage(0)->type());
 
   // Calling again should not cause another message to be sent.
@@ -104,9 +104,9 @@
   EXPECT_EQ(1u, index);
   EXPECT_TRUE(exists);
   ASSERT_EQ(2u, fake_collection_->MessageCount());
-  EXPECT_EQ(DWriteFontProxyMsg_FindFamily::ID,
+  EXPECT_EQ(static_cast<uint32_t>(DWriteFontProxyMsg_FindFamily::ID),
             fake_collection_->GetMessage(0)->type());
-  EXPECT_EQ(DWriteFontProxyMsg_GetFamilyCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(DWriteFontProxyMsg_GetFamilyCount::ID),
             fake_collection_->GetMessage(1)->type());
 }
 
@@ -121,7 +121,7 @@
   EXPECT_EQ(UINT32_MAX, index);
   EXPECT_FALSE(exists);
   ASSERT_EQ(1u, fake_collection_->MessageCount());
-  EXPECT_EQ(DWriteFontProxyMsg_FindFamily::ID,
+  EXPECT_EQ(static_cast<uint32_t>(DWriteFontProxyMsg_FindFamily::ID),
             fake_collection_->GetMessage(0)->type());
 }
 
@@ -202,7 +202,7 @@
   hr = family->GetFamilyNames(&names);
   EXPECT_EQ(S_OK, hr);
   EXPECT_EQ(3u, fake_collection_->MessageCount());
-  EXPECT_EQ(DWriteFontProxyMsg_GetFamilyNames::ID,
+  EXPECT_EQ(static_cast<uint32_t>(DWriteFontProxyMsg_GetFamilyNames::ID),
             fake_collection_->GetMessage(2)->type());
 
   EXPECT_EQ(2u, names->GetCount());
@@ -288,7 +288,7 @@
   UINT32 font_count = family->GetFontCount();
   EXPECT_LT(0u, font_count);
   EXPECT_EQ(3u, fake_collection_->MessageCount());
-  EXPECT_EQ(DWriteFontProxyMsg_GetFontFiles::ID,
+  EXPECT_EQ(static_cast<uint32_t>(DWriteFontProxyMsg_GetFontFiles::ID),
             fake_collection_->GetMessage(2)->type());
   mswr::ComPtr<IDWriteFont> font;
   hr = family->GetFirstMatchingFont(DWRITE_FONT_WEIGHT_NORMAL,
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index b677488e..e6f70f0 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -499,27 +499,6 @@
     sources -= [ "cursors/webcursor_aurawin.cc" ]
   }
 
-  if (!use_seccomp_bpf) {
-    if (is_linux && current_cpu != "s390x" && current_cpu != "ppc64") {
-      sources -= [
-        "sandbox_linux/bpf_base_policy_linux.cc",
-        "sandbox_linux/bpf_base_policy_linux.h",
-        "sandbox_linux/bpf_cros_amd_gpu_policy_linux.cc",
-        "sandbox_linux/bpf_cros_amd_gpu_policy_linux.h",
-        "sandbox_linux/bpf_cros_arm_gpu_policy_linux.cc",
-        "sandbox_linux/bpf_cros_arm_gpu_policy_linux.h",
-        "sandbox_linux/bpf_gpu_policy_linux.cc",
-        "sandbox_linux/bpf_gpu_policy_linux.h",
-        "sandbox_linux/bpf_ppapi_policy_linux.cc",
-        "sandbox_linux/bpf_ppapi_policy_linux.h",
-        "sandbox_linux/bpf_renderer_policy_linux.cc",
-        "sandbox_linux/bpf_renderer_policy_linux.h",
-        "sandbox_linux/bpf_utility_policy_linux.cc",
-        "sandbox_linux/bpf_utility_policy_linux.h",
-      ]
-    }
-  }
-
   if (is_mac) {
     deps += [ "//media/gpu" ]
   }
diff --git a/content/common/appcache.mojom b/content/common/appcache.mojom
index ee9366b..a722156 100644
--- a/content/common/appcache.mojom
+++ b/content/common/appcache.mojom
@@ -48,3 +48,57 @@
   int32 status;
   bool is_cross_origin;
 };
+
+
+// AppCache messages sent from the child process to the browser.
+interface AppCacheBackend {
+  // Informs the browser of a new appcache host.
+  RegisterHost(int32 host_id);
+
+  // Informs the browser of an appcache host being destroyed.
+  UnregisterHost(int32 host_id);
+
+  // Informs the browser of which host caused another to be created.
+  // This can influence which appcache should be utilized for the main
+  // resource load into the newly created host, so it should be sent
+  // prior to the main resource request being initiated.
+  SetSpawningHostId(int32 host_id, int32 spawning_host_id);
+
+  // Initiates the cache selection algorithm for the given host.
+  // This is sent prior to any subresource loads. An AppCacheMsg_CacheSelected
+  // message will be sent in response.
+  // 'host_id' indentifies a specific document or worker
+  // 'document_url' the url of the main resource
+  // 'appcache_document_was_loaded_from' the id of the appcache the main
+  //     resource was loaded from or kAppCacheNoCacheId
+  // 'opt_manifest_url' the manifest url specified in the <html> tag if any
+  SelectCache(int32 host_id,
+              url.mojom.Url document_url,
+              int64 appcache_document_was_loaded_from,
+              url.mojom.Url opt_manifest_url);
+
+  // Initiates worker specific cache selection algorithm for the given host.
+  SelectCacheForSharedWorker(int32 host_id, int64 appcache_id);
+
+  // Informs the browser of a 'foreign' entry in an appcache.
+  MarkAsForeignEntry(int32 host_id,
+                     url.mojom.Url document_url,
+                     int64 appcache_document_was_loaded_from);
+
+  // Returns the status of the appcache associated with host_id.
+  [Sync]
+  GetStatus(int32 host_id) => (AppCacheStatus status);
+
+  // Initiates an update of the appcache associated with host_id.
+  [Sync]
+  StartUpdate(int32 host_id) => (bool success);
+
+  // Swaps a new pending appcache, if there is one, into use for host_id.
+  [Sync]
+  SwapCache(int32 host_id) => (bool success);
+
+  // Gets resource list from appcache synchronously.
+  [Sync]
+  GetResourceList(int32 host_id) => (array<AppCacheResourceInfo> resources);
+};
+
diff --git a/content/common/appcache_messages.h b/content/common/appcache_messages.h
index 94f6af9..8fba395 100644
--- a/content/common/appcache_messages.h
+++ b/content/common/appcache_messages.h
@@ -52,70 +52,6 @@
 IPC_STRUCT_TRAITS_MEMBER(is_cross_origin)
 IPC_STRUCT_TRAITS_END()
 
-// AppCache messages sent from the child process to the browser.
-
-// Informs the browser of a new appcache host.
-IPC_MESSAGE_CONTROL1(AppCacheHostMsg_RegisterHost,
-                     int /* host_id */)
-
-// Informs the browser of an appcache host being destroyed.
-IPC_MESSAGE_CONTROL1(AppCacheHostMsg_UnregisterHost,
-                     int /* host_id */)
-
-// Informs the browser of which host caused another to be created.
-// This can influence which appcache should be utilized for the main
-// resource load into the newly created host, so it should be sent
-// prior to the main resource request being initiated.
-IPC_MESSAGE_CONTROL2(AppCacheHostMsg_SetSpawningHostId,
-                     int /* host_id */,
-                     int /* spawning_host_id */)
-
-// Initiates the cache selection algorithm for the given host.
-// This is sent prior to any subresource loads. An AppCacheMsg_CacheSelected
-// message will be sent in response.
-// 'host_id' indentifies a specific document or worker
-// 'document_url' the url of the main resource
-// 'appcache_document_was_loaded_from' the id of the appcache the main
-//     resource was loaded from or kAppCacheNoCacheId
-// 'opt_manifest_url' the manifest url specified in the <html> tag if any
-IPC_MESSAGE_CONTROL4(AppCacheHostMsg_SelectCache,
-                     int /* host_id */,
-                     GURL /* document_url */,
-                     int64_t /* appcache_document_was_loaded_from */,
-                     GURL /* opt_manifest_url */)
-
-// Initiates worker specific cache selection algorithm for the given host.
-IPC_MESSAGE_CONTROL2(AppCacheHostMsg_SelectCacheForSharedWorker,
-                     int /* host_id */,
-                     int64_t /* appcache_id */)
-
-// Informs the browser of a 'foreign' entry in an appcache.
-IPC_MESSAGE_CONTROL3(AppCacheHostMsg_MarkAsForeignEntry,
-                     int /* host_id */,
-                     GURL /* document_url */,
-                     int64_t /* appcache_document_was_loaded_from */)
-
-// Returns the status of the appcache associated with host_id.
-IPC_SYNC_MESSAGE_CONTROL1_1(AppCacheHostMsg_GetStatus,
-                            int /* host_id */,
-                            content::AppCacheStatus)
-
-// Initiates an update of the appcache associated with host_id.
-IPC_SYNC_MESSAGE_CONTROL1_1(AppCacheHostMsg_StartUpdate,
-                            int /* host_id */,
-                            bool /* success */)
-
-// Swaps a new pending appcache, if there is one, into use for host_id.
-IPC_SYNC_MESSAGE_CONTROL1_1(AppCacheHostMsg_SwapCache,
-                            int /* host_id */,
-                            bool /* success */)
-
-// Gets resource list from appcache synchronously.
-IPC_SYNC_MESSAGE_CONTROL1_1(AppCacheHostMsg_GetResourceList,
-                            int /* host_id in*/,
-                            std::vector<content::AppCacheResourceInfo>
-                            /* resources out */)
-
 
 // AppCache messages sent from the browser to the child process.
 
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 27bfead..b5589cf 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -38,13 +38,20 @@
 // Implemented by the frame provider and currently must be associated with the
 // legacy IPC channel.
 interface FrameNavigationControl {
-  // Tells the renderer that a navigation is ready to commit.  The renderer
-  // should request |body_url| to get access to the stream containing the body
-  // of the response. When the Network Service is enabled, |body_url| is not
-  // used and instead the data is passed to the renderer via |body_data|. In
-  // that case |subresource_loader_factories| may also be provided by the
-  // browser as a a means for the renderer to load subresources where
-  // applicable.
+  // Tells the renderer that a navigation is ready to commit.
+  //
+  // The renderer should request |body_url| to get access to the stream
+  // containing the body of the response. When the Network Service or
+  // NavigationMojoResponse is enabled, |body_url| is not used and instead
+  // |url_loader_client_endpoints| provides a way to continue the navigation.
+  //
+  // Note: |body_url| and |url_loader_client_endpoints| will be empty iff the
+  // navigation URL wasn't handled by the network stack (i.e. JavaScript URLs,
+  // renderer debug URLs, same document navigations, about:blank, ...)
+  //
+  // When the Network Service is enabled, |subresource_loader_factories| may
+  // also be provided by the browser as a a means for the renderer to load
+  // subresources where applicable.
   //
   // For automation driver-initiated navigations over the devtools protocol,
   // |devtools_navigation_token_| is used to tag the navigation. This navigation
@@ -56,13 +63,14 @@
   // cases, and thus shouldn't be trusted.
   // TODO(crbug.com/783506): Replace devtools navigation token with the generic
   // navigation token that can be passed from renderer to the browser.
-  CommitNavigation(URLResponseHead head,
-                   url.mojom.Url body_url,
-                   CommonNavigationParams common_params,
-                   RequestNavigationParams request_params,
-                   handle<data_pipe_consumer>? body_data,
-                   URLLoaderFactoryBundle? subresource_loader_factories,
-                   mojo.common.mojom.UnguessableToken devtools_navigation_token);
+  CommitNavigation(
+      URLResponseHead head,
+      url.mojom.Url body_url,
+      CommonNavigationParams common_params,
+      RequestNavigationParams request_params,
+      URLLoaderClientEndpoints? url_loader_client_endpoints,
+      URLLoaderFactoryBundle? subresource_loader_factories,
+      mojo.common.mojom.UnguessableToken devtools_navigation_token);
 };
 
 // Implemented by the frame (e.g. renderer processes).
@@ -225,4 +233,3 @@
       blink.mojom.WebSandboxFlags sandbox_flags,
       array<blink.mojom.ParsedFeaturePolicyDeclaration> parsed_header);
 };
-
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc
index cfa211a..d96223e 100644
--- a/content/common/throttling_url_loader.cc
+++ b/content/common/throttling_url_loader.cc
@@ -202,6 +202,11 @@
   loader_cancelled_ = true;
 }
 
+mojom::URLLoaderClientEndpointsPtr ThrottlingURLLoader::Unbind() {
+  return mojom::URLLoaderClientEndpoints::New(url_loader_.PassInterface(),
+                                              client_binding_.Unbind());
+}
+
 ThrottlingURLLoader::ThrottlingURLLoader(
     std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
     mojom::URLLoaderClient* client,
diff --git a/content/common/throttling_url_loader.h b/content/common/throttling_url_loader.h
index dd1138f7..4628efd 100644
--- a/content/common/throttling_url_loader.h
+++ b/content/common/throttling_url_loader.h
@@ -71,6 +71,10 @@
   // Disconnects the client connection and releases the URLLoader.
   void DisconnectClient();
 
+  // Disconnect the forwarding URLLoaderClient and the URLLoader. Returns the
+  // datapipe endpoints.
+  mojom::URLLoaderClientEndpointsPtr Unbind();
+
   // Sets the forwarding client to receive all subsequent notifications.
   void set_forwarding_client(mojom::URLLoaderClient* client) {
     forwarding_client_ = client;
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc
index fd1539c5..9aba2fe 100644
--- a/content/ppapi_plugin/ppapi_thread.cc
+++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -275,7 +275,9 @@
                                const ppapi::PpapiPermissions& permissions) {
   // In case of crashes, the crash dump doesn't indicate which plugin
   // it came from.
-  base::debug::SetCrashKeyValue("ppapi_path", path.MaybeAsASCII());
+  static auto* ppapi_path_key = base::debug::AllocateCrashKeyString(
+      "ppapi_path", base::debug::CrashKeySize::Size64);
+  base::debug::SetCrashKeyString(ppapi_path_key, path.MaybeAsASCII());
 
   SavePluginName(path);
 
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
index 8311a052..ed0ec71 100644
--- a/content/public/app/mojo/content_browser_manifest.json
+++ b/content/public/app/mojo/content_browser_manifest.json
@@ -22,11 +22,13 @@
           "blink::mojom::BackgroundSyncService",
           "blink::mojom::BlobRegistry",
           "blink::mojom::BroadcastChannelProvider",
+          "blink::mojom::LockManager",
           "blink::mojom::Hyphenation",
           "blink::mojom::MimeRegistry",
           "blink::mojom::OffscreenCanvasProvider",
           "blink::mojom::ReportingServiceProxy",
           "blink::mojom::WebDatabaseHost",
+          "content::mojom::AppCacheBackend",
           "content::mojom::ClipboardHost",
           "content::mojom::FieldTrialRecorder",
           "content::mojom::FileUtilitiesHost",
@@ -123,6 +125,7 @@
           "autofill::mojom::AutofillDriver",
           "autofill::mojom::PasswordManagerDriver",
           "blink::mojom::DedicatedWorkerFactory",
+          "blink::mojom::LockManager",
           "blink::mojom::GeolocationService",
           "blink::mojom::InsecureInputService",
           "blink::mojom::KeyboardLockService",
@@ -176,6 +179,7 @@
     "navigation:dedicated_worker": {
       "provides": {
         "renderer": [
+          "blink::mojom::LockManager",
           "blink::mojom::NotificationService",
           "blink::mojom::PermissionService",
           "payments::mojom::PaymentManager",
@@ -188,6 +192,7 @@
     "navigation:service_worker": {
       "provides": {
         "renderer": [
+          "blink::mojom::LockManager",
           "blink::mojom::NotificationService",
           "blink::mojom::PermissionService",
           "blink::mojom::WebSocket",
@@ -201,6 +206,7 @@
     "navigation:shared_worker": {
       "provides": {
         "renderer": [
+          "blink::mojom::LockManager",
           "blink::mojom::NotificationService",
           "blink::mojom::PermissionService",
           "blink::mojom::WebSocket",
diff --git a/content/public/app/mojo/content_utility_manifest.json b/content/public/app/mojo/content_utility_manifest.json
index 645b7fe..32ed07b 100644
--- a/content/public/app/mojo/content_utility_manifest.json
+++ b/content/public/app/mojo/content_utility_manifest.json
@@ -10,6 +10,7 @@
           "content::mojom::ChildHistogramFetcher",
           "content::mojom::ChildHistogramFetcherFactory",
           "IPC::mojom::ChannelBootstrap",
+          "printing::mojom::PdfToEmfConverterFactory",
           "printing::mojom::PdfToPwgRasterConverter",
           "service_manager::mojom::ServiceFactory"
         ],
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h
index 300adbb7..f73f0c3 100644
--- a/content/public/browser/navigation_handle.h
+++ b/content/public/browser/navigation_handle.h
@@ -295,8 +295,7 @@
 
   // Simulates the network request failing.
   virtual NavigationThrottle::ThrottleCheckResult CallWillFailRequestForTesting(
-      base::Optional<net::SSLInfo> ssl_info,
-      bool should_ssl_errors_be_fatal) = 0;
+      base::Optional<net::SSLInfo> ssl_info) = 0;
 
   // Simulates the reception of the network response.
   virtual NavigationThrottle::ThrottleCheckResult
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h
index 6aa5a86..5b40284 100644
--- a/content/public/browser/render_widget_host_view.h
+++ b/content/public/browser/render_widget_host_view.h
@@ -28,7 +28,6 @@
 }
 
 namespace ui {
-class AcceleratedWidgetMac;
 class TextInputClient;
 }
 
@@ -249,10 +248,6 @@
   virtual void GetScreenInfo(ScreenInfo* screen_info) = 0;
 
 #if defined(OS_MACOSX)
-  // Return the accelerated widget which hosts the CALayers that draw the
-  // content of the view in GetNativeView. This may be null.
-  virtual ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const = 0;
-
   // Set the view's active state (i.e., tint state of controls).
   virtual void SetActive(bool active) = 0;
 
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index 00da395..17679bf 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -194,6 +194,10 @@
   // Clear the bluetooth allowed devices map. For test use only.
   virtual void ClearBluetoothAllowedDevicesMapForTesting() = 0;
 
+  // Call |FlushForTesting()| on Network Service related interfaces. For test
+  // use only.
+  virtual void FlushNetworkInterfaceForTesting() = 0;
+
  protected:
   virtual ~StoragePartition() {}
 };
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index d34a43e..fb1f64a 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -151,7 +151,13 @@
 // invalidated upon notifications sent by base::SystemMonitor. If disabled, the
 // cache is considered invalid on every enumeration request.
 const base::Feature kMediaDevicesSystemMonitorCache{
-    "MediaDevicesSystemMonitorCaching", base::FEATURE_DISABLED_BY_DEFAULT};
+  "MediaDevicesSystemMonitorCaching",
+#if defined(OS_MACOSX)
+      base::FEATURE_ENABLED_BY_DEFAULT
+#else
+      base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
 
 // Enables the memory coordinator.
 // WARNING:
diff --git a/content/public/common/url_loader.mojom b/content/public/common/url_loader.mojom
index 1db483e..26cf7e4f 100644
--- a/content/public/common/url_loader.mojom
+++ b/content/public/common/url_loader.mojom
@@ -112,3 +112,9 @@
   OnComplete(URLLoaderCompletionStatus status);
 };
 
+// Convenient struct that groups the two communication endpoints most
+// implementations of URLLoaderClient use to communicate with their URLLoader.
+struct URLLoaderClientEndpoints {
+  URLLoader url_loader;
+  URLLoaderClient& url_loader_client;
+};
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 80085bd..d7c3a2ae 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -2061,6 +2061,10 @@
   handle_->CallResumeForTesting();
 }
 
+NavigationHandle* TestNavigationManager::GetNavigationHandle() {
+  return handle_;
+}
+
 bool TestNavigationManager::WaitForResponse() {
   desired_state_ = NavigationState::RESPONSE;
   return WaitForDesiredState();
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 92579ad..1180be5 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -861,7 +861,7 @@
 // resumed automatically if a Wait method is called for a future event.
 // Note: This class is one time use only! After it successfully tracks a
 // navigation it will ignore all subsequent navigations. Explicitly create
-// mutliple instances of this class if you want to pause multiple navigations.
+// multiple instances of this class if you want to pause multiple navigations.
 class TestNavigationManager : public WebContentsObserver {
  public:
   // Monitors any frame in WebContents.
@@ -886,6 +886,10 @@
   // * Called after |WaitForResponse|, it causes the response to be committed.
   void ResumeNavigation();
 
+  // Returns the NavigationHandle associated with the navigation. It is non-null
+  // only in between DidStartNavigation(...) and DidFinishNavigation(...).
+  NavigationHandle* GetNavigationHandle();
+
  protected:
   // Derived classes can override if they want to filter out navigations. This
   // is called from DidStartNavigation.
diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc
index b1d930a67..7cdebd4 100644
--- a/content/public/test/mock_render_thread.cc
+++ b/content/public/test/mock_render_thread.cc
@@ -27,6 +27,10 @@
 
 namespace {
 
+// Some tests hard-code small numbers for routing IDs, so make reasonably sure
+// that the IDs generated by MockRenderThread will not clash.
+constexpr int32_t kFirstGeneratedRoutingId = 313337000;
+
 class MockRenderMessageFilterImpl : public mojom::RenderMessageFilter {
  public:
   explicit MockRenderMessageFilterImpl(MockRenderThread* thread)
@@ -97,11 +101,7 @@
 }  // namespace
 
 MockRenderThread::MockRenderThread()
-    : routing_id_(0),
-      opener_id_(0),
-      new_window_routing_id_(0),
-      new_window_main_frame_widget_routing_id_(0),
-      new_frame_routing_id_(0),
+    : next_routing_id_(kFirstGeneratedRoutingId),
       mock_render_message_filter_(new MockRenderMessageFilterImpl(this)) {
   RenderThreadImpl::SetRenderMessageFilterForTesting(
       mock_render_message_filter_.get());
@@ -279,17 +279,16 @@
 
 void MockRenderThread::SetFieldTrialGroup(const std::string& trial_name,
                                           const std::string& group_name) {}
-void MockRenderThread::SendCloseMessage() {
-  ViewMsg_Close msg(routing_id_);
-  RenderViewImpl::FromRoutingID(routing_id_)->OnMessageReceived(msg);
+
+int32_t MockRenderThread::GetNextRoutingID() {
+  return next_routing_id_++;
 }
 
 // The Widget expects to be returned a valid route_id.
 void MockRenderThread::OnCreateWidget(int opener_id,
                                       blink::WebPopupType popup_type,
                                       int* route_id) {
-  opener_id_ = opener_id;
-  *route_id = routing_id_;
+  *route_id = GetNextRoutingID();
 }
 
 service_manager::mojom::InterfaceProviderRequest
@@ -321,7 +320,7 @@
     int* new_render_frame_id,
     mojo::MessagePipeHandle* new_interface_provider,
     base::UnguessableToken* devtools_frame_token) {
-  *new_render_frame_id = new_frame_routing_id_++;
+  *new_render_frame_id = GetNextRoutingID();
   service_manager::mojom::InterfaceProviderPtr interface_provider;
   frame_routing_id_to_initial_interface_provider_requests_.emplace(
       *new_render_frame_id, mojo::MakeRequest(&interface_provider));
@@ -364,13 +363,15 @@
 void MockRenderThread::OnCreateWindow(
     const mojom::CreateNewWindowParams& params,
     mojom::CreateNewWindowReply* reply) {
-  reply->route_id = new_window_routing_id_++;
-  reply->main_frame_route_id = new_frame_routing_id_++;
+  reply->route_id = GetNextRoutingID();
+  reply->main_frame_route_id = GetNextRoutingID();
   frame_routing_id_to_initial_interface_provider_requests_.emplace(
       reply->main_frame_route_id,
       mojo::MakeRequest(&reply->main_frame_interface_provider));
-  reply->main_frame_widget_route_id =
-      new_window_main_frame_widget_routing_id_++;
+  // TODO(avi): Widget routing IDs should be distinct from the view routing IDs,
+  // once RenderWidgetHost is distilled from RenderViewHostImpl.
+  // See: https://crbug.com/545684.
+  reply->main_frame_widget_route_id = reply->route_id;
   reply->cloned_session_storage_namespace_id = 0;
 }
 
diff --git a/content/public/test/mock_render_thread.h b/content/public/test/mock_render_thread.h
index adaa338..2ec55ea8 100644
--- a/content/public/test/mock_render_thread.h
+++ b/content/public/test/mock_render_thread.h
@@ -93,25 +93,9 @@
   void SetFieldTrialGroup(const std::string& trial_name,
                           const std::string& group_name) override;
 
-  //////////////////////////////////////////////////////////////////////////
-  // The following functions are called by the test itself.
-
-  void set_routing_id(int32_t id) { routing_id_ = id; }
-
-  int32_t opener_id() const { return opener_id_; }
-
-  void set_new_window_routing_id(int32_t id) { new_window_routing_id_ = id; }
-
-  void set_new_window_main_frame_widget_routing_id(int32_t id) {
-    new_window_main_frame_widget_routing_id_ = id;
-  }
-
-  void set_new_frame_routing_id(int32_t id) { new_frame_routing_id_ = id; }
-
-  // Simulates the Widget receiving a close message. This should result
-  // on releasing the internal reference counts and destroying the internal
-  // state.
-  void SendCloseMessage();
+  // Returns a new, unique routing ID that can be assigned to the next view,
+  // widget, or frame.
+  int32_t GetNextRoutingID();
 
   // Dispatches control messages to observers.
   bool OnControlMessageReceived(const IPC::Message& msg);
@@ -162,17 +146,8 @@
 
   IPC::TestSink sink_;
 
-  // Routing id what will be assigned to the Widget.
-  int32_t routing_id_;
-
-  // Opener id reported by the Widget.
-  int32_t opener_id_;
-
-  // Routing id that will be assigned to a CreateWindow Widget and/or child
-  // frames.
-  int32_t new_window_routing_id_;
-  int32_t new_window_main_frame_widget_routing_id_;
-  int32_t new_frame_routing_id_;
+  // Routing ID what will be assigned to the next view, widget, or frame.
+  int32_t next_routing_id_;
 
   std::map<int32_t, service_manager::mojom::InterfaceProviderRequest>
       frame_routing_id_to_initial_interface_provider_requests_;
diff --git a/content/public/test/network_service_test_helper.cc b/content/public/test/network_service_test_helper.cc
index 8b0b55350..4aaba75d 100644
--- a/content/public/test/network_service_test_helper.cc
+++ b/content/public/test/network_service_test_helper.cc
@@ -10,6 +10,8 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
+#include "base/logging.h"
+#include "base/process/process.h"
 #include "content/public/common/content_features.h"
 #include "content/public/test/test_host_resolver.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
@@ -45,7 +47,11 @@
   }
 
   void SimulateCrash() override {
-    CHECK(false) << "Crash NetworkService process for testing.";
+    LOG(ERROR) << "Intentionally issuing kill signal to current process to"
+               << " simulate NetworkService crash for testing.";
+    // Use |Process::Terminate()| instead of |CHECK()| to avoid 'Fatal error'
+    // dialog on Windows debug.
+    base::Process::Current().Terminate(1, false);
   }
 
   void BindRequest(content::mojom::NetworkServiceTestRequest request) {
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index 0061fcb2..43dbf8b 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -75,16 +75,6 @@
 
 namespace {
 
-const int32_t kRouteId = 101;
-const int32_t kMainFrameRouteId = 201;
-// TODO(avi): Widget routing IDs should be distinct from the view routing IDs,
-// once RenderWidgetHost is distilled from RenderViewHostImpl.
-// https://crbug.com/545684
-const int32_t kMainFrameWidgetRouteId = 101;
-
-const int32_t kNewWindowRouteId = 211;
-const int32_t kNewFrameRouteId = 111;
-const int32_t kNewFrameWidgetRouteId = 211;
 
 // Converts |ascii_character| into |key_code| and returns true on success.
 // Handles only the characters needed by tests.
@@ -239,11 +229,6 @@
   // the order on Chromium initialization.
   if (!render_thread_)
     render_thread_ = std::make_unique<MockRenderThread>();
-  render_thread_->set_routing_id(kRouteId);
-  render_thread_->set_new_window_routing_id(kNewWindowRouteId);
-  render_thread_->set_new_window_main_frame_widget_routing_id(
-      kNewFrameWidgetRouteId);
-  render_thread_->set_new_frame_routing_id(kNewFrameRouteId);
 
   // Blink needs to be initialized before calling CreateContentRendererClient()
   // because it uses blink internally.
@@ -309,12 +294,13 @@
   view_params->window_was_created_with_opener = false;
   view_params->renderer_preferences = RendererPreferences();
   view_params->web_preferences = WebPreferences();
-  view_params->view_id = kRouteId;
+  view_params->view_id = render_thread_->GetNextRoutingID();
+  // For now these two must be equal. See: https://crbug.com/545684.
+  view_params->main_frame_widget_routing_id = view_params->view_id;
+  view_params->main_frame_routing_id = render_thread_->GetNextRoutingID();
   render_thread_->PassInitialInterfaceProviderRequestForFrame(
-      kMainFrameRouteId,
+      view_params->main_frame_routing_id,
       mojo::MakeRequest(&view_params->main_frame_interface_provider));
-  view_params->main_frame_routing_id = kMainFrameRouteId;
-  view_params->main_frame_widget_routing_id = kMainFrameWidgetRouteId;
   view_params->session_storage_namespace_id = kInvalidSessionStorageNamespaceId;
   view_params->swapped_out = false;
   view_params->replicated_frame_state = FrameReplicationState();
@@ -335,7 +321,10 @@
   // Run the loop so the release task from the renderwidget executes.
   base::RunLoop().RunUntilIdle();
 
-  render_thread_->SendCloseMessage();
+  // Simulate the Widget receiving a close message. This should result on
+  // releasing the internal reference counts and destroying the internal state.
+  ViewMsg_Close msg(view_->GetRoutingID());
+  static_cast<RenderViewImpl*>(view_)->OnMessageReceived(msg);
 
   std::unique_ptr<blink::WebLeakDetector> leak_detector =
       base::WrapUnique(blink::WebLeakDetector::Create(this));
diff --git a/content/public/test/test_storage_partition.cc b/content/public/test/test_storage_partition.cc
index a584e345..cc4e470 100644
--- a/content/public/test/test_storage_partition.cc
+++ b/content/public/test/test_storage_partition.cc
@@ -116,4 +116,6 @@
 
 void TestStoragePartition::ClearBluetoothAllowedDevicesMapForTesting() {}
 
+void TestStoragePartition::FlushNetworkInterfaceForTesting() {}
+
 }  // namespace content
diff --git a/content/public/test/test_storage_partition.h b/content/public/test/test_storage_partition.h
index f96fc486..546e40fd 100644
--- a/content/public/test/test_storage_partition.h
+++ b/content/public/test/test_storage_partition.h
@@ -154,6 +154,7 @@
   void Flush() override;
 
   void ClearBluetoothAllowedDevicesMapForTesting() override;
+  void FlushNetworkInterfaceForTesting() override;
 
  private:
   base::FilePath file_path_;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index d88a57d..4a5c71d 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -909,9 +909,12 @@
       "//jingle:jingle_glue",
       "//third_party/libvpx",
       "//third_party/opus",
+      "//third_party/webrtc/api:libjingle_api_deprecated_headers",
       "//third_party/webrtc/api:libjingle_logging_api",
       "//third_party/webrtc/api:libjingle_peerconnection",
+      "//third_party/webrtc/api:libjingle_peerconnection_api",
       "//third_party/webrtc/api:optional",
+      "//third_party/webrtc/api:peerconnection_and_implicit_call_api",
       "//third_party/webrtc/api:rtc_stats_api",
       "//third_party/webrtc/api:video_frame_api",
       "//third_party/webrtc/api:video_frame_api_i420",
@@ -938,6 +941,7 @@
       "//third_party/webrtc/p2p:libstunprober",
       "//third_party/webrtc/p2p:rtc_p2p",
       "//third_party/webrtc/pc:rtc_pc",
+      "//third_party/webrtc/pc:rtc_pc_base",
       "//third_party/webrtc/rtc_base:rtc_base",
       "//third_party/webrtc/rtc_base:rtc_task_queue",
       "//third_party/webrtc/stats",
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
index 79b5099..177ef68 100644
--- a/content/renderer/android/synchronous_layer_tree_frame_sink.cc
+++ b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -19,7 +19,7 @@
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/quads/render_pass.h"
 #include "components/viz/common/quads/surface_draw_quad.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_frame.h"
@@ -130,7 +130,8 @@
       sender_(RenderThreadImpl::current()->sync_compositor_message_filter()),
       memory_policy_(0u),
       frame_swap_message_queue_(frame_swap_message_queue),
-      local_surface_id_allocator_(new viz::LocalSurfaceIdAllocator),
+      parent_local_surface_id_allocator_(
+          new viz::ParentLocalSurfaceIdAllocator),
       begin_frame_source_(std::move(begin_frame_source)) {
   DCHECK(registry_);
   DCHECK(sender_);
@@ -222,7 +223,7 @@
   child_support_.reset();
   software_output_surface_ = nullptr;
   display_ = nullptr;
-  local_surface_id_allocator_ = nullptr;
+  parent_local_surface_id_allocator_ = nullptr;
   frame_sink_manager_ = nullptr;
   cc::LayerTreeFrameSink::DetachFromClient();
   CancelFallbackTick();
@@ -261,14 +262,15 @@
 
     if (!root_local_surface_id_.is_valid() || display_size_ != display_size ||
         device_scale_factor_ != frame.metadata.device_scale_factor) {
-      root_local_surface_id_ = local_surface_id_allocator_->GenerateId();
+      root_local_surface_id_ = parent_local_surface_id_allocator_->GenerateId();
       display_size_ = display_size;
       device_scale_factor_ = frame.metadata.device_scale_factor;
     }
 
     if (!child_local_surface_id_.is_valid() || child_size_ != child_size ||
         device_scale_factor_ != frame.metadata.device_scale_factor) {
-      child_local_surface_id_ = local_surface_id_allocator_->GenerateId();
+      child_local_surface_id_ =
+          parent_local_surface_id_allocator_->GenerateId();
       child_size_ = child_size;
       device_scale_factor_ = frame.metadata.device_scale_factor;
     }
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.h b/content/renderer/android/synchronous_layer_tree_frame_sink.h
index a3af84f9..16c2ff82 100644
--- a/content/renderer/android/synchronous_layer_tree_frame_sink.h
+++ b/content/renderer/android/synchronous_layer_tree_frame_sink.h
@@ -36,7 +36,7 @@
 class ContextProvider;
 class Display;
 class FrameSinkManagerImpl;
-class LocalSurfaceIdAllocator;
+class ParentLocalSurfaceIdAllocator;
 }  // namespace viz
 
 namespace content {
@@ -153,12 +153,15 @@
         bool will_draw_and_swap,
         const viz::RenderPassList& render_passes) override {}
     void DisplayDidDrawAndSwap() override {}
+    void DisplayDidReceiveCALayerParams(
+        const gfx::CALayerParams& ca_layer_params) override {}
   };
 
   // TODO(danakj): These don't to be stored in unique_ptrs when OutputSurface
   // is owned/destroyed on the compositor thread.
   std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_;
-  std::unique_ptr<viz::LocalSurfaceIdAllocator> local_surface_id_allocator_;
+  std::unique_ptr<viz::ParentLocalSurfaceIdAllocator>
+      parent_local_surface_id_allocator_;
   viz::LocalSurfaceId child_local_surface_id_;
   viz::LocalSurfaceId root_local_surface_id_;
   gfx::Size child_size_;
diff --git a/content/renderer/appcache/appcache_backend_proxy.cc b/content/renderer/appcache/appcache_backend_proxy.cc
index 6b7ad4c..4014a9f 100644
--- a/content/renderer/appcache/appcache_backend_proxy.cc
+++ b/content/renderer/appcache/appcache_backend_proxy.cc
@@ -3,23 +3,37 @@
 // found in the LICENSE file.
 
 #include "content/renderer/appcache/appcache_backend_proxy.h"
-
+#include "content/common/appcache.mojom.h"
 #include "content/common/appcache_messages.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/public/renderer/render_thread.h"
+#include "services/service_manager/public/cpp/connector.h"
 
 namespace content {
 
+AppCacheBackendProxy::AppCacheBackendProxy(IPC::Sender* sender)
+    : sender_(sender) {}
+AppCacheBackendProxy::~AppCacheBackendProxy() = default;
+
+mojom::AppCacheBackend* AppCacheBackendProxy::GetAppCacheBackendPtr() {
+  if (!app_cache_backend_ptr_) {
+    RenderThread::Get()->GetConnector()->BindInterface(
+        mojom::kBrowserServiceName, mojo::MakeRequest(&app_cache_backend_ptr_));
+  }
+  return app_cache_backend_ptr_.get();
+}
+
 void AppCacheBackendProxy::RegisterHost(int host_id) {
-  sender_->Send(new AppCacheHostMsg_RegisterHost(host_id));
+  GetAppCacheBackendPtr()->RegisterHost(host_id);
 }
 
 void AppCacheBackendProxy::UnregisterHost(int host_id) {
-  sender_->Send(new AppCacheHostMsg_UnregisterHost(host_id));
+  GetAppCacheBackendPtr()->UnregisterHost(host_id);
 }
 
 void AppCacheBackendProxy::SetSpawningHostId(int host_id,
                                              int spawning_host_id) {
-  sender_->Send(new AppCacheHostMsg_SetSpawningHostId(
-                                    host_id, spawning_host_id));
+  GetAppCacheBackendPtr()->SetSpawningHostId(host_id, spawning_host_id);
 }
 
 void AppCacheBackendProxy::SelectCache(
@@ -27,48 +41,48 @@
     const GURL& document_url,
     const int64_t cache_document_was_loaded_from,
     const GURL& manifest_url) {
-  sender_->Send(new AppCacheHostMsg_SelectCache(
-                                    host_id, document_url,
-                                    cache_document_was_loaded_from,
-                                    manifest_url));
+  GetAppCacheBackendPtr()->SelectCache(
+      host_id, document_url, cache_document_was_loaded_from, manifest_url);
 }
 
 void AppCacheBackendProxy::SelectCacheForSharedWorker(int host_id,
                                                       int64_t appcache_id) {
-  sender_->Send(new AppCacheHostMsg_SelectCacheForSharedWorker(
-                                    host_id, appcache_id));
+  GetAppCacheBackendPtr()->SelectCacheForSharedWorker(host_id, appcache_id);
 }
 
 void AppCacheBackendProxy::MarkAsForeignEntry(
     int host_id,
     const GURL& document_url,
     int64_t cache_document_was_loaded_from) {
-  sender_->Send(new AppCacheHostMsg_MarkAsForeignEntry(
-                                    host_id, document_url,
-                                    cache_document_was_loaded_from));
+  GetAppCacheBackendPtr()->MarkAsForeignEntry(host_id, document_url,
+                                              cache_document_was_loaded_from);
 }
 
 AppCacheStatus AppCacheBackendProxy::GetStatus(int host_id) {
   AppCacheStatus status = AppCacheStatus::APPCACHE_STATUS_UNCACHED;
-  sender_->Send(new AppCacheHostMsg_GetStatus(host_id, &status));
+  GetAppCacheBackendPtr()->GetStatus(host_id, &status);
   return status;
 }
 
 bool AppCacheBackendProxy::StartUpdate(int host_id) {
   bool result = false;
-  sender_->Send(new AppCacheHostMsg_StartUpdate(host_id, &result));
+  GetAppCacheBackendPtr()->StartUpdate(host_id, &result);
   return result;
 }
 
 bool AppCacheBackendProxy::SwapCache(int host_id) {
   bool result = false;
-  sender_->Send(new AppCacheHostMsg_SwapCache(host_id, &result));
+  GetAppCacheBackendPtr()->SwapCache(host_id, &result);
   return result;
 }
 
 void AppCacheBackendProxy::GetResourceList(
     int host_id, std::vector<AppCacheResourceInfo>* resource_infos) {
-  sender_->Send(new AppCacheHostMsg_GetResourceList(host_id, resource_infos));
+  std::vector<mojom::AppCacheResourceInfoPtr> boxed_infos;
+  GetAppCacheBackendPtr()->GetResourceList(host_id, &boxed_infos);
+  for (auto& b : boxed_infos) {
+    resource_infos->emplace_back(std::move(*b));
+  }
 }
 
 }  // namespace content
diff --git a/content/renderer/appcache/appcache_backend_proxy.h b/content/renderer/appcache/appcache_backend_proxy.h
index 5ae06c5b..6635e93 100644
--- a/content/renderer/appcache/appcache_backend_proxy.h
+++ b/content/renderer/appcache/appcache_backend_proxy.h
@@ -9,6 +9,7 @@
 
 #include <vector>
 
+#include "content/common/appcache.mojom.h"
 #include "content/common/appcache_interfaces.h"
 #include "ipc/ipc_sender.h"
 
@@ -17,7 +18,8 @@
 // Sends appcache related messages to the main process.
 class AppCacheBackendProxy : public AppCacheBackend {
  public:
-  explicit AppCacheBackendProxy(IPC::Sender* sender) : sender_(sender) {}
+  explicit AppCacheBackendProxy(IPC::Sender* sender);
+  ~AppCacheBackendProxy() override;
 
   IPC::Sender* sender() const { return sender_; }
 
@@ -41,6 +43,10 @@
       std::vector<AppCacheResourceInfo>* resource_infos) override;
 
  private:
+  mojom::AppCacheBackend* GetAppCacheBackendPtr();
+
+  mojom::AppCacheBackendPtr app_cache_backend_ptr_;
+
   IPC::Sender* sender_;
 };
 
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index 55eaf81..9850f968 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -95,6 +95,7 @@
       ready_(false),
       browser_plugin_instance_id_(browser_plugin::kInstanceIDNone),
       delegate_(delegate),
+      task_runner_(render_frame->GetTaskRunner(blink::TaskType::kUnthrottled)),
       weak_ptr_factory_(this) {
   browser_plugin_instance_id_ =
       BrowserPluginManager::Get()->GetNextInstanceID();
@@ -267,7 +268,7 @@
       sent_resize_params_->screen_info != pending_resize_params_.screen_info;
 
   if (synchronized_params_changed)
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
 
   if (enable_surface_synchronization_ && frame_sink_id_.is_valid()) {
     compositing_helper_->SetPrimarySurfaceId(
@@ -452,7 +453,7 @@
 
   // Defer attach call so that if there's any pending browser plugin
   // destruction, then it can progress first.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
+  task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&BrowserPlugin::UpdateInternalInstanceId,
                                 weak_ptr_factory_.GetWeakPtr()));
 
@@ -482,7 +483,8 @@
       render_frame ? render_frame->GetRenderView() : nullptr);
   if (render_view)
     render_view->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
-  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+
+  task_runner_->DeleteSoon(FROM_HERE, this);
 }
 
 v8::Local<v8::Object> BrowserPlugin::V8ScriptableObject(v8::Isolate* isolate) {
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h
index 37d61fe..eb9abce 100644
--- a/content/renderer/browser_plugin/browser_plugin.h
+++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -15,7 +15,7 @@
 #include "base/sequenced_task_runner_helpers.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/common/surfaces/local_surface_id.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "content/public/common/screen_info.h"
 #include "content/renderer/mouse_lock_dispatcher.h"
 #include "content/renderer/render_view_impl.h"
@@ -247,7 +247,7 @@
 
   viz::FrameSinkId frame_sink_id_;
   viz::LocalSurfaceId local_surface_id_;
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
 
   bool enable_surface_synchronization_ = false;
 
@@ -276,6 +276,8 @@
   std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame_;
 #endif
 
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
   // Weak factory used in v8 |MakeWeak| callback, since the v8 callback might
   // get called after BrowserPlugin has been destroyed.
   base::WeakPtrFactory<BrowserPlugin> weak_ptr_factory_;
diff --git a/content/renderer/devtools/devtools_agent.cc b/content/renderer/devtools/devtools_agent.cc
index 685c39f..bc22eceb 100644
--- a/content/renderer/devtools/devtools_agent.cc
+++ b/content/renderer/devtools/devtools_agent.cc
@@ -111,10 +111,11 @@
  public:
   IOSession(int session_id,
             base::SequencedTaskRunner* session_task_runner,
+            scoped_refptr<base::SingleThreadTaskRunner> agent_task_runner,
             base::WeakPtr<DevToolsAgent> agent,
             mojom::DevToolsSessionRequest request)
       : session_id_(session_id),
-        agent_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+        agent_task_runner_(agent_task_runner),
         agent_(std::move(agent)),
         binding_(this) {
     session_task_runner->PostTask(
@@ -226,8 +227,9 @@
   io_sessions_.emplace(
       session_id,
       std::unique_ptr<IOSession, base::OnTaskRunnerDeleter>(
-          new IOSession(session_id, io_task_runner, weak_factory_.GetWeakPtr(),
-                        std::move(io_session)),
+          new IOSession(session_id, io_task_runner,
+                        frame_->GetTaskRunner(blink::TaskType::kUnthrottled),
+                        weak_factory_.GetWeakPtr(), std::move(io_session)),
           base::OnTaskRunnerDeleter(io_task_runner)));
 
   hosts_[session_id].Bind(std::move(host));
diff --git a/content/renderer/input/input_event_filter.cc b/content/renderer/input/input_event_filter.cc
index 90c5ae0e..3d6c6fb3 100644
--- a/content/renderer/input/input_event_filter.cc
+++ b/content/renderer/input/input_event_filter.cc
@@ -322,8 +322,11 @@
     return;
   static size_t s_send_failure_count_ = 0;
   s_send_failure_count_++;
-  base::debug::SetCrashKeyValue("input-event-filter-send-failure",
-                                base::IntToString(s_send_failure_count_));
+
+  static auto* crash_key = base::debug::AllocateCrashKeyString(
+      "input-event-filter-send-failure", base::debug::CrashKeySize::Size32);
+  base::debug::SetCrashKeyString(crash_key,
+                                 base::IntToString(s_send_failure_count_));
 }
 
 }  // namespace content
diff --git a/content/renderer/input/input_event_filter_unittest.cc b/content/renderer/input/input_event_filter_unittest.cc
index e691012..a3cf3f6 100644
--- a/content/renderer/input/input_event_filter_unittest.cc
+++ b/content/renderer/input/input_event_filter_unittest.cc
@@ -312,7 +312,8 @@
   for (size_t i = 0; i < arraysize(kEvents); ++i) {
     const IPC::Message* message = ipc_sink_.GetMessageAt(i);
     EXPECT_EQ(kTestRoutingID, message->routing_id());
-    EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
+    EXPECT_EQ(static_cast<uint32_t>(InputHostMsg_HandleInputEvent_ACK::ID),
+              message->type());
 
     InputHostMsg_HandleInputEvent_ACK::Param params;
     EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(message, &params));
@@ -358,7 +359,8 @@
   for (size_t i = 0; i < arraysize(kEvents); ++i) {
     const IPC::Message* message = ipc_sink_.GetMessageAt(i);
     EXPECT_EQ(kTestRoutingID, message->routing_id());
-    EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
+    EXPECT_EQ(static_cast<uint32_t>(InputHostMsg_HandleInputEvent_ACK::ID),
+              message->type());
 
     InputHostMsg_HandleInputEvent_ACK::Param params;
     EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(message, &params));
diff --git a/content/renderer/input/widget_input_handler_impl.cc b/content/renderer/input/widget_input_handler_impl.cc
index c32c751..c06b9b0a 100644
--- a/content/renderer/input/widget_input_handler_impl.cc
+++ b/content/renderer/input/widget_input_handler_impl.cc
@@ -43,9 +43,11 @@
 void RunClosureIfNotSwappedOut(base::WeakPtr<RenderWidget> render_widget,
                                base::OnceClosure closure) {
   // Input messages must not be processed if the RenderWidget is in swapped out
-  // state.
-  if (!render_widget || render_widget->is_swapped_out())
+  // or closing state.
+  if (!render_widget || render_widget->is_swapped_out() ||
+      render_widget->IsClosing()) {
     return;
+  }
   std::move(closure).Run();
 }
 
diff --git a/content/renderer/input/widget_input_handler_manager.cc b/content/renderer/input/widget_input_handler_manager.cc
index e570d814..aa4a8c3a 100644
--- a/content/renderer/input/widget_input_handler_manager.cc
+++ b/content/renderer/input/widget_input_handler_manager.cc
@@ -315,7 +315,8 @@
     const ui::WebScopedInputEvent& event,
     const ui::LatencyInfo& latency,
     mojom::WidgetInputHandler::DispatchEventCallback callback) {
-  if (!render_widget_ || render_widget_->is_swapped_out()) {
+  if (!render_widget_ || render_widget_->is_swapped_out() ||
+      render_widget_->IsClosing()) {
     std::move(callback).Run(InputEventAckSource::MAIN_THREAD, latency,
                             INPUT_EVENT_ACK_STATE_NOT_CONSUMED, base::nullopt,
                             base::nullopt);
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc
index 7d6b8a0..22a89f4 100644
--- a/content/renderer/loader/resource_dispatcher.cc
+++ b/content/renderer/loader/resource_dispatcher.cc
@@ -659,7 +659,7 @@
     blink::WebURLRequest::LoadingIPCType ipc_type,
     mojom::URLLoaderFactory* url_loader_factory,
     std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
-    mojo::ScopedDataPipeConsumerHandle consumer_handle) {
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints) {
   CheckSchemeForReferrerPolicy(*request);
 
   // Compute a unique request_id for this renderer process.
@@ -677,14 +677,14 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       loading_task_runner ? loading_task_runner : thread_task_runner_;
 
-  if (consumer_handle.is_valid()) {
+  if (url_loader_client_endpoints) {
     pending_requests_[request_id]->url_loader_client =
         std::make_unique<URLLoaderClientImpl>(request_id, this, task_runner);
 
     task_runner->PostTask(
         FROM_HERE, base::BindOnce(&ResourceDispatcher::ContinueForNavigation,
                                   weak_factory_.GetWeakPtr(), request_id,
-                                  base::Passed(std::move(consumer_handle))));
+                                  std::move(url_loader_client_endpoints)));
 
     return request_id;
   }
@@ -787,7 +787,8 @@
 
 void ResourceDispatcher::ContinueForNavigation(
     int request_id,
-    mojo::ScopedDataPipeConsumerHandle consumer_handle) {
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints) {
+  DCHECK(url_loader_client_endpoints);
   PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
   if (!request_info)
     return;
@@ -800,28 +801,13 @@
   // WebURLLoaderImpl::Context::OnReceivedResponse.
   client_ptr->OnReceiveResponse(ResourceResponseHead(), base::nullopt,
                                 mojom::DownloadedTempFilePtr());
+  // TODO(clamy): Move the replaying of redirects from WebURLLoaderImpl here.
 
   // Abort if the request is cancelled.
   if (!GetPendingRequestInfo(request_id))
     return;
 
-  // Start streaming now.
-  client_ptr->OnStartLoadingResponseBody(std::move(consumer_handle));
-
-  // Abort if the request is cancelled.
-  if (!GetPendingRequestInfo(request_id))
-    return;
-
-  // Call OnComplete now too, as it won't get called on the client.
-  // TODO(kinuko): Fill this properly.
-  network::URLLoaderCompletionStatus status;
-  status.error_code = net::OK;
-  status.exists_in_cache = false;
-  status.completion_time = base::TimeTicks::Now();
-  status.encoded_data_length = -1;
-  status.encoded_body_length = -1;
-  status.decoded_body_length = -1;
-  client_ptr->OnComplete(status);
+  client_ptr->Bind(std::move(url_loader_client_endpoints));
 }
 
 // static
diff --git a/content/renderer/loader/resource_dispatcher.h b/content/renderer/loader/resource_dispatcher.h
index 0313783..c0f96e9 100644
--- a/content/renderer/loader/resource_dispatcher.h
+++ b/content/renderer/loader/resource_dispatcher.h
@@ -122,7 +122,7 @@
       blink::WebURLRequest::LoadingIPCType ipc_type,
       mojom::URLLoaderFactory* url_loader_factory,
       std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
-      mojo::ScopedDataPipeConsumerHandle consumer_handle);
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
 
   // Removes a request from the |pending_requests_| list, returning true if the
   // request was found and removed.
@@ -267,7 +267,7 @@
 
   void ContinueForNavigation(
       int request_id,
-      mojo::ScopedDataPipeConsumerHandle consumer_handle);
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
 
   // Returns true if the message passed in is a resource related message.
   static bool IsResourceDispatcherMessage(const IPC::Message& message);
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc
index 92ec9721..c85306e9 100644
--- a/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -86,7 +86,8 @@
     }
 
     ResourceHostMsg_RequestResource::Param params;
-    if (ResourceHostMsg_RequestResource::ID != message_queue_[0].type() ||
+    if (static_cast<uint32_t>(ResourceHostMsg_RequestResource::ID) !=
+            message_queue_[0].type() ||
         !ResourceHostMsg_RequestResource::Read(&message_queue_[0], &params)) {
       ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
       return -1;
@@ -100,7 +101,8 @@
   void ConsumeFollowRedirect(int expected_request_id) {
     ASSERT_FALSE(message_queue_.empty());
     std::tuple<int> args;
-    ASSERT_EQ(ResourceHostMsg_FollowRedirect::ID, message_queue_[0].type());
+    ASSERT_EQ(static_cast<uint32_t>(ResourceHostMsg_FollowRedirect::ID),
+              message_queue_[0].type());
     ASSERT_TRUE(ResourceHostMsg_FollowRedirect::Read(
         &message_queue_[0], &args));
     EXPECT_EQ(expected_request_id, std::get<0>(args));
@@ -110,7 +112,8 @@
   void ConsumeDataReceived_ACK(int expected_request_id) {
     ASSERT_FALSE(message_queue_.empty());
     std::tuple<int> args;
-    ASSERT_EQ(ResourceHostMsg_DataReceived_ACK::ID, message_queue_[0].type());
+    ASSERT_EQ(static_cast<uint32_t>(ResourceHostMsg_DataReceived_ACK::ID),
+              message_queue_[0].type());
     ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
         &message_queue_[0], &args));
     EXPECT_EQ(expected_request_id, std::get<0>(args));
@@ -120,7 +123,7 @@
   void ConsumeReleaseDownloadedFile(int expected_request_id) {
     ASSERT_FALSE(message_queue_.empty());
     std::tuple<int> args;
-    ASSERT_EQ(ResourceHostMsg_ReleaseDownloadedFile::ID,
+    ASSERT_EQ(static_cast<uint32_t>(ResourceHostMsg_ReleaseDownloadedFile::ID),
               message_queue_[0].type());
     ASSERT_TRUE(ResourceHostMsg_ReleaseDownloadedFile::Read(
         &message_queue_[0], &args));
@@ -131,7 +134,8 @@
   void ConsumeCancelRequest(int expected_request_id) {
     ASSERT_FALSE(message_queue_.empty());
     std::tuple<int> args;
-    ASSERT_EQ(ResourceHostMsg_CancelRequest::ID, message_queue_[0].type());
+    ASSERT_EQ(static_cast<uint32_t>(ResourceHostMsg_CancelRequest::ID),
+              message_queue_[0].type());
     ASSERT_TRUE(ResourceHostMsg_CancelRequest::Read(
         &message_queue_[0], &args));
     EXPECT_EQ(expected_request_id, std::get<0>(args));
@@ -233,7 +237,7 @@
         TRAFFIC_ANNOTATION_FOR_TESTS, false, std::move(peer),
         blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr,
         std::vector<std::unique_ptr<URLLoaderThrottle>>(),
-        mojo::ScopedDataPipeConsumerHandle());
+        mojom::URLLoaderClientEndpointsPtr());
     peer_context->request_id = request_id;
     return request_id;
   }
diff --git a/content/renderer/loader/sync_load_context.cc b/content/renderer/loader/sync_load_context.cc
index b367bda..898e358d 100644
--- a/content/renderer/loader/sync_load_context.cc
+++ b/content/renderer/loader/sync_load_context.cc
@@ -34,7 +34,7 @@
       true /* is_sync */, base::WrapUnique(context),
       blink::WebURLRequest::LoadingIPCType::kMojo,
       context->url_loader_factory_.get(), std::move(throttles),
-      mojo::ScopedDataPipeConsumerHandle());
+      mojom::URLLoaderClientEndpointsPtr());
 }
 
 SyncLoadContext::SyncLoadContext(
diff --git a/content/renderer/loader/url_loader_client_impl.cc b/content/renderer/loader/url_loader_client_impl.cc
index 885b798..a38faf48 100644
--- a/content/renderer/loader/url_loader_client_impl.cc
+++ b/content/renderer/loader/url_loader_client_impl.cc
@@ -20,6 +20,7 @@
     : request_id_(request_id),
       resource_dispatcher_(resource_dispatcher),
       task_runner_(std::move(task_runner)),
+      url_loader_client_binding_(this),
       weak_factory_(this) {}
 
 URLLoaderClientImpl::~URLLoaderClientImpl() {
@@ -103,6 +104,13 @@
   }
 }
 
+void URLLoaderClientImpl::Bind(mojom::URLLoaderClientEndpointsPtr endpoints) {
+  url_loader_.Bind(std::move(endpoints->url_loader));
+  url_loader_client_binding_.Bind(std::move(endpoints->url_loader_client));
+  url_loader_client_binding_.set_connection_error_handler(base::BindOnce(
+      &URLLoaderClientImpl::OnConnectionClosed, weak_factory_.GetWeakPtr()));
+}
+
 void URLLoaderClientImpl::OnReceiveResponse(
     const ResourceResponseHead& response_head,
     const base::Optional<net::SSLInfo>& ssl_info,
@@ -175,6 +183,7 @@
 
 void URLLoaderClientImpl::OnComplete(
     const network::URLLoaderCompletionStatus& status) {
+  has_received_complete_ = true;
   if (!body_consumer_) {
     if (NeedsStoringMessage()) {
       StoreAndDispatch(ResourceMsg_RequestComplete(request_id_, status));
@@ -216,4 +225,12 @@
   std::move(ack_callback).Run();
 }
 
+void URLLoaderClientImpl::OnConnectionClosed() {
+  // If the connection aborts before the load completes, mark it as aborted.
+  if (!has_received_complete_) {
+    OnComplete(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+    return;
+  }
+}
+
 }  // namespace content
diff --git a/content/renderer/loader/url_loader_client_impl.h b/content/renderer/loader/url_loader_client_impl.h
index e474354..7497bbe 100644
--- a/content/renderer/loader/url_loader_client_impl.h
+++ b/content/renderer/loader/url_loader_client_impl.h
@@ -13,6 +13,7 @@
 #include "content/common/content_export.h"
 #include "content/public/common/url_loader.mojom.h"
 #include "ipc/ipc_message.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 
 namespace base {
@@ -49,6 +50,14 @@
   // Disaptches the messages received after SetDefersLoading is called.
   void FlushDeferredMessages();
 
+  // Binds this instance to the given URLLoaderClient endpoints so that it can
+  // start getting the mojo calls from the given loader. This is used only for
+  // the main resource loading when NavigationMojoResponse and/or NetworkService
+  // is enabled. Otherwise (in regular subresource loading cases) |this| is not
+  // bound to a client request, but used via ThrottlingURLLoader to get client
+  // upcalls from the loader.
+  void Bind(mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
+
   // mojom::URLLoaderClient implementation
   void OnReceiveResponse(const ResourceResponseHead& response_head,
                          const base::Optional<net::SSLInfo>& ssl_info,
@@ -68,16 +77,23 @@
  private:
   bool NeedsStoringMessage() const;
   void StoreAndDispatch(const IPC::Message& message);
+  void OnConnectionClosed();
 
   scoped_refptr<URLResponseBodyConsumer> body_consumer_;
   mojom::DownloadedTempFilePtr downloaded_file_;
   std::vector<IPC::Message> deferred_messages_;
   const int request_id_;
   bool has_received_response_ = false;
+  bool has_received_complete_ = false;
   bool is_deferred_ = false;
   int32_t accumulated_transfer_size_diff_during_deferred_ = 0;
   ResourceDispatcher* const resource_dispatcher_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+  // Used in NavigationMojoResponse and NetworkService.
+  mojom::URLLoaderPtr url_loader_;
+  mojo::Binding<mojom::URLLoaderClient> url_loader_client_binding_;
+
   base::WeakPtrFactory<URLLoaderClientImpl> weak_factory_;
 };
 
diff --git a/content/renderer/loader/url_loader_client_impl_unittest.cc b/content/renderer/loader/url_loader_client_impl_unittest.cc
index 572a0cf..9bb5741 100644
--- a/content/renderer/loader/url_loader_client_impl_unittest.cc
+++ b/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -37,7 +37,7 @@
         blink::WebURLRequest::LoadingIPCType::kMojo,
         url_loader_factory_proxy_.get(),
         std::vector<std::unique_ptr<URLLoaderThrottle>>(),
-        mojo::ScopedDataPipeConsumerHandle());
+        mojom::URLLoaderClientEndpointsPtr());
     request_peer_context_.request_id = request_id_;
 
     base::RunLoop().RunUntilIdle();
diff --git a/content/renderer/loader/url_response_body_consumer_unittest.cc b/content/renderer/loader/url_response_body_consumer_unittest.cc
index 3b26571..302789c 100644
--- a/content/renderer/loader/url_response_body_consumer_unittest.cc
+++ b/content/renderer/loader/url_response_body_consumer_unittest.cc
@@ -139,7 +139,7 @@
         std::make_unique<TestRequestPeer>(context, message_loop_.task_runner()),
         blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr,
         std::vector<std::unique_ptr<URLLoaderThrottle>>(),
-        mojo::ScopedDataPipeConsumerHandle());
+        mojom::URLLoaderClientEndpointsPtr());
   }
 
   void Run(TestRequestPeer::Context* context) {
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index 4d6f3aa8..e0978bc 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -655,16 +655,18 @@
   resource_request->previews_state =
       static_cast<PreviewsState>(request.GetPreviewsState());
 
-  // PlzNavigate: during navigation, the renderer should request a stream which
-  // contains the body of the response. The network request has already been
-  // made by the browser.
-  mojo::ScopedDataPipeConsumerHandle consumer_handle;
+  // PlzNavigate: The network request has already been made by the browser.
+  // The renderer should request a stream which contains the body of the
+  // response. If the Network Service or NavigationMojoResponse is enabled, the
+  // URLLoaderClientEndpoints is used instead to get the body.
+  mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
   if (stream_override_) {
     CHECK(IsBrowserSideNavigationEnabled());
     DCHECK(!sync_load_response);
     DCHECK_NE(WebURLRequest::kFrameTypeNone, request.GetFrameType());
-    if (stream_override_->consumer_handle.is_valid()) {
-      consumer_handle = std::move(stream_override_->consumer_handle);
+    if (stream_override_->url_loader_client_endpoints) {
+      url_loader_client_endpoints =
+          std::move(stream_override_->url_loader_client_endpoints);
     } else {
       resource_request->resource_body_stream_url = stream_override_->stream_url;
     }
@@ -697,7 +699,8 @@
       false /* is_sync */,
       std::make_unique<WebURLLoaderImpl::RequestPeerImpl>(this),
       request.GetLoadingIPCType(), url_loader_factory_,
-      extra_data->TakeURLLoaderThrottles(), std::move(consumer_handle));
+      extra_data->TakeURLLoaderThrottles(),
+      std::move(url_loader_client_endpoints));
 
   if (defers_loading_ != NOT_DEFERRING)
     resource_dispatcher_->SetDefersLoading(request_id_, true);
diff --git a/content/renderer/loader/web_url_loader_impl.h b/content/renderer/loader/web_url_loader_impl.h
index 2d19fe09..3c049d6 100644
--- a/content/renderer/loader/web_url_loader_impl.h
+++ b/content/renderer/loader/web_url_loader_impl.h
@@ -13,6 +13,7 @@
 #include "content/common/content_export.h"
 #include "content/common/frame.mojom.h"
 #include "content/public/common/resource_response.h"
+#include "content/public/common/url_loader.mojom.h"
 #include "content/public/common/url_loader_factory.mojom.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/url_request/redirect_info.h"
@@ -37,7 +38,7 @@
   ~StreamOverrideParameters();
 
   GURL stream_url;
-  mojo::ScopedDataPipeConsumerHandle consumer_handle;
+  mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
   ResourceResponseHead response;
   std::vector<GURL> redirects;
   std::vector<ResourceResponseInfo> redirect_responses;
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc
index 5b096cf..70d6f3e0 100644
--- a/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -91,7 +91,7 @@
       blink::WebURLRequest::LoadingIPCType ipc_type,
       mojom::URLLoaderFactory* url_loader_factory,
       std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
-      mojo::ScopedDataPipeConsumerHandle consumer_handle) override {
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints) override {
     EXPECT_FALSE(peer_);
     if (sync_load_response_.encoded_body_length != -1)
       EXPECT_TRUE(is_sync);
diff --git a/content/renderer/media/peer_connection_tracker_unittest.cc b/content/renderer/media/peer_connection_tracker_unittest.cc
index eda293f..da3b215 100644
--- a/content/renderer/media/peer_connection_tracker_unittest.cc
+++ b/content/renderer/media/peer_connection_tracker_unittest.cc
@@ -46,7 +46,9 @@
 class MockPeerConnectionHandler : public RTCPeerConnectionHandler {
  public:
   MockPeerConnectionHandler()
-      : RTCPeerConnectionHandler(&client_, &dependency_factory_) {}
+      : RTCPeerConnectionHandler(&client_,
+                                 &dependency_factory_,
+                                 base::ThreadTaskRunnerHandle::Get()) {}
   MOCK_METHOD0(CloseClientPeerConnection, void());
 
  private:
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
index c51b2386..857d739 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -538,9 +538,9 @@
 // GetStats into a blink::WebRTCStatsCallback.
 class StatsResponse : public webrtc::StatsObserver {
  public:
-  explicit StatsResponse(const scoped_refptr<LocalRTCStatsRequest>& request)
-      : request_(request.get()),
-        main_thread_(base::ThreadTaskRunnerHandle::Get()) {
+  StatsResponse(const scoped_refptr<LocalRTCStatsRequest>& request,
+                scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+      : request_(request.get()), main_thread_(task_runner) {
     // Measure the overall time it takes to satisfy a getStats request.
     TRACE_EVENT_ASYNC_BEGIN0("webrtc", "getStats_Native", this);
     signaling_thread_checker_.DetachFromThread();
@@ -983,9 +983,10 @@
   WebRtcSetRemoteDescriptionObserverImpl(
       base::WeakPtr<RTCPeerConnectionHandler> handler,
       blink::WebRTCVoidRequest web_request,
-      base::WeakPtr<PeerConnectionTracker> tracker)
+      base::WeakPtr<PeerConnectionTracker> tracker,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
       : handler_(handler),
-        main_thread_(base::ThreadTaskRunnerHandle::Get()),
+        main_thread_(task_runner),
         web_request_(web_request),
         tracker_(tracker) {}
 
@@ -1146,8 +1147,9 @@
       public PeerConnectionObserver,
       public RtcEventLogOutputSink {
  public:
-  Observer(const base::WeakPtr<RTCPeerConnectionHandler>& handler)
-      : handler_(handler), main_thread_(base::ThreadTaskRunnerHandle::Get()) {}
+  Observer(const base::WeakPtr<RTCPeerConnectionHandler>& handler,
+           scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+      : handler_(handler), main_thread_(task_runner) {}
 
   // When an RTC event log is sent back from PeerConnection, it arrives here.
   void OnWebRtcEventLogWrite(const std::string& output) override {
@@ -1268,7 +1270,8 @@
 
 RTCPeerConnectionHandler::RTCPeerConnectionHandler(
     blink::WebRTCPeerConnectionHandlerClient* client,
-    PeerConnectionDependencyFactory* dependency_factory)
+    PeerConnectionDependencyFactory* dependency_factory,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
     : initialize_called_(false),
       client_(client),
       is_closed_(false),
@@ -1277,6 +1280,7 @@
           new WebRtcMediaStreamTrackAdapterMap(dependency_factory_)),
       stream_adapter_map_(new WebRtcMediaStreamAdapterMap(dependency_factory_,
                                                           track_adapter_map_)),
+      task_runner_(task_runner),
       weak_factory_(this) {
   CHECK(client_);
   GetPeerConnectionHandlers()->insert(this);
@@ -1334,7 +1338,8 @@
   // Copy all the relevant constraints into |config|.
   CopyConstraintsIntoRtcConfiguration(options, &configuration_);
 
-  peer_connection_observer_ = new Observer(weak_factory_.GetWeakPtr());
+  peer_connection_observer_ =
+      new Observer(weak_factory_.GetWeakPtr(), task_runner_);
   native_peer_connection_ = dependency_factory_->CreatePeerConnection(
       configuration_, frame_, peer_connection_observer_.get());
 
@@ -1364,7 +1369,8 @@
 
   GetNativeRtcConfiguration(server_configuration, &configuration_);
 
-  peer_connection_observer_ = new Observer(weak_factory_.GetWeakPtr());
+  peer_connection_observer_ =
+      new Observer(weak_factory_.GetWeakPtr(), task_runner_);
   CopyConstraintsIntoRtcConfiguration(options, &configuration_);
 
   native_peer_connection_ = dependency_factory_->CreatePeerConnection(
@@ -1385,8 +1391,8 @@
 
   scoped_refptr<CreateSessionDescriptionRequest> description_request(
       new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
-          base::ThreadTaskRunnerHandle::Get(), request,
-          weak_factory_.GetWeakPtr(), peer_connection_tracker_,
+          task_runner_, request, weak_factory_.GetWeakPtr(),
+          peer_connection_tracker_,
           PeerConnectionTracker::ACTION_CREATE_OFFER));
 
   // TODO(tommi): Do this asynchronously via e.g. PostTaskAndReply.
@@ -1407,8 +1413,8 @@
 
   scoped_refptr<CreateSessionDescriptionRequest> description_request(
       new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
-          base::ThreadTaskRunnerHandle::Get(), request,
-          weak_factory_.GetWeakPtr(), peer_connection_tracker_,
+          task_runner_, request, weak_factory_.GetWeakPtr(),
+          peer_connection_tracker_,
           PeerConnectionTracker::ACTION_CREATE_OFFER));
 
   // TODO(tommi): Do this asynchronously via e.g. PostTaskAndReply.
@@ -1428,8 +1434,8 @@
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createAnswer");
   scoped_refptr<CreateSessionDescriptionRequest> description_request(
       new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
-          base::ThreadTaskRunnerHandle::Get(), request,
-          weak_factory_.GetWeakPtr(), peer_connection_tracker_,
+          task_runner_, request, weak_factory_.GetWeakPtr(),
+          peer_connection_tracker_,
           PeerConnectionTracker::ACTION_CREATE_ANSWER));
   webrtc::PeerConnectionInterface::RTCOfferAnswerOptions webrtc_options;
   ConvertConstraintsToWebrtcOfferOptions(options, &webrtc_options);
@@ -1448,8 +1454,8 @@
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createAnswer");
   scoped_refptr<CreateSessionDescriptionRequest> description_request(
       new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
-          base::ThreadTaskRunnerHandle::Get(), request,
-          weak_factory_.GetWeakPtr(), peer_connection_tracker_,
+          task_runner_, request, weak_factory_.GetWeakPtr(),
+          peer_connection_tracker_,
           PeerConnectionTracker::ACTION_CREATE_ANSWER));
   // TODO(tommi): Do this asynchronously via e.g. PostTaskAndReply.
   webrtc::PeerConnectionInterface::RTCOfferAnswerOptions webrtc_options;
@@ -1511,8 +1517,8 @@
 
   scoped_refptr<SetLocalDescriptionRequest> set_request(
       new rtc::RefCountedObject<SetLocalDescriptionRequest>(
-          base::ThreadTaskRunnerHandle::Get(), request,
-          weak_factory_.GetWeakPtr(), peer_connection_tracker_,
+          task_runner_, request, weak_factory_.GetWeakPtr(),
+          peer_connection_tracker_,
           PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
 
   signaling_thread()->PostTask(
@@ -1570,13 +1576,13 @@
 
   scoped_refptr<WebRtcSetRemoteDescriptionObserverImpl> content_observer(
       new WebRtcSetRemoteDescriptionObserverImpl(
-          weak_factory_.GetWeakPtr(), request, peer_connection_tracker_));
+          weak_factory_.GetWeakPtr(), request, peer_connection_tracker_,
+          task_runner_));
 
   rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>
       webrtc_observer(WebRtcSetRemoteDescriptionObserverHandler::Create(
-                          base::ThreadTaskRunnerHandle::Get(),
-                          native_peer_connection_, stream_adapter_map_,
-                          content_observer)
+                          task_runner_, native_peer_connection_,
+                          stream_adapter_map_, content_observer)
                           .get());
 
   signaling_thread()->PostTask(
@@ -1664,7 +1670,7 @@
   // TODO(tommi): Instead of calling addICECandidate here, we can do a
   // PostTaskAndReply kind of a thing.
   bool result = AddICECandidate(std::move(candidate));
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
+  task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&RTCPeerConnectionHandler::OnaddICECandidateResult,
                      weak_factory_.GetWeakPtr(), request, result));
@@ -1796,9 +1802,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::getStats");
 
-
   rtc::scoped_refptr<webrtc::StatsObserver> observer(
-      new rtc::RefCountedObject<StatsResponse>(request));
+      new rtc::RefCountedObject<StatsResponse>(request, task_runner_));
 
   std::string track_id;
   blink::WebMediaStreamSource::Type track_type =
@@ -1833,8 +1838,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   signaling_thread()->PostTask(
       FROM_HERE,
-      base::BindOnce(&GetRTCStatsOnSignalingThread,
-                     base::ThreadTaskRunnerHandle::Get(),
+      base::BindOnce(&GetRTCStatsOnSignalingThread, task_runner_,
                      native_peer_connection_, base::Passed(&callback)));
 }
 
@@ -2003,8 +2007,7 @@
 
   ++num_data_channels_created_;
 
-  return new RtcDataChannelHandler(base::ThreadTaskRunnerHandle::Get(),
-                                   webrtc_channel);
+  return new RtcDataChannelHandler(task_runner_, webrtc_channel);
 }
 
 blink::WebRTCDTMFSenderHandler* RTCPeerConnectionHandler::CreateDTMFSender(
diff --git a/content/renderer/media/rtc_peer_connection_handler.h b/content/renderer/media/rtc_peer_connection_handler.h
index 9b17862..f60db06 100644
--- a/content/renderer/media/rtc_peer_connection_handler.h
+++ b/content/renderer/media/rtc_peer_connection_handler.h
@@ -95,7 +95,8 @@
  public:
   RTCPeerConnectionHandler(
       blink::WebRTCPeerConnectionHandlerClient* client,
-      PeerConnectionDependencyFactory* dependency_factory);
+      PeerConnectionDependencyFactory* dependency_factory,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
   ~RTCPeerConnectionHandler() override;
 
   // Destroy all existing RTCPeerConnectionHandler objects.
@@ -361,6 +362,8 @@
   // Track which ICE Connection state that this PeerConnection has gone through.
   bool ice_state_seen_[webrtc::PeerConnectionInterface::kIceConnectionMax] = {};
 
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
   base::WeakPtrFactory<RTCPeerConnectionHandler> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(RTCPeerConnectionHandler);
diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index b7362c4e..ac7705dd 100644
--- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -245,8 +245,9 @@
   RTCPeerConnectionHandlerUnderTest(
       WebRTCPeerConnectionHandlerClient* client,
       PeerConnectionDependencyFactory* dependency_factory)
-      : RTCPeerConnectionHandler(client, dependency_factory) {
-  }
+      : RTCPeerConnectionHandler(client,
+                                 dependency_factory,
+                                 base::ThreadTaskRunnerHandle::Get()) {}
 
   MockPeerConnectionImpl* native_peer_connection() {
     return static_cast<MockPeerConnectionImpl*>(
diff --git a/content/renderer/media/user_media_client_impl.cc b/content/renderer/media/user_media_client_impl.cc
index 47c3cca..7a573dd 100644
--- a/content/renderer/media/user_media_client_impl.cc
+++ b/content/renderer/media/user_media_client_impl.cc
@@ -24,7 +24,6 @@
 #include "content/renderer/render_thread_impl.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
-#include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -34,21 +33,6 @@
 namespace content {
 namespace {
 
-blink::WebMediaDeviceInfo::MediaDeviceKind ToMediaDeviceKind(
-    MediaDeviceType type) {
-  switch (type) {
-    case MEDIA_DEVICE_TYPE_AUDIO_INPUT:
-      return blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput;
-    case MEDIA_DEVICE_TYPE_VIDEO_INPUT:
-      return blink::WebMediaDeviceInfo::kMediaDeviceKindVideoInput;
-    case MEDIA_DEVICE_TYPE_AUDIO_OUTPUT:
-      return blink::WebMediaDeviceInfo::kMediaDeviceKindAudioOutput;
-    default:
-      NOTREACHED();
-      return blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput;
-  }
-}
-
 static int g_next_request_id = 0;
 
 }  // namespace
@@ -275,16 +259,6 @@
   }
 }
 
-void UserMediaClientImpl::RequestMediaDevices(
-    const blink::WebMediaDevicesRequest& media_devices_request) {
-  UpdateWebRTCMethodCount(WEBKIT_GET_MEDIA_DEVICES);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  GetMediaDevicesDispatcher()->EnumerateDevices(
-      true /* audio input */, true /* video input */, true /* audio output */,
-      base::BindOnce(&UserMediaClientImpl::FinalizeEnumerateDevices,
-                     weak_factory_.GetWeakPtr(), media_devices_request));
-}
-
 void UserMediaClientImpl::SetMediaDeviceChangeObserver(
     const blink::WebMediaDeviceChangeObserver& observer) {
   media_device_change_observer_ = observer;
@@ -309,30 +283,6 @@
   }
 }
 
-void UserMediaClientImpl::FinalizeEnumerateDevices(
-    blink::WebMediaDevicesRequest request,
-    const EnumerationResult& result) {
-  DCHECK_EQ(static_cast<size_t>(NUM_MEDIA_DEVICE_TYPES), result.size());
-
-  blink::WebVector<blink::WebMediaDeviceInfo> devices(
-      result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size() +
-      result[MEDIA_DEVICE_TYPE_VIDEO_INPUT].size() +
-      result[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT].size());
-  size_t index = 0;
-  for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
-    blink::WebMediaDeviceInfo::MediaDeviceKind device_kind =
-        ToMediaDeviceKind(static_cast<MediaDeviceType>(i));
-    for (const auto& device_info : result[i]) {
-      devices[index++].Initialize(
-          blink::WebString::FromUTF8(device_info.device_id), device_kind,
-          blink::WebString::FromUTF8(device_info.label),
-          blink::WebString::FromUTF8(device_info.group_id));
-    }
-  }
-
-  EnumerateDevicesSucceded(&request, devices);
-}
-
 void UserMediaClientImpl::DevicesChanged(
     MediaDeviceType type,
     const MediaDeviceInfoArray& device_infos) {
@@ -340,12 +290,6 @@
     media_device_change_observer_.DidChangeMediaDevices();
 }
 
-void UserMediaClientImpl::EnumerateDevicesSucceded(
-    blink::WebMediaDevicesRequest* request,
-    blink::WebVector<blink::WebMediaDeviceInfo>& devices) {
-  request->RequestSucceeded(devices);
-}
-
 void UserMediaClientImpl::DeleteAllUserMediaRequests() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   user_media_processor_->StopAllProcessing();
diff --git a/content/renderer/media/user_media_client_impl.h b/content/renderer/media/user_media_client_impl.h
index e88d4e7..2520cb6 100644
--- a/content/renderer/media/user_media_client_impl.h
+++ b/content/renderer/media/user_media_client_impl.h
@@ -22,7 +22,6 @@
 #include "third_party/WebKit/public/platform/modules/mediastream/media_devices.mojom.h"
 #include "third_party/WebKit/public/web/WebApplyConstraintsRequest.h"
 #include "third_party/WebKit/public/web/WebMediaDeviceChangeObserver.h"
-#include "third_party/WebKit/public/web/WebMediaDevicesRequest.h"
 #include "third_party/WebKit/public/web/WebUserMediaClient.h"
 #include "third_party/WebKit/public/web/WebUserMediaRequest.h"
 
@@ -58,8 +57,6 @@
   void RequestUserMedia(const blink::WebUserMediaRequest& web_request) override;
   void CancelUserMediaRequest(
       const blink::WebUserMediaRequest& web_request) override;
-  void RequestMediaDevices(
-      const blink::WebMediaDevicesRequest& media_devices_request) override;
   void SetMediaDeviceChangeObserver(
       const blink::WebMediaDeviceChangeObserver& observer) override;
   void ApplyConstraints(
@@ -72,14 +69,6 @@
   void SetMediaDevicesDispatcherForTesting(
       blink::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher);
 
- protected:
-  // This method is virtual for test purposes. A test can override it to
-  // test requesting local media streams. The function notifies Blink that the
-  // |request| has completed.
-  virtual void EnumerateDevicesSucceded(
-      blink::WebMediaDevicesRequest* request,
-      blink::WebVector<blink::WebMediaDeviceInfo>& devices);
-
  private:
   class Request {
    public:
@@ -122,10 +111,6 @@
   // RenderFrameObserver implementation.
   void OnDestruct() override;
 
-  using EnumerationResult = std::vector<MediaDeviceInfoArray>;
-  void FinalizeEnumerateDevices(blink::WebMediaDevicesRequest request,
-                                const EnumerationResult& result);
-
   // Callback invoked by MediaDevicesEventDispatcher when a device-change
   // notification arrives.
   void DevicesChanged(MediaDeviceType device_type,
diff --git a/content/renderer/media/user_media_client_impl_unittest.cc b/content/renderer/media/user_media_client_impl_unittest.cc
index e19b252..3057fd4 100644
--- a/content/renderer/media/user_media_client_impl_unittest.cc
+++ b/content/renderer/media/user_media_client_impl_unittest.cc
@@ -18,6 +18,7 @@
 #include "content/common/media/media_devices.h"
 #include "content/renderer/media/media_stream_audio_processor_options.h"
 #include "content/renderer/media/media_stream_audio_source.h"
+#include "content/renderer/media/media_stream_audio_track.h"
 #include "content/renderer/media/media_stream_constraints_util.h"
 #include "content/renderer/media/media_stream_constraints_util_video_content.h"
 #include "content/renderer/media/media_stream_device_observer.h"
@@ -29,7 +30,6 @@
 #include "media/audio/audio_device_description.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h"
 #include "third_party/WebKit/public/platform/WebMediaStream.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
@@ -427,26 +427,8 @@
     RequestUserMediaForTest(user_media_request);
   }
 
-  void RequestMediaDevicesForTest() {
-    blink::WebMediaDevicesRequest media_devices_request;
-    *state_ = REQUEST_NOT_COMPLETE;
-    RequestMediaDevices(media_devices_request);
-  }
-
-  void EnumerateDevicesSucceded(
-      blink::WebMediaDevicesRequest* request,
-      blink::WebVector<blink::WebMediaDeviceInfo>& devices) override {
-    *state_ = REQUEST_SUCCEEDED;
-    last_devices_ = devices;
-  }
-
-  const blink::WebVector<blink::WebMediaDeviceInfo>& last_devices() {
-    return last_devices_;
-  }
-
  private:
   RequestState* state_;
-  blink::WebVector<blink::WebMediaDeviceInfo> last_devices_;
 };
 
 }  // namespace
@@ -542,6 +524,31 @@
     return video_tracks[0];
   }
 
+  blink::WebMediaStreamTrack RequestLocalAudioTrackWithAssociatedSink(
+      bool render_to_associated_sink) {
+    MockConstraintFactory constraint_factory;
+    constraint_factory.basic().render_to_associated_sink.SetExact(
+        render_to_associated_sink);
+    blink::WebUserMediaRequest user_media_request =
+        blink::WebUserMediaRequest::CreateForTesting(
+            constraint_factory.CreateWebMediaConstraints(),
+            blink::WebMediaConstraints());
+    user_media_client_impl_->RequestUserMediaForTest(user_media_request);
+
+    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
+
+    blink::WebMediaStream desc = user_media_processor_->last_generated_stream();
+    blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
+    desc.AudioTracks(audio_tracks);
+    blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
+    desc.VideoTracks(video_tracks);
+
+    EXPECT_EQ(audio_tracks.size(), 1u);
+    EXPECT_TRUE(video_tracks.empty());
+
+    return audio_tracks[0];
+  }
+
   void StartMockedVideoSource() {
     MockMediaStreamVideoCapturerSource* video_source =
         user_media_processor_->last_created_video_source();
@@ -856,61 +863,6 @@
   EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
 }
 
-TEST_F(UserMediaClientImplTest, EnumerateMediaDevices) {
-  user_media_client_impl_->RequestMediaDevicesForTest();
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
-  EXPECT_EQ(static_cast<size_t>(5),
-            user_media_client_impl_->last_devices().size());
-
-  // Audio input device with matched output ID.
-  const blink::WebMediaDeviceInfo* device =
-      &user_media_client_impl_->last_devices()[0];
-  EXPECT_FALSE(device->DeviceId().IsEmpty());
-  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput,
-            device->Kind());
-  EXPECT_FALSE(device->Label().IsEmpty());
-  EXPECT_FALSE(device->GroupId().IsEmpty());
-
-  // Audio input device without matched output ID.
-  device = &user_media_client_impl_->last_devices()[1];
-  EXPECT_FALSE(device->DeviceId().IsEmpty());
-  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput,
-            device->Kind());
-  EXPECT_FALSE(device->Label().IsEmpty());
-  EXPECT_FALSE(device->GroupId().IsEmpty());
-
-  // Video input devices.
-  device = &user_media_client_impl_->last_devices()[2];
-  EXPECT_FALSE(device->DeviceId().IsEmpty());
-  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindVideoInput,
-            device->Kind());
-  EXPECT_FALSE(device->Label().IsEmpty());
-  EXPECT_TRUE(device->GroupId().IsEmpty());
-
-  device = &user_media_client_impl_->last_devices()[3];
-  EXPECT_FALSE(device->DeviceId().IsEmpty());
-  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindVideoInput,
-            device->Kind());
-  EXPECT_FALSE(device->Label().IsEmpty());
-  EXPECT_TRUE(device->GroupId().IsEmpty());
-
-  // Audio output device.
-  device = &user_media_client_impl_->last_devices()[4];
-  EXPECT_FALSE(device->DeviceId().IsEmpty());
-  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindAudioOutput,
-            device->Kind());
-  EXPECT_FALSE(device->Label().IsEmpty());
-  EXPECT_FALSE(device->GroupId().IsEmpty());
-
-  // Verfify group IDs.
-  EXPECT_TRUE(user_media_client_impl_->last_devices()[0].GroupId().Equals(
-      user_media_client_impl_->last_devices()[4].GroupId()));
-  EXPECT_FALSE(user_media_client_impl_->last_devices()[1].GroupId().Equals(
-      user_media_client_impl_->last_devices()[4].GroupId()));
-}
-
 TEST_F(UserMediaClientImplTest, DefaultConstraintsPropagate) {
   blink::WebUserMediaRequest request =
       blink::WebUserMediaRequest::CreateForTesting(CreateDefaultConstraints(),
@@ -1434,4 +1386,24 @@
   }
 }
 
+// These tests check that audio parameters for the associated output device are
+// set according to the renderToAssociatedSink constrainable property.
+TEST_F(UserMediaClientImplTest, RenderToAssociatedSinkTrueAudioParams) {
+  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
+  blink::WebMediaStreamTrack web_track =
+      RequestLocalAudioTrackWithAssociatedSink(true);
+  MediaStreamAudioSource* source =
+      MediaStreamAudioSource::From(web_track.Source());
+  EXPECT_TRUE(source->device().matched_output.IsValid());
+}
+
+TEST_F(UserMediaClientImplTest, RenderToAssociatedSinkFalseAudioParams) {
+  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
+  blink::WebMediaStreamTrack web_track =
+      RequestLocalAudioTrackWithAssociatedSink(false);
+  MediaStreamAudioSource* source =
+      MediaStreamAudioSource::From(web_track.Source());
+  EXPECT_FALSE(source->device().matched_output.IsValid());
+}
+
 }  // namespace content
diff --git a/content/renderer/media/user_media_processor.cc b/content/renderer/media/user_media_processor.cc
index 7faa066..cf86228 100644
--- a/content/renderer/media/user_media_processor.cc
+++ b/content/renderer/media/user_media_processor.cc
@@ -836,7 +836,9 @@
     // be removed.
     for (auto& device : overridden_audio_devices) {
       device.matched_output_device_id = "";
-      device.matched_output = media::AudioParameters::UnavailableDeviceParams();
+      // Audio parameters must be invalid in order to ensure that the matched
+      // output device will not be used.
+      device.matched_output = media::AudioParameters();
     }
   }
 
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index d8e343c..dc8f5439 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -123,13 +123,14 @@
 
 std::unique_ptr<blink::WebRTCPeerConnectionHandler>
 PeerConnectionDependencyFactory::CreateRTCPeerConnectionHandler(
-    blink::WebRTCPeerConnectionHandlerClient* client) {
+    blink::WebRTCPeerConnectionHandlerClient* client,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   // Save histogram data so we can see how much PeerConnetion is used.
   // The histogram counts the number of calls to the JS API
   // webKitRTCPeerConnection.
   UpdateWebRTCMethodCount(WEBKIT_RTC_PEER_CONNECTION);
 
-  return std::make_unique<RTCPeerConnectionHandler>(client, this);
+  return std::make_unique<RTCPeerConnectionHandler>(client, this, task_runner);
 }
 
 const scoped_refptr<webrtc::PeerConnectionFactoryInterface>&
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
index 743f1ba..13383b2 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.h
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -56,7 +56,8 @@
   // WebKit WebRTCPeerConnectionHandler interface.
   std::unique_ptr<blink::WebRTCPeerConnectionHandler>
   CreateRTCPeerConnectionHandler(
-      blink::WebRTCPeerConnectionHandlerClient* client);
+      blink::WebRTCPeerConnectionHandlerClient* client,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   // Create a proxy object for a VideoTrackSource that makes sure it's called on
   // the correct threads.
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc
index fa23cf1..e86dddd 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc
@@ -24,7 +24,8 @@
 TEST_F(PeerConnectionDependencyFactoryTest, CreateRTCPeerConnectionHandler) {
   MockWebRTCPeerConnectionHandlerClient client_jsep;
   std::unique_ptr<blink::WebRTCPeerConnectionHandler> pc_handler(
-      dependency_factory_->CreateRTCPeerConnectionHandler(&client_jsep));
+      dependency_factory_->CreateRTCPeerConnectionHandler(
+          &client_jsep, base::ThreadTaskRunnerHandle::Get()));
   EXPECT_TRUE(pc_handler.get() != nullptr);
 }
 
diff --git a/content/renderer/pepper/pepper_audio_input_host.cc b/content/renderer/pepper/pepper_audio_input_host.cc
index f25c532d..a722013f 100644
--- a/content/renderer/pepper/pepper_audio_input_host.cc
+++ b/content/renderer/pepper/pepper_audio_input_host.cc
@@ -21,14 +21,6 @@
 
 namespace content {
 
-namespace {
-
-base::PlatformFile ConvertSyncSocketHandle(const base::SyncSocket& socket) {
-  return socket.handle();
-}
-
-}  // namespace
-
 PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host,
                                            PP_Instance instance,
                                            PP_Resource resource)
@@ -164,8 +156,8 @@
     const base::SharedMemory& shared_memory,
     IPC::PlatformFileForTransit* remote_socket_handle,
     base::SharedMemoryHandle* remote_shared_memory_handle) {
-  *remote_socket_handle = renderer_ppapi_host_->ShareHandleWithRemote(
-      ConvertSyncSocketHandle(socket), false);
+  *remote_socket_handle =
+      renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false);
   if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
     return PP_ERROR_FAILED;
 
diff --git a/content/renderer/pepper/pepper_audio_output_host.cc b/content/renderer/pepper/pepper_audio_output_host.cc
index fdde5d0..6aa32bde 100644
--- a/content/renderer/pepper/pepper_audio_output_host.cc
+++ b/content/renderer/pepper/pepper_audio_output_host.cc
@@ -23,14 +23,6 @@
 
 namespace content {
 
-namespace {
-
-base::PlatformFile ConvertSyncSocketHandle(const base::SyncSocket& socket) {
-  return socket.handle();
-}
-
-}  // namespace
-
 PepperAudioOutputHost::PepperAudioOutputHost(RendererPpapiHostImpl* host,
                                              PP_Instance instance,
                                              PP_Resource resource)
@@ -205,8 +197,8 @@
     const base::SharedMemory& shared_memory,
     IPC::PlatformFileForTransit* remote_socket_handle,
     base::SharedMemoryHandle* remote_shared_memory_handle) {
-  *remote_socket_handle = renderer_ppapi_host_->ShareHandleWithRemote(
-      ConvertSyncSocketHandle(socket), false);
+  *remote_socket_handle =
+      renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false);
   if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
     return PP_ERROR_FAILED;
 
diff --git a/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc b/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
index 2475fcf..7a9dc820 100644
--- a/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
+++ b/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
@@ -65,7 +65,8 @@
   // Test that we've sent an IPC to the browser.
   ASSERT_EQ(1u, sink_->message_count());
   const IPC::Message* msg = sink_->GetMessageAt(0);
-  EXPECT_EQ(FrameHostMsg_PluginContentOriginAllowed::ID, msg->type());
+  EXPECT_EQ(static_cast<uint32_t>(FrameHostMsg_PluginContentOriginAllowed::ID),
+            msg->type());
   FrameHostMsg_PluginContentOriginAllowed::Param params;
   FrameHostMsg_PluginContentOriginAllowed::Read(msg, &params);
   EXPECT_TRUE(url::Origin::Create(GURL("http://other.com"))
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 86153593..9e7102b7 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3079,7 +3079,7 @@
     const GURL& body_url,
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
-    mojo::ScopedDataPipeConsumerHandle body_data,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     base::Optional<URLLoaderFactoryBundle> subresource_loader_factories,
     const base::UnguessableToken& devtools_navigation_token) {
   CHECK(IsBrowserSideNavigationEnabled());
@@ -3098,7 +3098,8 @@
   std::unique_ptr<StreamOverrideParameters> stream_override(
       new StreamOverrideParameters());
   stream_override->stream_url = body_url;
-  stream_override->consumer_handle = std::move(body_data);
+  stream_override->url_loader_client_endpoints =
+      std::move(url_loader_client_endpoints);
   stream_override->response = head;
   stream_override->redirects = request_params.redirects;
   stream_override->redirect_responses = request_params.redirect_response;
@@ -6730,13 +6731,12 @@
 
   blink::WebURLRequest& request = info.url_request;
 
-  // Set RequestorOrigin and SiteForCookies
+  // Set SiteForCookies.
   WebDocument frame_document = frame_->GetDocument();
   if (request.GetFrameType() == blink::WebURLRequest::kFrameTypeTopLevel)
     request.SetSiteForCookies(request.Url());
   else
     request.SetSiteForCookies(frame_document.SiteForCookies());
-  request.SetRequestorOrigin(frame_document.GetSecurityOrigin());
 
   // Note: At this stage, the goal is to apply all the modifications the
   // renderer wants to make to the request, and then send it to the browser, so
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 81d9b66b..6b2a1a7 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -521,7 +521,7 @@
       const GURL& body_url,
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
-      mojo::ScopedDataPipeConsumerHandle body_data,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       base::Optional<URLLoaderFactoryBundle> subresource_loaders,
       const base::UnguessableToken& devtools_navigation_token) override;
 
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index 6d74f5d7..09eac0f 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -537,7 +537,7 @@
           pending_resize_params_.sequence_number;
 
   if (synchronized_params_changed)
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
 
   viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
   if (enable_surface_synchronization_)
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h
index 00f88ee..c5e90a8 100644
--- a/content/renderer/render_frame_proxy.h
+++ b/content/renderer/render_frame_proxy.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "content/common/content_export.h"
 #include "content/public/common/screen_info.h"
 #include "ipc/ipc_listener.h"
@@ -276,7 +276,7 @@
 
   viz::FrameSinkId frame_sink_id_;
   viz::LocalSurfaceId local_surface_id_;
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
 
   bool enable_surface_synchronization_ = false;
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index ba46b442..4240912 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -427,14 +427,14 @@
         RenderWidgetSurfaceProperties::FromCompositorFrame(frame);
     if (!local_surface_id_.is_valid() ||
         new_surface_properties != surface_properties_) {
-      local_surface_id_ = local_surface_id_allocator_.GenerateId();
+      local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
       surface_properties_ = new_surface_properties;
     }
     return local_surface_id_;
   }
 
  private:
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
   viz::LocalSurfaceId local_surface_id_;
   RenderWidgetSurfaceProperties surface_properties_;
 };
@@ -1981,12 +1981,11 @@
   is_gpu_compositing_disabled_ = true;
 }
 
-scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync(
-    bool* connection_error) {
+scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() {
   TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");
 
   scoped_refptr<gpu::GpuChannelHost> gpu_channel =
-      gpu_->EstablishGpuChannelSync(connection_error);
+      gpu_->EstablishGpuChannelSync();
   if (gpu_channel)
     GetContentClient()->SetGpuInfo(gpu_channel->gpu_info());
   return gpu_channel;
@@ -2028,13 +2027,7 @@
       callback.Run(nullptr);
       return;
     }
-    bool connection_error = false;
-    scoped_refptr<gpu::GpuChannelHost> channel =
-        EstablishGpuChannelSync(&connection_error);
-    // If the connection to the host is gone, then don't bother running the
-    // |callback| to retry.
-    if (connection_error)
-      return;
+    scoped_refptr<gpu::GpuChannelHost> channel = EstablishGpuChannelSync();
     // If the channel could not be established correctly, then return null. This
     // would cause the compositor to wait and try again at a later time.
     if (!channel) {
@@ -2077,13 +2070,8 @@
     return;
   }
 
-  bool connection_error = false;
   scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
-      EstablishGpuChannelSync(&connection_error);
-  // If the connection to the host is gone, then don't bother running the
-  // |callback| to retry.
-  if (connection_error)
-    return;
+      EstablishGpuChannelSync();
   if (!gpu_channel_host) {
     // Wait and try again. We may hear that the compositing mode has switched
     // to software in the meantime.
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index fbc4ef2..2ac1ecf 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -282,12 +282,8 @@
   // Synchronously establish a channel to the GPU plugin if not previously
   // established or if it has been lost (for example if the GPU plugin crashed).
   // If there is a pending asynchronous request, it will be completed by the
-  // time this routine returns. If |connection_error| is set to true, it was
-  // unable to connect to the host process to try establish a channel, which
-  // should mean that the host is shutting this process down and there's no
-  // reason to retry.
-  scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync(
-      bool* connection_error = nullptr);
+  // time this routine returns.
+  scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync();
 
   gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager();
 
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index f02e349..f135a88 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -1162,7 +1162,8 @@
     view()->UpdateTextInputState();
     const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
     EXPECT_TRUE(msg != nullptr);
-    EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewHostMsg_TextInputStateChanged::ID),
+              msg->type());
     ViewHostMsg_TextInputStateChanged::Param params;
     ViewHostMsg_TextInputStateChanged::Read(msg, &params);
     TextInputState p = std::get<0>(params);
@@ -1183,7 +1184,8 @@
     view()->UpdateTextInputState();
     msg = render_thread_->sink().GetMessageAt(0);
     EXPECT_TRUE(msg != nullptr);
-    EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
+    EXPECT_EQ(static_cast<uint32_t>(ViewHostMsg_TextInputStateChanged::ID),
+              msg->type());
     ViewHostMsg_TextInputStateChanged::Read(msg, &params);
     p = std::get<0>(params);
     type = p.type;
@@ -1208,7 +1210,8 @@
       base::RunLoop().RunUntilIdle();
       const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
       EXPECT_TRUE(msg != nullptr);
-      EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
+      EXPECT_EQ(static_cast<uint32_t>(ViewHostMsg_TextInputStateChanged::ID),
+                msg->type());
       ViewHostMsg_TextInputStateChanged::Read(msg, &params);
       p = std::get<0>(params);
       type = p.type;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 8873a2b..e17152c 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -917,7 +917,8 @@
 
 std::unique_ptr<WebRTCPeerConnectionHandler>
 RendererBlinkPlatformImpl::CreateRTCPeerConnectionHandler(
-    WebRTCPeerConnectionHandlerClient* client) {
+    WebRTCPeerConnectionHandlerClient* client,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   RenderThreadImpl* render_thread = RenderThreadImpl::current();
   DCHECK(render_thread);
   if (!render_thread)
@@ -926,7 +927,8 @@
 #if BUILDFLAG(ENABLE_WEBRTC)
   PeerConnectionDependencyFactory* rtc_dependency_factory =
       render_thread->GetPeerConnectionDependencyFactory();
-  return rtc_dependency_factory->CreateRTCPeerConnectionHandler(client);
+  return rtc_dependency_factory->CreateRTCPeerConnectionHandler(client,
+                                                                task_runner);
 #else
   return nullptr;
 #endif  // BUILDFLAG(ENABLE_WEBRTC)
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 9f7bb41..1caf15a 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -168,7 +168,8 @@
   void SampleGamepads(device::Gamepads&) override;
   std::unique_ptr<blink::WebRTCPeerConnectionHandler>
   CreateRTCPeerConnectionHandler(
-      blink::WebRTCPeerConnectionHandlerClient* client) override;
+      blink::WebRTCPeerConnectionHandlerClient* client,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
   std::unique_ptr<blink::WebRTCCertificateGenerator>
   CreateRTCCertificateGenerator() override;
   std::unique_ptr<blink::WebMediaRecorderHandler> CreateMediaRecorderHandler()
diff --git a/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
index e5a0d661..f18bfb1 100644
--- a/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
+++ b/content/renderer/scheduler/resource_dispatch_throttler_unittest.cc
@@ -408,9 +408,12 @@
     const auto& priority_msg = *sent_messages_[i + 1];
     const auto& cancel_msg = *sent_messages_[i + 2];
 
-    EXPECT_EQ(request_msg.type(), ResourceHostMsg_RequestResource::ID);
-    EXPECT_EQ(priority_msg.type(), ResourceHostMsg_DidChangePriority::ID);
-    EXPECT_EQ(cancel_msg.type(), ResourceHostMsg_CancelRequest::ID);
+    EXPECT_EQ(request_msg.type(),
+              static_cast<uint32_t>(ResourceHostMsg_RequestResource::ID));
+    EXPECT_EQ(priority_msg.type(),
+              static_cast<uint32_t>(ResourceHostMsg_DidChangePriority::ID));
+    EXPECT_EQ(cancel_msg.type(),
+              static_cast<uint32_t>(ResourceHostMsg_CancelRequest::ID));
 
     EXPECT_EQ(GetRequestId(request_msg), GetRequestId(priority_msg));
     EXPECT_EQ(GetRequestId(request_msg) - 1, GetRequestId(cancel_msg));
diff --git a/content/renderer/service_worker/service_worker_dispatcher_unittest.cc b/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
index 384b7ad8..8be7e30 100644
--- a/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
+++ b/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
@@ -184,7 +184,8 @@
           Adopt(std::move(info->installing)));
   EXPECT_EQ(worker, existing_worker);
   ASSERT_EQ(1UL, ipc_sink()->message_count());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(0)->type());
   ipc_sink()->ClearMessages();
 
diff --git a/content/renderer/service_worker/service_worker_provider_context_unittest.cc b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
index cafcc56..3b1dd68 100644
--- a/content/renderer/service_worker/service_worker_provider_context_unittest.cc
+++ b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -234,11 +234,14 @@
   // associated registration and its versions.
   provider_context = nullptr;
   ASSERT_EQ(3UL, ipc_sink()->message_count());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(0)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(1)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(2)->type());
   // ServiceWorkerRegistrationObjectHost Mojo connection got broken.
   base::RunLoop().RunUntilIdle();
@@ -275,7 +278,8 @@
     // the controller.
     provider_context = nullptr;
     ASSERT_EQ(1UL, ipc_sink()->message_count());
-    EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+    EXPECT_EQ(static_cast<uint32_t>(
+                  ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
               ipc_sink()->GetMessageAt(0)->type());
     ipc_sink()->ClearMessages();
   }
@@ -315,7 +319,8 @@
 
     EXPECT_TRUE(client->was_set_controller_called());
     ASSERT_EQ(1UL, ipc_sink()->message_count());
-    EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+    EXPECT_EQ(static_cast<uint32_t>(
+                  ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
               ipc_sink()->GetMessageAt(0)->type());
   }
 }
@@ -385,9 +390,11 @@
   // client. See the comment on dispatchMessageEvent() of the mock).
   EXPECT_TRUE(client->was_dispatch_message_event_called());
   ASSERT_EQ(2UL, ipc_sink()->message_count());
-  EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(0)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(1)->type());
 }
 
@@ -452,11 +459,14 @@
   EXPECT_EQ(registration_id, registration->RegistrationId());
   EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
   ASSERT_EQ(3UL, ipc_sink()->message_count());
-  EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(0)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(1)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(2)->type());
 
   ipc_sink()->ClearMessages();
@@ -464,11 +474,14 @@
   // The registration dtor decrements the refcounts.
   registration = nullptr;
   ASSERT_EQ(3UL, ipc_sink()->message_count());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(0)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(1)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(2)->type());
   // The Mojo connection has been dropped.
   base::RunLoop().RunUntilIdle();
@@ -524,11 +537,14 @@
     base::RunLoop().RunUntilIdle();
     EXPECT_EQ(1, remote_registration_object_host().GetBindingCount());
     ASSERT_EQ(3UL, ipc_sink()->message_count());
-    EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+    EXPECT_EQ(static_cast<uint32_t>(
+                  ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
               ipc_sink()->GetMessageAt(0)->type());
-    EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+    EXPECT_EQ(static_cast<uint32_t>(
+                  ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
               ipc_sink()->GetMessageAt(1)->type());
-    EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+    EXPECT_EQ(static_cast<uint32_t>(
+                  ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
               ipc_sink()->GetMessageAt(2)->type());
   }
 
@@ -538,11 +554,14 @@
   registration1 = nullptr;
   registration2 = nullptr;
   ASSERT_EQ(3UL, ipc_sink()->message_count());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(0)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(1)->type());
-  EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID,
+  EXPECT_EQ(static_cast<uint32_t>(
+                ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID),
             ipc_sink()->GetMessageAt(2)->type());
   // The 1st Mojo connection has been dropped.
   base::RunLoop().RunUntilIdle();
diff --git a/content/renderer/webclipboard_impl.cc b/content/renderer/webclipboard_impl.cc
index 7b333ed6..249bce87 100644
--- a/content/renderer/webclipboard_impl.cc
+++ b/content/renderer/webclipboard_impl.cc
@@ -158,11 +158,8 @@
                              image.GetSkBitmap()))
     return;
 
-  if (!url.IsEmpty()) {
-    GURL gurl(url);
-    clipboard_.WriteBookmark(blink::mojom::ClipboardBuffer::kStandard,
-                             gurl.spec(), title.Utf16());
 #if !defined(OS_MACOSX)
+  if (!url.IsEmpty()) {
     // When writing the image, we also write the image markup so that pasting
     // into rich text editors, such as Gmail, reveals the image. We also don't
     // want to call writeText(), since some applications (WordPad) don't pick
@@ -173,8 +170,15 @@
     clipboard_.WriteHtml(blink::mojom::ClipboardBuffer::kStandard,
                          base::UTF8ToUTF16(URLToImageMarkup(url, title)),
                          GURL());
-#endif
+    // Only write a bookmark (url/title pair) if we're writing markup,
+    // otherwise web applications such as Gmail frequently prefer string
+    // content (assuming it to be markup, even if noted as text/plain) over
+    // the image, resulting in the URL being pasted. https://crbug.com/736439
+    GURL gurl(url);
+    clipboard_.WriteBookmark(blink::mojom::ClipboardBuffer::kStandard,
+                             gurl.spec(), title.Utf16());
   }
+#endif
   clipboard_.CommitWrite(blink::mojom::ClipboardBuffer::kStandard);
 }
 
diff --git a/content/renderer/webclipboard_impl_browsertest.cc b/content/renderer/webclipboard_impl_browsertest.cc
index 809765f..7d4412e 100644
--- a/content/renderer/webclipboard_impl_browsertest.cc
+++ b/content/renderer/webclipboard_impl_browsertest.cc
@@ -6,6 +6,8 @@
 
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
@@ -34,11 +36,46 @@
   focus_observer.Wait();
 
   const base::string16 expected_title = base::UTF8ToUTF16(rtf_content);
-  content::TitleWatcher title_watcher(shell()->web_contents(), expected_title);
+  TitleWatcher title_watcher(shell()->web_contents(), expected_title);
   shell()->web_contents()->Paste();
   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
 }
 
+IN_PROC_BROWSER_TEST_F(WebClipboardImplTest, ImageCopy) {
+  BrowserTestClipboardScope clipboard;
+  clipboard.SetText("");
+
+  base::string16 expected_types;
+#if !defined(OS_MACOSX)
+  // See comments in WebClipboardImpl::WriteImage for why the expected types
+  // are platform-specific.
+  expected_types = base::ASCIIToUTF16("file;image/png string;text/html");
+#else
+  expected_types = base::ASCIIToUTF16("file;image/png");
+#endif
+
+  NavigateToURL(shell(), GetTestUrl(".", "image_copy_types.html"));
+  WebContents* web_contents = shell()->web_contents();
+  FrameFocusedObserver focus_observer(web_contents->GetMainFrame());
+  focus_observer.Wait();
+
+  // Populate an iframe with an image, and wait for load to complete.
+  NavigateIframeToURL(web_contents, "copyme",
+                      GetTestUrl(".", "media/blackwhite.png"));
+
+  // Run script to copy image contents and wait for completion.
+  web_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+      base::ASCIIToUTF16("frames[0].document.execCommand('copy');"
+                         "document.title = 'copied';"));
+  TitleWatcher watcher1(web_contents, base::ASCIIToUTF16("copied"));
+  EXPECT_EQ(base::ASCIIToUTF16("copied"), watcher1.WaitAndGetTitle());
+
+  // Paste and check the types.
+  web_contents->Paste();
+  TitleWatcher watcher2(web_contents, expected_types);
+  EXPECT_EQ(expected_types, watcher2.WaitAndGetTitle());
 }
 
-} // namespace content
+}  // namespace
+
+}  // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 036c780..c1b60819 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -395,6 +395,8 @@
 
     deps += [
       "//third_party/webrtc/api:libjingle_peerconnection",
+      "//third_party/webrtc/api:libjingle_peerconnection_api",
+      "//third_party/webrtc/api:peerconnection_and_implicit_call_api",
       "//third_party/webrtc/api:rtc_stats_api",
       "//third_party/webrtc/media:rtc_media_base",
       "//third_party/webrtc/modules/video_capture",
@@ -674,6 +676,7 @@
     "../browser/accessibility/dump_accessibility_browsertest_base.h",
     "../browser/accessibility/dump_accessibility_events_browsertest.cc",
     "../browser/accessibility/dump_accessibility_tree_browsertest.cc",
+    "../browser/accessibility/fullscreen_browsertest.cc",
     "../browser/accessibility/hit_testing_browsertest.cc",
     "../browser/accessibility/site_per_process_accessibility_browsertest.cc",
     "../browser/accessibility/snapshot_ax_tree_browsertest.cc",
@@ -1845,6 +1848,8 @@
       "//third_party/libyuv",
       "//third_party/opus",
       "//third_party/webrtc/api:libjingle_peerconnection",
+      "//third_party/webrtc/api:libjingle_peerconnection_api",
+      "//third_party/webrtc/api:peerconnection_and_implicit_call_api",
       "//third_party/webrtc/api:rtc_stats_api",
       "//third_party/webrtc/api:video_frame_api",
       "//third_party/webrtc/api:video_frame_api_i420",
@@ -1884,7 +1889,9 @@
   # Screen capture unit tests.
   if (is_linux || is_mac || is_win) {
     deps += [ "//third_party/libyuv" ]
-    sources += [ "../browser/media/capture/web_contents_video_capture_device_unittest.cc" ]
+    sources += [
+      "../browser/media/capture/web_contents_video_capture_device_unittest.cc",
+    ]
     if (use_aura) {
       sources += [ "../browser/media/capture/cursor_renderer_aura_unittest.cc" ]
     }
diff --git a/content/test/data/accessibility/fullscreen/links.html b/content/test/data/accessibility/fullscreen/links.html
new file mode 100644
index 0000000..ca318b7
--- /dev/null
+++ b/content/test/data/accessibility/fullscreen/links.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<a href="/">link before target</a>
+<div id="target">
+  <button>Enter fullscreen</button>
+  <a href="/">link inside target</a>
+</div>
+<a href="/">link after target</a>
+<script>
+const target = document.getElementById('target');
+
+const button = document.querySelector('button');
+button.addEventListener('click', function() {
+  target.webkitRequestFullscreen();
+});
+
+document.onwebkitfullscreenchange = function() {
+  button.setAttribute('aria-label', 'Done');
+}
+</script>
diff --git a/content/test/data/accessibility/html/isInteresting-expected-android.txt b/content/test/data/accessibility/html/isInteresting-expected-android.txt
new file mode 100644
index 0000000..df13252a
--- /dev/null
+++ b/content/test/data/accessibility/html/isInteresting-expected-android.txt
@@ -0,0 +1,5 @@
+android.webkit.WebView focusable focused scrollable interesting
+++android.view.View role_description='heading 1' heading interesting name='A non focusable child of a control should not be interesting on Android'
+++android.view.View interesting name='Div with click handler'
+++android.widget.Button role_description='button' interesting name='I am interesting'
+++++android.view.View name='I should not be interesting'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/isInteresting.html b/content/test/data/accessibility/html/isInteresting.html
new file mode 100644
index 0000000..34637b4
--- /dev/null
+++ b/content/test/data/accessibility/html/isInteresting.html
@@ -0,0 +1,14 @@
+<!--
+@ANDROID-ALLOW:interesting
+@ANDROID-DENY:clickable
+-->
+<!DOCTYPE html>
+<html>
+<body>
+<h1>A non focusable child of a control should not be interesting on Android</h1>
+<div onclick="alert('success');">Div with click handler</div>
+<div onclick="alert('success');" aria-label= "I am interesting" role="button">
+  <p>I should not be interesting</p>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/test/data/image_copy_types.html b/content/test/data/image_copy_types.html
new file mode 100644
index 0000000..c052bcd
--- /dev/null
+++ b/content/test/data/image_copy_types.html
@@ -0,0 +1,12 @@
+<title>Waiting for paste</title>
+<body>
+<iframe id=copyme></iframe>
+<script>
+document.body.contentEditable = true;
+document.body.addEventListener('paste', event => {
+  document.title = [...event.clipboardData.items]
+    .map(item => `${item.kind};${item.type}`)
+    .sort()
+    .join(' ');
+});
+</script>
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 1fc58af..8f3bd7d 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -196,16 +196,11 @@
     self.Fail('conformance/rendering/rendering-stencil-large-viewport.html',
         ['win', 'intel', 'd3d11'], bug=782317)
 
-    self.Skip('conformance2/textures/misc/copy-texture-image.html',
-        ['win', 'intel', 'd3d11'], bug=617449)
     # Seems to cause the harness to fail immediately afterward
     self.Skip('conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html',
         ['win', 'intel', 'd3d11'], bug=648337)
     self.Flaky('deqp/functional/gles3/lifetime.html',
         ['win', 'intel', 'd3d11'], bug=620379)
-    self.Skip('deqp/functional/gles3/texturespecification/' +
-        'teximage3d_depth_pbo.html',
-        ['win', 'intel', 'd3d11'], bug=617449)
     self.Flaky('deqp/functional/gles3/textureformat/unsized_3d.html',
         ['win', 'intel', 'd3d11'], bug=614418)
 
@@ -333,6 +328,8 @@
     self.Fail('conformance/textures/image_bitmap_from_video/' +
         'tex-2d-rgb-rgb-unsigned_short_5_6_5.html',
         ['linux', 'passthrough', 'opengl', 'nvidia'], bug=766918)
+    self.Fail('deqp/functional/gles3/shaderoperator/common_functions.html',
+        ['linux', 'passthrough', 'opengl', 'nvidia'], bug=793055)
 
     # Regressions in 10.12.4.
     self.Fail('conformance2/textures/misc/tex-base-level-bug.html',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index 6698492..6f07c59 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -616,6 +616,12 @@
         bug=752291)
 
     # Nexus 5X
+    # The following two tests just started timing out randomly on the
+    # android_optional_gpu_tests_rel tryserver with no apparent cause.
+    self.Flaky('deqp/data/gles2/shaders/conversions.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
+    self.Flaky('deqp/data/gles2/shaders/swizzles.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
     # This one is causing intermittent timeouts on the device, and it
     # looks like when that happens, the next test also always times
     # out. Skip it for now until it's fixed and running reliably.
@@ -633,9 +639,21 @@
     self.Skip('conformance/glsl/misc/shader-with-non-reserved-words.html',
         ['android', ('qualcomm', 'Adreno (TM) 418'), 'no_passthrough'],
         bug=609883)
+    self.Flaky('conformance/ogles/GL/all/all_001_to_004.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
+    self.Flaky('conformance/ogles/GL/cos/cos_001_to_006.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
+    self.Flaky('conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
+    self.Flaky('conformance/textures/image_bitmap_from_video/' +
+        'tex-2d-luminance-luminance-unsigned_byte.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
     self.Flaky('conformance/textures/image_bitmap_from_video/' +
         'tex-2d-rgb-rgb-unsigned_byte.html',
         ['android', ('qualcomm', 'Adreno (TM) 418')], bug=716496)
+    self.Flaky('conformance/textures/misc/' +
+        'tex-video-using-tex-unit-non-zero.html',
+        ['android', ('qualcomm', 'Adreno (TM) 418')], bug=793050)
     self.Fail('conformance/uniforms/uniform-samplers-test.html',
         ['android', ('qualcomm', 'Adreno (TM) 418'), 'no_passthrough'],
         bug=610951)
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc
index e3c48ea..853cd74 100644
--- a/content/test/test_navigation_url_loader.cc
+++ b/content/test/test_navigation_url_loader.cc
@@ -40,9 +40,6 @@
   response_proceeded_ = true;
 }
 
-void TestNavigationURLLoader::InterceptNavigation(
-    NavigationURLLoader::NavigationInterceptionCB callback) {}
-
 void TestNavigationURLLoader::SimulateServerRedirect(const GURL& redirect_url) {
   net::RedirectInfo redirect_info;
   redirect_info.status_code = 302;
@@ -76,10 +73,10 @@
           ->GetProcess()
           ->GetID();
   GlobalRequestID global_id(child_id, ++request_id);
-  delegate_->OnResponseStarted(response, std::move(body),
-                               mojo::ScopedDataPipeConsumerHandle(),
-                               net::SSLInfo(), std::move(navigation_data),
-                               global_id, false, false, base::nullopt);
+  delegate_->OnResponseStarted(response, mojom::URLLoaderClientEndpointsPtr(),
+                               std::move(body), net::SSLInfo(),
+                               std::move(navigation_data), global_id, false,
+                               false, base::nullopt);
 }
 
 TestNavigationURLLoader::~TestNavigationURLLoader() {}
diff --git a/content/test/test_navigation_url_loader.h b/content/test/test_navigation_url_loader.h
index 741e1054..8edcdfc 100644
--- a/content/test/test_navigation_url_loader.h
+++ b/content/test/test_navigation_url_loader.h
@@ -36,7 +36,6 @@
   // NavigationURLLoader implementation.
   void FollowRedirect() override;
   void ProceedWithResponse() override;
-  void InterceptNavigation(NavigationInterceptionCB callback) override;
 
   NavigationRequestInfo* request_info() const { return request_info_.get(); }
 
diff --git a/content/test/test_navigation_url_loader_delegate.cc b/content/test/test_navigation_url_loader_delegate.cc
index cbe46b9..19311a19 100644
--- a/content/test/test_navigation_url_loader_delegate.cc
+++ b/content/test/test_navigation_url_loader_delegate.cc
@@ -44,8 +44,8 @@
 }
 
 void TestNavigationURLLoaderDelegate::ReleaseBody() {
+  url_loader_client_endpoints_ = nullptr;
   body_.reset();
-  handle_.reset();
 }
 
 void TestNavigationURLLoaderDelegate::OnRequestRedirected(
@@ -59,8 +59,8 @@
 
 void TestNavigationURLLoaderDelegate::OnResponseStarted(
     const scoped_refptr<ResourceResponse>& response,
+    mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     std::unique_ptr<StreamHandle> body,
-    mojo::ScopedDataPipeConsumerHandle consumer_handle,
     const net::SSLInfo& ssl_info,
     std::unique_ptr<NavigationData> navigation_data,
     const GlobalRequestID& request_id,
@@ -68,8 +68,8 @@
     bool is_stream,
     base::Optional<SubresourceLoaderParams> subresource_loader_params) {
   response_ = response;
+  url_loader_client_endpoints_ = std::move(url_loader_client_endpoints);
   body_ = std::move(body);
-  handle_ = std::move(consumer_handle);
   ssl_info_ = ssl_info;
   is_download_ = is_download;
   if (response_started_)
diff --git a/content/test/test_navigation_url_loader_delegate.h b/content/test/test_navigation_url_loader_delegate.h
index ae2c26d..e0a6941 100644
--- a/content/test/test_navigation_url_loader_delegate.h
+++ b/content/test/test_navigation_url_loader_delegate.h
@@ -12,7 +12,6 @@
 #include "base/optional.h"
 #include "base/time/time.h"
 #include "content/browser/loader/navigation_url_loader_delegate.h"
-#include "mojo/public/cpp/system/data_pipe.h"
 #include "net/url_request/redirect_info.h"
 
 namespace base {
@@ -58,16 +57,17 @@
   void OnRequestRedirected(
       const net::RedirectInfo& redirect_info,
       const scoped_refptr<ResourceResponse>& response) override;
-  void OnResponseStarted(const scoped_refptr<ResourceResponse>& response,
-                         std::unique_ptr<StreamHandle> body,
-                         mojo::ScopedDataPipeConsumerHandle consumer_handle,
-                         const net::SSLInfo& ssl_info,
-                         std::unique_ptr<NavigationData> navigation_data,
-                         const GlobalRequestID& request_id,
-                         bool is_download,
-                         bool is_stream,
-                         base::Optional<SubresourceLoaderParams>
-                             subresource_loader_params) override;
+  void OnResponseStarted(
+      const scoped_refptr<ResourceResponse>& response,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      std::unique_ptr<StreamHandle> body,
+      const net::SSLInfo& ssl_info,
+      std::unique_ptr<NavigationData> navigation_data,
+      const GlobalRequestID& request_id,
+      bool is_download,
+      bool is_stream,
+      base::Optional<SubresourceLoaderParams> subresource_loader_params)
+      override;
   void OnRequestFailed(bool in_cache,
                        int net_error,
                        const base::Optional<net::SSLInfo>& ssl_info) override;
@@ -76,9 +76,9 @@
  private:
   net::RedirectInfo redirect_info_;
   scoped_refptr<ResourceResponse> redirect_response_;
+  mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints_;
   scoped_refptr<ResourceResponse> response_;
   std::unique_ptr<StreamHandle> body_;
-  mojo::ScopedDataPipeConsumerHandle handle_;
   int net_error_;
   net::SSLInfo ssl_info_;
   int on_request_handled_counter_;
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc
index fe25617f..762c7ec 100644
--- a/content/test/test_render_frame.cc
+++ b/content/test/test_render_frame.cc
@@ -138,7 +138,7 @@
   // PlzNavigate
   if (IsBrowserSideNavigationEnabled()) {
     CommitNavigation(ResourceResponseHead(), GURL(), common_params,
-                     request_params, mojo::ScopedDataPipeConsumerHandle(),
+                     request_params, mojom::URLLoaderClientEndpointsPtr(),
                      URLLoaderFactoryBundle(),
                      base::UnguessableToken::Create());
   } else {
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index d34a542..4b4101d2 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -63,12 +63,13 @@
       const GURL& body_url,
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
-      mojo::ScopedDataPipeConsumerHandle body_data,
+      mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       base::Optional<URLLoaderFactoryBundle> subresource_loader_factories,
       const base::UnguessableToken& devtools_navigation_token) override {
     frame_host_->GetProcess()->set_did_frame_commit_navigation(true);
     frame_host_->GetInternalNavigationControl()->CommitNavigation(
-        head, body_url, common_params, request_params, std::move(body_data),
+        head, body_url, common_params, request_params,
+        std::move(url_loader_client_endpoints),
         std::move(subresource_loader_factories), devtools_navigation_token);
   }
 
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc
index 35fd8d35..9e97367 100644
--- a/content/test/test_render_view_host.cc
+++ b/content/test/test_render_view_host.cc
@@ -172,11 +172,6 @@
 
 #if defined(OS_MACOSX)
 
-ui::AcceleratedWidgetMac* TestRenderWidgetHostView::GetAcceleratedWidgetMac()
-    const {
-  return nullptr;
-}
-
 void TestRenderWidgetHostView::SetActive(bool active) {
   // <viettrungluu@gmail.com>: Do I need to do anything here?
 }
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h
index 2605e82..0b32221 100644
--- a/content/test/test_render_view_host.h
+++ b/content/test/test_render_view_host.h
@@ -86,7 +86,6 @@
   void SetBackgroundColor(SkColor color) override;
   SkColor background_color() const override;
 #if defined(OS_MACOSX)
-  ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const override;
   void SetActive(bool active) override;
   void ShowDefinitionForSelection() override {}
   bool SupportsSpeech() const override;
diff --git a/device/bluetooth/DEPS b/device/bluetooth/DEPS
index 02d2283a..f3ddf86 100644
--- a/device/bluetooth/DEPS
+++ b/device/bluetooth/DEPS
@@ -6,6 +6,7 @@
   "+net/base",
   "+net/log",
   "+net/socket",
+  "+net/traffic_annotation",
   "+ui/base/l10n",
   "+third_party/cros_system_api/dbus",
   "+third_party/re2",
diff --git a/device/bluetooth/bluetooth_socket_net.cc b/device/bluetooth/bluetooth_socket_net.cc
index dbccbe3..1a8ee372 100644
--- a/device/bluetooth/bluetooth_socket_net.cc
+++ b/device/bluetooth/bluetooth_socket_net.cc
@@ -20,6 +20,7 @@
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/log/net_log_source.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 
 namespace {
 
@@ -259,8 +260,10 @@
                  this,
                  request->success_callback,
                  request->error_callback);
+  // TODO(crbug.com/656607): Add proper annotation.
   int send_result =
-      tcp_socket_->Write(request->buffer.get(), request->buffer_size, callback);
+      tcp_socket_->Write(request->buffer.get(), request->buffer_size, callback,
+                         NO_TRAFFIC_ANNOTATION_BUG_656607);
   if (send_result != net::ERR_IO_PENDING) {
     callback.Run(send_result);
   }
diff --git a/device/vr/vr_service.mojom b/device/vr/vr_service.mojom
index 1d5fd8e..3a5a90da 100644
--- a/device/vr/vr_service.mojom
+++ b/device/vr/vr_service.mojom
@@ -31,6 +31,7 @@
 struct VRDisplayCapabilities {
   bool hasPosition;
   bool hasExternalDisplay;
+  // Indicates whether the display can actively show imagery on a headset.
   bool canPresent;
 };
 
@@ -53,8 +54,10 @@
   string displayName;
   VRDisplayCapabilities capabilities;
   VRStageParameters? stageParameters;
-  VREyeParameters leftEye;
-  VREyeParameters rightEye;
+  // Parameters required to distort a scene for viewing in a VR headset. Only
+  // required for devices which have the canPresent capability.
+  VREyeParameters? leftEye;
+  VREyeParameters? rightEye;
 };
 
 enum VRDisplayEventReason {
diff --git a/docs/code_reviews.md b/docs/code_reviews.md
index 46077d5..f7f0017e 100644
--- a/docs/code_reviews.md
+++ b/docs/code_reviews.md
@@ -110,7 +110,7 @@
 to address them in a followup patch.
 
 Do not use TBR just because a change is urgent or the reviewer is being slow.
-Contact the reviewer directly or find somebody.
+Contact the reviewer directly or find somebody else to review your change.
 
 To send a change TBR, annotate the description and send email like normal.
 Otherwise the reviewer won't know to review the patch.
diff --git a/docs/security/faq.md b/docs/security/faq.md
index a4f73b8..fc97b934 100644
--- a/docs/security/faq.md
+++ b/docs/security/faq.md
@@ -58,6 +58,11 @@
 greater benefit in the long run than backporting. We strongly recommend that you
 track the latest stable branches, and we support only the latest stable branch.
 
+<a name="TOC-Severity-Guidelines"></a>
+## How does the Chrome team determine severity of security bugs?
+
+See the [severity guidelines](severity-guidelines.md) for more information.
+
 <a name="TOC-Are-privacy-issues-considered-security-bugs-"></a>
 ## Are privacy issues considered security bugs?
 
@@ -515,6 +520,18 @@
 For a longer discussion on this, see the [mailing list
 announcement](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/zhhj7hCip5c).
 
+<a name="TOC-Signout-of-Chrome"></a>
+## Signing out of Chrome does not delete previously-synced data?
+
+If you have signed into Chrome and subsequently sign out of Chrome, previously
+saved passwords and other data are not deleted from your device unless you
+select that option when signing out of Chrome.
+
+If you change your Google password, synced data will no longer be updated in
+Chrome instances until you provide the new password to Chrome on each device
+configured to sync. However, previously synced data [remains available](https://crbug.com/792967)
+on each previously-syncing device unless manually removed.
+
 <a name="TOC-Why-doesn-t-the-Password-Manager-save-my-Google-password-if-I-am-using-Chrome-Sync-"></a>
 ## Why doesn't the Password Manager save my Google password if I am using Chrome Sync?
 
diff --git a/docs/security/security-labels.md b/docs/security/security-labels.md
index 2085cd3..fa0eba1 100644
--- a/docs/security/security-labels.md
+++ b/docs/security/security-labels.md
@@ -32,14 +32,42 @@
 * **Security_Impact-**{**Head**, **Beta**, **Stable**, **None**}: Designates
 which branch(es) were impacted by the bug. Only apply the label corresponding
 with the earliest affected branch. **None** means that a security bug is in a
-disabled feature, or otherwise doesn't impact Chrome. Note that **Security_Severity**
-should still be set on **Security_Impact-None** issues, as if the feature were enabled or
-the code reachable.
-* **Restrict-View-SecurityTeam** or **Restrict-View-SecurityNotify**: Labels
-that restrict access to the bug for members of security@chromium.org or
-security-notify@chromium.org, respectively. Should a bug ever contain
-confidential information, or if the reporter wishes to remain anonymous, we add
-**Restrict-View-Google** and/or **Restrict-View-SecurityEmbargo**.
+disabled feature, or otherwise doesn't impact Chrome. Note that
+**Security_Severity** should still be set on **Security_Impact-None** issues, as
+if the feature were enabled or the code reachable.
+* **Restrict-View-**{**SecurityTeam**, **SecurityNotify**, **Google**,
+**SecurityEmbargo**}: Labels that restrict access to the bug. Meaning and usage
+guidelines are as follows:
+  * **Restrict-View-SecurityTeam**: Restricts access to members of
+    *security@chromium.org*. This is the default that should be used for general
+    security bugs that aren't sensitive otherwise.
+  * **Restrict-View-SecurityNotify**: Restricts access to members of
+    *security-notify@chromium.org*, which includes external parties who ship
+    Chromium-based products and who need to know about available bug fixes.
+    *security@chromium.org* is a member of that group so the former is a
+    superset of the latter. **Restrict-View-SecurityNotify** is not suitable for
+    sensitive bugs.
+  * **Restrict-View-Google**: Restricts access to users that are Google
+    employees (but also via their *chromium.org* accounts). This should be used
+    for bugs that aren't OK for external contributors to see (even if we trust
+    them with security work), for example due to:
+      * legal reasons (bug affects a partner Google is under NDA and the
+        information is subject to that)
+      * the bug affecting more Google products than Chrome and Chrome OS
+  * **Restrict-View-SecurityEmbargo**: Restricts access to
+    *security@chromium.org* and and stops Sheriffbot from publishing the bug
+    automatically. Use this if the bug in question is subject to disclosure
+    decisions made externally, such as:
+      * We receive advance notice of security bugs from an upstream open source
+        project or Google partner and they organize a coordinated disclosure
+        process. We'd remove the restriction label if/when the embarge gets
+        lifted.
+      * The reporter indicates a preference to remain anonymous an the bug
+        history would give away the reporter's identity (if they file using an
+        anonymous account, this doesn't apply).
+
+  If multiple restriction labels are appropriate, set all of them. Note that all
+  restriction labels must be satisfied for a user to have access to a bug.
 * **reward-**{**topanel**, **unpaid**, **na**, **inprocess**, _#_}: Labels used
 in tracking bugs nominated for our [Vulnerability Reward
 Program](https://www.chromium.org/Home/chromium-security/vulnerability-rewards-program).
@@ -54,11 +82,10 @@
 * **Merge-**{**Request-?**, **Approved-?**, **Merged-?**}: Security fixes
 are frequently merged to earlier release branches.
 * **Release-#-M##**: Denotes which exact patch a security fix made it into.
-This is more fine-grained than the **M-** label. **Release-0-M50** denotes the
+This is more fine-grained than the **M-#** label. **Release-0-M50** denotes the
 initial release of a M50 to Stable.
 * **CVE-####-####**: For security bugs that get assigned a CVE, we tag the
 appropriate bug(s) with the label for easy searching.
-
 **Type-Bug-Security** bugs should always have **Security_Severity**, 
 **Security_Impact**, **OS**, **Pri**, **M**, **Component**, and an
 **owner** set.
@@ -81,6 +108,92 @@
 OS, and perhaps Fuchsia (?). Views for macOS is increasingly a thing, but Cocoa
 code (e.g. `ui/message_center/cocoa`) is particular to macOS.
 
+## Sheriffbot automation
+
+Security labels guide the actions taken by
+[SheriffBot](https://www.chromium.org/issue-tracking/autotriage). The source of
+truth for the actual rule set is
+[go/sheriffbot-source](https://goto.google.com/sheriffbot-source) (sorry, Google
+employees only). The motivation behind these rules is to help automate the
+security bug life cycle so security sheriffs and security engineers in general
+spend less time updating bugs and can do more useful work instead.
+
+The following sections describe the current set of rules relevant to security
+bugs. The list below only describes rules that change the labels described
+above. There are additional rules for sending nag messages and janitorial tasks;
+check the [sheriffbot source](https://goto.google.com/sheriffbot-source) for
+details.
+
+### Remove Invalid **Release-#** Labels
+
+Only bugs that affect stable should carry a release label, this rule removes
+release labels that are set on bugs not affecting stable.
+
+### Remove Invalid **Security_Impact-X** Labels
+
+There should be exactly one **Security_Impact-X** label and it should be one of
+the 4 valid impact labels (None, Stable, Beta, Head). This rule removes any
+invalid and excess impact labels.
+
+### Adjust **Security_Impact-X** To Match Milestone Labels
+
+Based on **M-#** milestone labels this rule assigns corresponding
+**Security_Impact-X** labels if they are incorrect or absent.
+
+### Update **M-#** Labels
+
+Bugs that are labelled with milestones earlier than the current milestone will
+be relabeled to set the label for the current milestone and
+**Security_Impact-Stable**.
+
+Bugs that carry a **Security_Impact-X** label but are missing a milestone label
+will be assigned the **M-#** label corresponding to the respective milestone.
+
+### Set **ReleaseBlock-X** For Regressions
+
+If there's a high or medium severity security regression in beta or ToT, add a
+**ReleaseBlock-Stable** label to prevent that regression to be shipped to users.
+
+Similarly, critical security regressions are marked **ReleaseBlock-Beta**.
+
+### Adjust **Pri-#** To Match Severity
+
+Adjust **Pri-#** according to the priority rules for severity labels described
+above.
+
+### Drop **Restrict-View-{SecurityTeam,SecurityNotify}** From Old And Fixed Bugs
+
+Remove **Restrict-View-SecurityTeam** and **Restrict-View-SecurityNotify** from
+security bugs that have been closed (Fixed, Verified, Duplicate, WontFix,
+Invalid) more than 14 weeks ago and add the **allpublic** label to make the bugs
+accessible publicly. The idea here is that security bug fixes will generally
+require 12 weeks to ship (2 release cycles for ToT changes to hit stable). This
+catches cases where the bug owner forgets to mark the bug public after the fix
+is released.
+
+### Set **Restrict-View-SecurityNotify** On Fixed Bugs
+
+Replace **Restrict-View-SecurityTeam** with **Restrict-View-SecurityNotify** for
+fixed security bugs. Rationale is that while fixed bugs are generally not
+intended to become public immediately, we'd like to give access to external
+parties depending on Chromium via *security-notify@chromium.org*.
+
+### Set **Merge-Request-X** For Beta Branch For Fixed Bugs
+
+Fixed security bugs that affect stable or beta and are critical or high severity
+will automatically trigger a merge request for the current beta branch.
+
+### Drop **ReleaseBlock-X** Labels From **Security_Impact-None** Bugs
+
+No need to stop a release if the bug doesn't have any consequences.
+
+### Set **Status:Fixed** For Open Security Bugs With Merge Labels
+
+Security bugs that have a merge label (but excluding bugs with **component:OS**)
+are marked as fixed automatically. The rationale is that if something gets
+merged to a release branch, there's a high likelihood that the bug is actually
+fixed.
+
 ## An Example
 
 Given the importance and volume of labels, an example might be useful.
diff --git a/extensions/browser/api/feedback_private/feedback_private_api.cc b/extensions/browser/api/feedback_private/feedback_private_api.cc
index 4cb484c..b04ebe3 100644
--- a/extensions/browser/api/feedback_private/feedback_private_api.cc
+++ b/extensions/browser/api/feedback_private/feedback_private_api.cc
@@ -232,9 +232,9 @@
 
 #if defined(OS_CHROMEOS)
 void FeedbackPrivateReadLogSourceFunction::OnCompleted(
-    const feedback_private::ReadLogSourceResult& result) {
+    std::unique_ptr<feedback_private::ReadLogSourceResult> result) {
   Respond(
-      ArgumentList(feedback_private::ReadLogSource::Results::Create(result)));
+      ArgumentList(feedback_private::ReadLogSource::Results::Create(*result)));
 }
 #endif  // defined(OS_CHROMEOS)
 
diff --git a/extensions/browser/api/feedback_private/feedback_private_api.h b/extensions/browser/api/feedback_private/feedback_private_api.h
index e0ef4236..9fdee6d 100644
--- a/extensions/browser/api/feedback_private/feedback_private_api.h
+++ b/extensions/browser/api/feedback_private/feedback_private_api.h
@@ -117,7 +117,8 @@
 
 #if defined(OS_CHROMEOS)
  private:
-  void OnCompleted(const api::feedback_private::ReadLogSourceResult& result);
+  void OnCompleted(
+      std::unique_ptr<api::feedback_private::ReadLogSourceResult> result);
 #endif  // defined(OS_CHROMEOS)
 };
 
diff --git a/extensions/browser/api/feedback_private/log_source_access_manager.cc b/extensions/browser/api/feedback_private/log_source_access_manager.cc
index 4d555ef2..8e0036c 100644
--- a/extensions/browser/api/feedback_private/log_source_access_manager.cc
+++ b/extensions/browser/api/feedback_private/log_source_access_manager.cc
@@ -10,6 +10,8 @@
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_split.h"
+#include "base/task_runner_util.h"
+#include "base/task_scheduler/post_task.h"
 #include "base/time/default_tick_clock.h"
 #include "extensions/browser/api/api_resource_manager.h"
 #include "extensions/browser/api/extensions_api_client.h"
@@ -52,12 +54,28 @@
   }
 }
 
+// Anonymizes the strings in |result|.
+void AnonymizeResults(
+    scoped_refptr<feedback::AnonymizerToolContainer> anonymizer_container,
+    ReadLogSourceResult* result) {
+  feedback::AnonymizerTool* anonymizer = anonymizer_container->Get();
+  for (std::string& line : result->log_lines)
+    line = anonymizer->Anonymize(line);
+}
+
 }  // namespace
 
 LogSourceAccessManager::LogSourceAccessManager(content::BrowserContext* context)
     : context_(context),
       tick_clock_(std::make_unique<base::DefaultTickClock>()),
-      anonymizer_(std::make_unique<feedback::AnonymizerTool>()),
+      task_runner_for_anonymizer_(base::CreateSequencedTaskRunnerWithTraits(
+          // User visible as the feedback_api is used by the Chrome (OS)
+          // feedback extension while the user may be looking at a spinner.
+          {base::TaskPriority::USER_VISIBLE,
+           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
+      anonymizer_container_(
+          base::MakeRefCounted<feedback::AnonymizerToolContainer>(
+              task_runner_for_anonymizer_)),
       weak_factory_(this) {}
 
 LogSourceAccessManager::~LogSourceAccessManager() {}
@@ -95,7 +113,8 @@
   // perspective, there is no new data. There is no need for the caller to keep
   // track of the time since last access.
   if (!UpdateSourceAccessTime(resource_id)) {
-    callback.Run({});
+    callback.Run(
+        std::make_unique<api::feedback_private::ReadLogSourceResult>());
     return true;
   }
 
@@ -117,22 +136,28 @@
     bool delete_resource,
     const ReadLogSourceCallback& callback,
     std::unique_ptr<SystemLogsResponse> response) {
-  ReadLogSourceResult result;
+  auto result = std::make_unique<ReadLogSourceResult>();
+
   // Always return invalid resource ID if there is a cleanup.
-  result.reader_id = delete_resource ? kInvalidResourceId : resource_id;
+  result->reader_id = delete_resource ? kInvalidResourceId : resource_id;
 
-  GetLogLinesFromSystemLogsResponse(*response, &result.log_lines);
+  GetLogLinesFromSystemLogsResponse(*response, &result->log_lines);
 
-  for (std::string& line : result.log_lines)
-    line = anonymizer_->Anonymize(line);
+  // Retrieve result pointer before the PostTaskAndReply to fix issues with
+  // an undefined execution order of arguments in a function call
+  // (std::move(result) being executed before result.get()).
+  ReadLogSourceResult* result_ptr = result.get();
+  task_runner_for_anonymizer_->PostTaskAndReply(
+      FROM_HERE,
+      base::BindOnce(AnonymizeResults, anonymizer_container_,
+                     base::Unretained(result_ptr)),
+      base::BindOnce(callback, std::move(result)));
 
   if (delete_resource) {
     // This should also remove the entry from |sources_|.
     ApiResourceManager<LogSourceResource>::Get(context_)->Remove(extension_id,
                                                                  resource_id);
   }
-
-  callback.Run(result);
 }
 
 void LogSourceAccessManager::RemoveHandle(ResourceId id) {
diff --git a/extensions/browser/api/feedback_private/log_source_access_manager.h b/extensions/browser/api/feedback_private/log_source_access_manager.h
index 343b42f..62563a5 100644
--- a/extensions/browser/api/feedback_private/log_source_access_manager.h
+++ b/extensions/browser/api/feedback_private/log_source_access_manager.h
@@ -14,6 +14,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
 #include "components/feedback/anonymizer_tool.h"
@@ -29,8 +30,8 @@
 // - A source may not be accessed too frequently by an extension.
 class LogSourceAccessManager {
  public:
-  using ReadLogSourceCallback =
-      base::Callback<void(const api::feedback_private::ReadLogSourceResult&)>;
+  using ReadLogSourceCallback = base::Callback<void(
+      std::unique_ptr<api::feedback_private::ReadLogSourceResult>)>;
 
   explicit LogSourceAccessManager(content::BrowserContext* context);
   ~LogSourceAccessManager();
@@ -152,7 +153,8 @@
   std::unique_ptr<base::TickClock> tick_clock_;
 
   // For removing PII from log strings from log sources.
-  std::unique_ptr<feedback::AnonymizerTool> anonymizer_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_for_anonymizer_;
+  scoped_refptr<feedback::AnonymizerToolContainer> anonymizer_container_;
 
   base::WeakPtrFactory<LogSourceAccessManager> weak_factory_;
 
diff --git a/extensions/browser/api/feedback_private/log_source_access_manager_chromeos_unittest.cc b/extensions/browser/api/feedback_private/log_source_access_manager_chromeos_unittest.cc
index dc0ce62..449eef40 100644
--- a/extensions/browser/api/feedback_private/log_source_access_manager_chromeos_unittest.cc
+++ b/extensions/browser/api/feedback_private/log_source_access_manager_chromeos_unittest.cc
@@ -33,7 +33,7 @@
 
   // Create a dummy callback to pass to FetchFromSource().
   LogSourceAccessManager::ReadLogSourceCallback callback =
-      base::Bind([](const ReadLogSourceResult&) {});
+      base::Bind([](std::unique_ptr<ReadLogSourceResult>) {});
 
   const std::string extension_id = "extension";
 
@@ -84,7 +84,7 @@
 
   // Create a dummy callback to pass to FetchFromSource().
   LogSourceAccessManager::ReadLogSourceCallback callback =
-      base::Bind([](const ReadLogSourceResult&) {});
+      base::Bind([](std::unique_ptr<ReadLogSourceResult>) {});
 
   int count = 0;
 
diff --git a/extensions/browser/api/messaging/OWNERS b/extensions/browser/api/messaging/OWNERS
index c2707aec..5325484 100644
--- a/extensions/browser/api/messaging/OWNERS
+++ b/extensions/browser/api/messaging/OWNERS
@@ -1,4 +1,3 @@
-kelvinp@chromium.org
 sergeyu@chromium.org
 
 # COMPONENT: Platform>Extensions>API
diff --git a/extensions/browser/api/socket/tcp_socket.cc b/extensions/browser/api/socket/tcp_socket.cc
index 4b31116..af08fb1 100644
--- a/extensions/browser/api/socket/tcp_socket.cc
+++ b/extensions/browser/api/socket/tcp_socket.cc
@@ -16,6 +16,7 @@
 #include "net/base/rand_callback.h"
 #include "net/log/net_log_source.h"
 #include "net/socket/tcp_client_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 
 namespace extensions {
 
@@ -269,12 +270,14 @@
 int TCPSocket::WriteImpl(net::IOBuffer* io_buffer,
                          int io_buffer_size,
                          const net::CompletionCallback& callback) {
+  // TODO(crbug.com/656607): Add proper annotation.
   if (socket_mode_ != CLIENT)
     return net::ERR_FAILED;
   else if (!socket_.get() || !IsConnected())
     return net::ERR_SOCKET_NOT_CONNECTED;
   else
-    return socket_->Write(io_buffer, io_buffer_size, callback);
+    return socket_->Write(io_buffer, io_buffer_size, callback,
+                          NO_TRAFFIC_ANNOTATION_BUG_656607);
 }
 
 void TCPSocket::RefreshConnectionStatus() {
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 828f8424..5d657fc 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1061,7 +1061,7 @@
   DEVELOPERPRIVATE_GETPROFILECONFIGURATION,
   DEVELOPERPRIVATE_UPDATEPROFILECONFIGURATION,
   SOCKETS_UDP_SETBROADCAST,
-  FILEMANAGERPRIVATE_GETPROVIDINGEXTENSIONS,
+  FILEMANAGERPRIVATE_GETPROVIDERS,
   WEBVIEWINTERNAL_ADDCONTENTSCRIPTS,
   WEBVIEWINTERNAL_REMOVECONTENTSCRIPTS,
   DEVELOPERPRIVATE_REPAIREXTENSION,
diff --git a/extensions/browser/renderer_startup_helper_unittest.cc b/extensions/browser/renderer_startup_helper_unittest.cc
index 7cff90d..c954145 100644
--- a/extensions/browser/renderer_startup_helper_unittest.cc
+++ b/extensions/browser/renderer_startup_helper_unittest.cc
@@ -171,7 +171,8 @@
   EXPECT_FALSE(IsExtensionPendingActivationInProcess(
       *extension_, render_process_host_.get()));
   ASSERT_EQ(1u, sink.message_count());
-  EXPECT_EQ(ExtensionMsg_Loaded::ID, sink.GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID),
+            sink.GetMessageAt(0)->type());
 
   // Activate extension.
   sink.ClearMessages();
@@ -179,7 +180,8 @@
   EXPECT_FALSE(IsExtensionPendingActivationInProcess(
       *extension_, render_process_host_.get()));
   ASSERT_EQ(1u, sink.message_count());
-  EXPECT_EQ(ExtensionMsg_ActivateExtension::ID, sink.GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_ActivateExtension::ID),
+            sink.GetMessageAt(0)->type());
 
   // Disable extension.
   sink.ClearMessages();
@@ -187,7 +189,8 @@
   helper_->OnExtensionUnloaded(*extension_);
   EXPECT_FALSE(IsExtensionLoaded(*extension_));
   ASSERT_EQ(1u, sink.message_count());
-  EXPECT_EQ(ExtensionMsg_Unloaded::ID, sink.GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Unloaded::ID),
+            sink.GetMessageAt(0)->type());
 
   // Extension enabled again.
   sink.ClearMessages();
@@ -198,7 +201,8 @@
   EXPECT_FALSE(IsExtensionPendingActivationInProcess(
       *extension_, render_process_host_.get()));
   ASSERT_EQ(1u, sink.message_count());
-  EXPECT_EQ(ExtensionMsg_Loaded::ID, sink.GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID),
+            sink.GetMessageAt(0)->type());
 
   // Render Process terminated.
   SimulateRenderProcessTerminated(render_process_host_.get());
@@ -329,12 +333,15 @@
   // The extension would not have been unloaded from the incognito renderer
   // since it wasn't loaded.
   ASSERT_EQ(1u, incognito_sink.message_count());
-  EXPECT_EQ(ExtensionMsg_Loaded::ID, incognito_sink.GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID),
+            incognito_sink.GetMessageAt(0)->type());
   // The extension would be first unloaded and then loaded from the normal
   // renderer.
   ASSERT_EQ(2u, sink.message_count());
-  EXPECT_EQ(ExtensionMsg_Unloaded::ID, sink.GetMessageAt(0)->type());
-  EXPECT_EQ(ExtensionMsg_Loaded::ID, sink.GetMessageAt(1)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Unloaded::ID),
+            sink.GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID),
+            sink.GetMessageAt(1)->type());
 }
 
 // Tests that platform apps are always loaded in an incognito renderer.
@@ -360,7 +367,8 @@
   EXPECT_TRUE(IsExtensionLoadedInProcess(*platform_app,
                                          incognito_render_process_host_.get()));
   ASSERT_EQ(1u, incognito_sink.message_count());
-  EXPECT_EQ(ExtensionMsg_Loaded::ID, incognito_sink.GetMessageAt(0)->type());
+  EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID),
+            incognito_sink.GetMessageAt(0)->type());
 }
 
 }  // namespace extensions
diff --git a/extensions/renderer/api_activity_logger_unittest.cc b/extensions/renderer/api_activity_logger_unittest.cc
index a76c5b0..2751c81 100644
--- a/extensions/renderer/api_activity_logger_unittest.cc
+++ b/extensions/renderer/api_activity_logger_unittest.cc
@@ -66,7 +66,9 @@
 
   ASSERT_EQ(1u, sink.message_count());
   const IPC::Message* message = sink.GetMessageAt(0u);
-  ASSERT_EQ(ExtensionHostMsg_AddAPIActionToActivityLog::ID, message->type());
+  ASSERT_EQ(
+      static_cast<uint32_t>(ExtensionHostMsg_AddAPIActionToActivityLog::ID),
+      message->type());
   ExtensionHostMsg_AddAPIActionToActivityLog::Param full_params;
   ASSERT_TRUE(
       ExtensionHostMsg_AddAPIActionToActivityLog::Read(message, &full_params));
diff --git a/extensions/renderer/resources/guest_view/guest_view.js b/extensions/renderer/resources/guest_view/guest_view.js
index 70726b46..7484b54 100644
--- a/extensions/renderer/resources/guest_view/guest_view.js
+++ b/extensions/renderer/resources/guest_view/guest_view.js
@@ -259,7 +259,10 @@
   GuestViewInternal.destroyGuest(
       this.id, $Function.bind(this.handleCallback, this, callback));
 
-  // Reset the state of the destroyed guest;
+  // Reset the state of the destroyed guest; it's ok to do this after shipping
+  // the callback to the GuestViewInternal api, since it runs asynchronously,
+  // and the changes below will happen before the next item from the action
+  // queue is executed.
   this.contentWindow = null;
   this.id = 0;
   this.internalInstanceId = 0;
diff --git a/extensions/renderer/resources/guest_view/guest_view_iframe.js b/extensions/renderer/resources/guest_view/guest_view_iframe.js
index b8d54fae..eb6f38df 100644
--- a/extensions/renderer/resources/guest_view/guest_view_iframe.js
+++ b/extensions/renderer/resources/guest_view/guest_view_iframe.js
@@ -127,8 +127,6 @@
     GuestViewInternalNatives.DetachGuest(this.internalInstanceId);
   }
 
-  this.handleCallback(callback);
-
   // Reset the state of the destroyed guest;
   this.contentWindow = null;
   this.id = 0;
@@ -137,4 +135,8 @@
   if (ResizeEvent.hasListener(this.callOnResize)) {
     ResizeEvent.removeListener(this.callOnResize);
   }
+
+  // Handle callback at end to avoid handling items in the action queue out of
+  // order, since the callback is run synchronously here.
+  this.handleCallback(callback);
 };
diff --git a/extensions/renderer/script_context_browsertest.cc b/extensions/renderer/script_context_browsertest.cc
index c436106..37f42755 100644
--- a/extensions/renderer/script_context_browsertest.cc
+++ b/extensions/renderer/script_context_browsertest.cc
@@ -6,6 +6,7 @@
 #include "content/public/renderer/render_frame.h"
 #include "content/public/test/frame_load_waiter.h"
 #include "extensions/renderer/script_context.h"
+#include "extensions/renderer/script_context_set.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "url/gurl.h"
@@ -94,5 +95,16 @@
   EXPECT_EQ(GetEffectiveDocumentURL(frame3_1), different_url);
 }
 
+TEST_F(ScriptContextTest, GetMainWorldContextForFrame) {
+  // ScriptContextSet::GetMainWorldContextForFrame should work, even without an
+  // existing v8::HandleScope.
+  content::RenderFrame* render_frame =
+      content::RenderFrame::FromWebFrame(GetMainFrame());
+  ScriptContext* script_context =
+      ScriptContextSet::GetMainWorldContextForFrame(render_frame);
+  ASSERT_TRUE(script_context);
+  EXPECT_EQ(render_frame, script_context->GetRenderFrame());
+}
+
 }  // namespace
 }  // namespace extensions
diff --git a/extensions/renderer/script_context_set.cc b/extensions/renderer/script_context_set.cc
index 72d67b00c..3f62119 100644
--- a/extensions/renderer/script_context_set.cc
+++ b/extensions/renderer/script_context_set.cc
@@ -14,6 +14,7 @@
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_injection.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "v8/include/v8.h"
 
@@ -93,6 +94,7 @@
 
 ScriptContext* ScriptContextSet::GetMainWorldContextForFrame(
     content::RenderFrame* render_frame) {
+  v8::HandleScope handle_scope(blink::MainThreadIsolate());
   return GetContextByV8Context(
       render_frame->GetWebFrame()->MainWorldScriptContext());
 }
diff --git a/extensions/shell/browser/system_logs/shell_system_logs_fetcher_unittest.cc b/extensions/shell/browser/system_logs/shell_system_logs_fetcher_unittest.cc
index 27fe9c0d..649f01e 100644
--- a/extensions/shell/browser/system_logs/shell_system_logs_fetcher_unittest.cc
+++ b/extensions/shell/browser/system_logs/shell_system_logs_fetcher_unittest.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "components/feedback/system_logs/system_logs_fetcher.h"
@@ -46,12 +47,16 @@
   void OnSystemLogsResponse(
       std::unique_ptr<system_logs::SystemLogsResponse> response) {
     response_ = std::move(response);
+    wait_for_logs_response_run_loop_.Quit();
   }
 
   const system_logs::SystemLogsResponse* response() const {
     return response_.get();
   }
 
+ protected:
+  base::RunLoop wait_for_logs_response_run_loop_;
+
  private:
   std::unique_ptr<system_logs::SystemLogsResponse> response_;
 };
@@ -72,7 +77,9 @@
   fetcher->Fetch(base::Bind(&ShellSystemLogsFetcherTest::OnSystemLogsResponse,
                             base::Unretained(this)));
 
-  EXPECT_TRUE(response());
+  wait_for_logs_response_run_loop_.Run();
+
+  ASSERT_TRUE(response());
   EXPECT_LT(0u, response()->at("APPSHELL VERSION").size());
   EXPECT_LT(0u, response()->at("OS VERSION").size());
 
diff --git a/gin/BUILD.gn b/gin/BUILD.gn
index d71adf51..39bd188c 100644
--- a/gin/BUILD.gn
+++ b/gin/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//testing/test.gni")
 import("//v8/gni/v8.gni")
+import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
 
 component("gin") {
   sources = [
@@ -82,6 +83,9 @@
       "$root_out_dir/natives_blob.bin",
       "$root_out_dir/snapshot_blob.bin",
     ]
+    if (use_v8_context_snapshot) {
+      data += [ "$root_out_dir/v8_context_snapshot.bin" ]
+    }
   }
 
   defines = [ "GIN_IMPLEMENTATION" ]
@@ -98,7 +102,10 @@
     libs = [ "CoreFoundation.framework" ]
   }
 
-  configs += [ "//v8:external_startup_data" ]
+  configs += [
+    "//tools/v8_context_snapshot:use_v8_context_snapshot",
+    "//v8:external_startup_data",
+  ]
 }
 
 executable("gin_shell") {
@@ -115,7 +122,10 @@
     "//v8",
   ]
 
-  configs += [ "//v8:external_startup_data" ]
+  configs += [
+    "//tools/v8_context_snapshot:use_v8_context_snapshot",
+    "//v8:external_startup_data",
+  ]
 }
 
 source_set("gin_test") {
@@ -142,10 +152,14 @@
   ]
   deps = [
     "//base/test:test_support",
+    "//tools/v8_context_snapshot",
     "//v8",
   ]
 
-  configs += [ "//v8:external_startup_data" ]
+  configs += [
+    "//tools/v8_context_snapshot:use_v8_context_snapshot",
+    "//v8:external_startup_data",
+  ]
 }
 
 test("gin_unittests") {
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
index 0018a7f..1a7b62df 100644
--- a/gin/isolate_holder.cc
+++ b/gin/isolate_holder.cc
@@ -37,16 +37,12 @@
 IsolateHolder::IsolateHolder(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     AccessMode access_mode)
-    : IsolateHolder(std::move(task_runner),
-                    access_mode,
-                    kAllowAtomicsWait,
-                    nullptr) {}
+    : IsolateHolder(std::move(task_runner), access_mode, kAllowAtomicsWait) {}
 
 IsolateHolder::IsolateHolder(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     AccessMode access_mode,
-    AllowAtomicsWaitMode atomics_wait_mode,
-    v8::StartupData* startup_data)
+    AllowAtomicsWaitMode atomics_wait_mode)
     : access_mode_(access_mode) {
   v8::ArrayBuffer::Allocator* allocator = g_array_buffer_allocator;
   CHECK(allocator) << "You need to invoke gin::IsolateHolder::Initialize first";
@@ -59,14 +55,6 @@
   params.array_buffer_allocator = allocator;
   params.allow_atomics_wait = atomics_wait_mode == kAllowAtomicsWait;
   params.external_references = g_reference_table;
-
-  if (startup_data) {
-    CHECK(g_reference_table);
-    V8Initializer::GetV8ContextSnapshotData(startup_data);
-    if (startup_data->data) {
-      params.snapshot_blob = startup_data;
-    }
-  }
   isolate_ = v8::Isolate::New(params);
 
   SetUp(std::move(task_runner));
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index f29b2de..11403c3 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -59,8 +59,7 @@
                 AccessMode access_mode);
   IsolateHolder(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
                 AccessMode access_mode,
-                AllowAtomicsWaitMode atomics_wait_mode,
-                v8::StartupData* startup_data);
+                AllowAtomicsWaitMode atomics_wait_mode);
 
   // This constructor is to create V8 snapshot for Blink.
   // Note this constructor calls isolate->Enter() internally.
diff --git a/gin/shell/gin_main.cc b/gin/shell/gin_main.cc
index 0b8f8b859..a28ca155 100644
--- a/gin/shell/gin_main.cc
+++ b/gin/shell/gin_main.cc
@@ -71,7 +71,10 @@
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
   gin::V8Initializer::LoadV8Snapshot();
   gin::V8Initializer::LoadV8Natives();
-#endif
+#ifdef USE_V8_CONTEXT_SNAPSHOT
+  gin::V8Initializer::LoadV8ContextSnapshot();
+#endif  // USE_V8_CONTEXT_SNAPSHOT
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
 
   base::MessageLoop message_loop;
   base::TaskScheduler::CreateAndStartWithDefaultParams("gin");
diff --git a/gin/shell_runner_unittest.cc b/gin/shell_runner_unittest.cc
index 02e6835..a2dc656f 100644
--- a/gin/shell_runner_unittest.cc
+++ b/gin/shell_runner_unittest.cc
@@ -32,6 +32,9 @@
   gin::V8Initializer::LoadV8Snapshot();
   gin::V8Initializer::LoadV8Natives();
 #endif
+#ifdef USE_V8_CONTEXT_SNAPSHOT
+  gin::V8Initializer::LoadV8ContextSnapshot();
+#endif
 
   gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
                                  gin::IsolateHolder::kStableV8Extras,
diff --git a/gin/test/file_runner.cc b/gin/test/file_runner.cc
index 853a695..39ece62 100644
--- a/gin/test/file_runner.cc
+++ b/gin/test/file_runner.cc
@@ -63,7 +63,10 @@
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
   gin::V8Initializer::LoadV8Snapshot();
   gin::V8Initializer::LoadV8Natives();
-#endif
+#ifdef USE_V8_CONTEXT_SNAPSHOT
+  gin::V8Initializer::LoadV8ContextSnapshot();
+#endif  // USE_V8_CONTEXT_SNAPSHOT
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
 
   gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
                                  gin::IsolateHolder::kStableV8Extras,
diff --git a/gin/test/v8_test.cc b/gin/test/v8_test.cc
index 88009dd..79db655 100644
--- a/gin/test/v8_test.cc
+++ b/gin/test/v8_test.cc
@@ -24,6 +24,10 @@
   gin::V8Initializer::LoadV8Snapshot();
   gin::V8Initializer::LoadV8Natives();
 #endif
+#ifdef USE_V8_CONTEXT_SNAPSHOT
+  gin::V8Initializer::LoadV8ContextSnapshot();
+#endif
+
   gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
                                  gin::IsolateHolder::kStableV8Extras,
                                  gin::ArrayBufferAllocator::SharedInstance());
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 03353be..b45e6db 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -242,16 +242,22 @@
 
 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
   v8::StartupData natives;
-  natives.data = reinterpret_cast<const char*>(g_mapped_natives->data());
-  natives.raw_size = static_cast<int>(g_mapped_natives->length());
+  GetMappedFileData(g_mapped_natives, &natives);
   v8::V8::SetNativesDataBlob(&natives);
 
-  if (g_mapped_snapshot) {
-    v8::StartupData snapshot;
-    snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data());
-    snapshot.raw_size = static_cast<int>(g_mapped_snapshot->length());
+#if defined(USE_V8_CONTEXT_SNAPSHOT)
+  if (g_mapped_v8_context_snapshot) {
+    v8::StartupData snapshot{};
+    GetMappedFileData(g_mapped_v8_context_snapshot, &snapshot);
     v8::V8::SetSnapshotDataBlob(&snapshot);
   }
+#else
+  if (g_mapped_snapshot) {
+    v8::StartupData snapshot{};
+    GetMappedFileData(g_mapped_snapshot, &snapshot);
+    v8::V8::SetSnapshotDataBlob(&snapshot);
+  }
+#endif  // USE_V8_CONTEXT_SNAPSHOT
 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
 
   v8::V8::SetEntropySource(&GenerateEntropy);
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 4daba143..cb85b04 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -20,6 +20,7 @@
 #include "base/atomic_sequence_num.h"
 #include "base/bits.h"
 #include "base/compiler_specific.h"
+#include "base/containers/span.h"
 #include "base/numerics/safe_math.h"
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
@@ -7106,8 +7107,8 @@
   ScopedMappedMemoryPtr mapped_alloc(entry.SerializedSize(), helper_,
                                      mapped_memory_.get());
   DCHECK(mapped_alloc.valid());
-  bool succeeded = entry.Serialize(
-      mapped_alloc.size(), reinterpret_cast<uint8_t*>(mapped_alloc.address()));
+  bool succeeded = entry.Serialize(base::make_span(
+      reinterpret_cast<uint8_t*>(mapped_alloc.address()), mapped_alloc.size()));
   DCHECK(succeeded);
 
   helper_->CreateTransferCacheEntryCHROMIUM(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 30cc6326..f0c62a2 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -18,6 +18,7 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/containers/queue.h"
+#include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
@@ -20434,7 +20435,8 @@
                                   handle_shm_id);
 
   if (!GetContextGroup()->transfer_cache()->CreateLockedEntry(
-          handle_id, handle, type, gr_context_.get(), data_memory, data_size))
+          handle_id, handle, type, gr_context_.get(),
+          base::make_span(data_memory, data_size)))
     return error::kInvalidArguments;
 
   return error::kNoError;
diff --git a/gpu/command_buffer/service/service_transfer_cache.cc b/gpu/command_buffer/service/service_transfer_cache.cc
index 0e65fb0..bbf1223 100644
--- a/gpu/command_buffer/service/service_transfer_cache.cc
+++ b/gpu/command_buffer/service/service_transfer_cache.cc
@@ -43,8 +43,7 @@
                                              ServiceDiscardableHandle handle,
                                              cc::TransferCacheEntryType type,
                                              GrContext* context,
-                                             uint8_t* data_memory,
-                                             size_t data_size) {
+                                             base::span<uint8_t> data) {
   auto found = entries_.Peek(id);
   if (found != entries_.end()) {
     return false;
@@ -55,8 +54,8 @@
   if (!entry)
     return false;
 
-  entry->Deserialize(context, data_size, data_memory);
-  total_size_ += entry->Size();
+  entry->Deserialize(context, data);
+  total_size_ += entry->CachedSize();
   entries_.Put(id, CacheEntryInternal(handle, std::move(entry)));
   EnforceLimits();
   return true;
@@ -77,7 +76,7 @@
     return false;
 
   found->second.handle.ForceDelete();
-  total_size_ -= found->second.entry->Size();
+  total_size_ -= found->second.entry->CachedSize();
   entries_.Erase(found);
   return true;
 }
@@ -100,7 +99,7 @@
       continue;
     }
 
-    total_size_ -= it->second.entry->Size();
+    total_size_ -= it->second.entry->CachedSize();
     it = entries_.Erase(it);
   }
 }
diff --git a/gpu/command_buffer/service/service_transfer_cache.h b/gpu/command_buffer/service/service_transfer_cache.h
index 1efaad12..b55ed582 100644
--- a/gpu/command_buffer/service/service_transfer_cache.h
+++ b/gpu/command_buffer/service/service_transfer_cache.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/containers/mru_cache.h"
+#include "base/containers/span.h"
 #include "cc/paint/transfer_cache_entry.h"
 #include "gpu/command_buffer/common/discardable_handle.h"
 #include "gpu/command_buffer/common/transfer_cache_entry_id.h"
@@ -33,8 +34,7 @@
                          ServiceDiscardableHandle handle,
                          cc::TransferCacheEntryType type,
                          GrContext* context,
-                         uint8_t* data_memory,
-                         size_t data_size);
+                         base::span<uint8_t> data);
   bool UnlockEntry(TransferCacheEntryId id);
   bool DeleteEntry(TransferCacheEntryId id);
   cc::ServiceTransferCacheEntry* GetEntry(TransferCacheEntryId id);
diff --git a/gpu/ipc/client/gpu_channel_host.h b/gpu/ipc/client/gpu_channel_host.h
index a994816..d8a9c12 100644
--- a/gpu/ipc/client/gpu_channel_host.h
+++ b/gpu/ipc/client/gpu_channel_host.h
@@ -50,10 +50,7 @@
 
   virtual void EstablishGpuChannel(
       const GpuChannelEstablishedCallback& callback) = 0;
-  // If the connection to the host process fails so the channel can not be
-  // established, then |connection_error| is set to true (if it's not null).
-  virtual scoped_refptr<GpuChannelHost> EstablishGpuChannelSync(
-      bool* connection_error) = 0;
+  virtual scoped_refptr<GpuChannelHost> EstablishGpuChannelSync() = 0;
   virtual GpuMemoryBufferManager* GetGpuMemoryBufferManager() = 0;
 };
 
diff --git a/ios/DEPS b/ios/DEPS
index 94f7f2c..0644d46 100644
--- a/ios/DEPS
+++ b/ios/DEPS
@@ -12,4 +12,8 @@
   # For unit tests.
   "+ios/testing",
   "+third_party/ocmock",
+
+  # To avoid includes from web::HttpServer since it is deprecated. Reference
+  # to crbug.com/708307.
+  "-ios/web/public/test/http_server/http_server.h",
 ]
diff --git a/ios/build/bots/scripts/run.py b/ios/build/bots/scripts/run.py
index ff5e50d..3baf5a89 100755
--- a/ios/build/bots/scripts/run.py
+++ b/ios/build/bots/scripts/run.py
@@ -49,6 +49,7 @@
         mac_toolchain=args.mac_toolchain_cmd,
         retries=args.retries,
         test_args=test_args,
+        test_cases=args.test_cases,
         xcode_path=args.xcode_path,
         xctest=args.xctest,
       )
@@ -63,6 +64,7 @@
         restart=args.restart,
         retries=args.retries,
         test_args=test_args,
+        test_cases=args.test_cases,
         xcode_path=args.xcode_path,
         xctest=args.xctest,
       )
@@ -144,6 +146,14 @@
     type=int,
   )
   parser.add_argument(
+    '-t',
+    '--test-cases',
+    action='append',
+    help=('Tests that should be included in the test run. All other tests '
+          'will be excluded from this run. If unspecified, run all tests.'),
+    metavar='testcase',
+  )
+  parser.add_argument(
     '-v',
     '--version',
     help='Version of iOS the simulator should run.',
@@ -198,6 +208,8 @@
   args.env_var = args.env_var or []
   args.env_var.extend(args_json.get('env_var', []))
   args.restart = args_json.get('restart', args.restart)
+  args.test_cases = args.test_cases or []
+  args.test_cases.extend(args_json.get('test_cases', []))
   args.xctest = args_json.get('xctest', args.xctest)
   test_args.extend(args_json.get('test_args', []))
 
diff --git a/ios/build/bots/scripts/test_runner.py b/ios/build/bots/scripts/test_runner.py
index 4d9d92a..712ec55e 100644
--- a/ios/build/bots/scripts/test_runner.py
+++ b/ios/build/bots/scripts/test_runner.py
@@ -51,11 +51,13 @@
     super(DeviceDetectionError, self).__init__(
       'Expected one device, found %s:\n%s' % (len(udids), '\n'.join(udids)))
 
+
 class DeviceRestartError(TestRunnerError):
   """Error restarting a device."""
   def __init__(self):
     super(DeviceRestartError, self).__init__('Error restarting a device')
 
+
 class PlugInsNotFoundError(TestRunnerError):
   """The PlugIns directory was not found."""
   def __init__(self, plugins_dir):
@@ -209,6 +211,7 @@
     mac_toolchain='',
     retries=None,
     test_args=None,
+    test_cases=None,
     xcode_path='',
     xctest=False,
   ):
@@ -225,6 +228,8 @@
       retries: Number of times to retry failed test cases.
       test_args: List of strings to pass as arguments to the test when
         launching.
+      test_cases: List of tests to be included in the test run. None or [] to
+        include all tests.
       xcode_path: Path to Xcode.app folder where its contents will be installed.
       xctest: Whether or not this is an XCTest.
 
@@ -263,6 +268,7 @@
     self.out_dir = out_dir
     self.retries = retries or 0
     self.test_args = test_args or []
+    self.test_cases = test_cases or []
     self.xcode_version = xcode_version
     self.xctest_path = ''
 
@@ -495,6 +501,7 @@
       mac_toolchain='',
       retries=None,
       test_args=None,
+      test_cases=None,
       xcode_path='',
       xctest=False,
   ):
@@ -516,6 +523,8 @@
       retries: Number of times to retry failed test cases.
       test_args: List of strings to pass as arguments to the test when
         launching.
+      test_cases: List of tests to be included in the test run. None or [] to
+        include all tests.
       xcode_path: Path to Xcode.app folder where its contents will be installed.
       xctest: Whether or not this is an XCTest.
 
@@ -534,6 +543,7 @@
         mac_toolchain=mac_toolchain,
         retries=retries,
         test_args=test_args,
+        test_cases=test_cases,
         xcode_path=xcode_path,
         xctest=xctest,
     )
@@ -687,6 +697,9 @@
         gtest_filter = get_gtest_filter(test_filter, invert=invert)
         cmd.extend(['-e', 'GKIF_SCENARIO_FILTER=%s' % kif_filter])
         cmd.extend(['-c', '--gtest_filter=%s' % gtest_filter])
+    elif self.xctest_path and not invert:
+      for test_case in self.test_cases:
+        cmd.extend(['-t', test_case])
 
     for env_var in self.env_vars:
       cmd.extend(['-e', env_var])
@@ -725,6 +738,7 @@
     restart=False,
     retries=None,
     test_args=None,
+    test_cases=None,
     xctest=False,
     xcode_path='',
   ):
@@ -742,6 +756,8 @@
       retries: Number of times to retry failed test cases.
       test_args: List of strings to pass as arguments to the test when
         launching.
+      test_cases: List of tests to be included in the test run. None or [] to
+        include all tests.
       xctest: Whether or not this is an XCTest.
       xcode_path: Path to Xcode.app folder where its contents will be installed.
 
@@ -759,6 +775,7 @@
       env_vars=env_vars,
       retries=retries,
       test_args=test_args,
+      test_cases=test_cases,
       xctest=xctest,
       mac_toolchain=mac_toolchain,
       xcode_path=xcode_path,
@@ -856,6 +873,28 @@
     self.retrieve_crash_reports()
     self.uninstall_apps()
 
+  def set_xctest_filters(self, test_filter=None, invert=False):
+    """Sets the tests be included in the test run."""
+    if self.test_cases:
+      filter = self.test_cases
+      if test_filter:
+        # If inverted, the filter should match tests in test_cases except the
+        # ones in test_filter. Otherwise, the filter should be tests both in
+        # test_cases and test_filter. test_filter is used for test retries, it
+        # should be a subset of test_cases. If the intersection of test_cases
+        # and test_filter fails, use test_filter.
+        filter = (sorted(set(filter) - set(test_filter)) if invert
+                  else sorted(set(filter) & set(test_filter)) or test_filter)
+      self.xctestrun_data['TestTargetName'].update(
+        {'OnlyTestIdentifiers': filter})
+    elif test_filter:
+      if invert:
+        self.xctestrun_data['TestTargetName'].update(
+          {'SkipTestIdentifiers': test_filter})
+      else:
+        self.xctestrun_data['TestTargetName'].update(
+          {'OnlyTestIdentifiers': test_filter})
+
   def get_launch_command(self, test_filter=None, invert=False):
     """Returns the command that can be used to launch the test app.
 
@@ -868,13 +907,7 @@
       A list of strings forming the command to launch the test.
     """
     if self.xctest_path:
-      if test_filter:
-        if invert:
-          self.xctestrun_data['TestTargetName'].update(
-            {'SkipTestIdentifiers': test_filter})
-        else:
-          self.xctestrun_data['TestTargetName'].update(
-            {'OnlyTestIdentifiers': test_filter})
+      self.set_xctest_filters(test_filter, invert)
       if self.env_vars:
         self.xctestrun_data['TestTargetName'].update(
           {'EnvironmentVariables': self.env_vars})
diff --git a/ios/build/bots/scripts/test_runner_test.py b/ios/build/bots/scripts/test_runner_test.py
index 262d60cd..ca81faf9 100755
--- a/ios/build/bots/scripts/test_runner_test.py
+++ b/ios/build/bots/scripts/test_runner_test.py
@@ -204,6 +204,41 @@
     with self.assertRaises(test_runner.AppLaunchError):
       tr.launch()
 
+  def test_get_launch_command(self):
+    """Ensures test filters are set correctly for launch command"""
+    tr = test_runner.SimulatorTestRunner(
+      'fake-app',
+      'fake-iossim',
+      'platform',
+      'os',
+      'xcode-version',
+      'xcode-build',
+      'out-dir',
+    )
+    tr.xctest_path = 'fake.xctest'
+    # Cases test_filter is not empty, with empty/non-empty self.test_cases.
+    tr.test_cases = []
+    cmd = tr.get_launch_command(['a'], invert=False)
+    self.assertIn('-t', cmd)
+    self.assertIn('a', cmd)
+
+    tr.test_cases = ['a', 'b']
+    cmd = tr.get_launch_command(['a'], invert=False)
+    self.assertIn('-t', cmd)
+    self.assertIn('a', cmd)
+    self.assertNotIn('b', cmd)
+
+    # Cases test_filter is empty, with empty/non-empty self.test_cases.
+    tr.test_cases = []
+    cmd = tr.get_launch_command(test_filter=None, invert=False)
+    self.assertNotIn('-t', cmd)
+
+    tr.test_cases = ['a', 'b']
+    cmd = tr.get_launch_command(test_filter=None, invert=False)
+    self.assertIn('-t', cmd)
+    self.assertIn('a', cmd)
+    self.assertIn('b', cmd)
+
   def test_relaunch(self):
     """Ensures test is relaunched on test crash until tests complete."""
     def set_up(self):
@@ -258,5 +293,95 @@
     self.assertTrue(tr.logs)
 
 
+class DeviceTestRunnerTest(TestCase):
+  def setUp(self):
+    super(DeviceTestRunnerTest, self).setUp()
+
+    def install_xcode(build, mac_toolchain_cmd, xcode_app_path):
+      return True
+
+    self.mock(test_runner.find_xcode, 'find_xcode',
+              lambda _: {'found': True})
+    self.mock(test_runner.find_xcode, 'get_current_xcode_info', lambda: {
+        'version': 'test version', 'build': 'test build', 'path': 'test/path'})
+    self.mock(test_runner, 'install_xcode', install_xcode)
+    self.mock(test_runner.subprocess, 'check_output',
+              lambda _: 'fake-bundle-id')
+    self.mock(os.path, 'abspath', lambda path: '/abs/path/to/%s' % path)
+    self.mock(os.path, 'exists', lambda _: True)
+
+    self.tr = test_runner.DeviceTestRunner(
+        'fake-app',
+        'xcode-version',
+        'xcode-build',
+        'out-dir',
+    )
+    self.tr.xctestrun_data = {'TestTargetName':{}}
+
+  def test_with_test_filter_without_test_cases(self):
+    """Ensures tests in the run with test_filter and no test_cases."""
+    self.tr.set_xctest_filters(['a', 'b'], invert=False)
+    self.assertEqual(
+        self.tr.xctestrun_data['TestTargetName']['OnlyTestIdentifiers'],
+        ['a', 'b']
+    )
+
+  def test_invert_with_test_filter_without_test_cases(self):
+    """Ensures tests in the run invert with test_filter and no test_cases."""
+    self.tr.set_xctest_filters(['a', 'b'], invert=True)
+    self.assertEqual(
+        self.tr.xctestrun_data['TestTargetName']['SkipTestIdentifiers'],
+        ['a', 'b']
+    )
+
+  def test_with_test_filter_with_test_cases(self):
+    """Ensures tests in the run with test_filter and test_cases."""
+    self.tr.test_cases = ['a', 'b', 'c', 'd']
+    self.tr.set_xctest_filters(['a', 'b', 'irrelevant test'], invert=False)
+    self.assertEqual(
+        self.tr.xctestrun_data['TestTargetName']['OnlyTestIdentifiers'],
+        ['a', 'b']
+    )
+
+  def test_invert_with_test_filter_with_test_cases(self):
+    """Ensures tests in the run invert with test_filter and test_cases."""
+    self.tr.test_cases = ['a', 'b', 'c', 'd']
+    self.tr.set_xctest_filters(['a', 'b', 'irrelevant test'], invert=True)
+    self.assertEqual(
+        self.tr.xctestrun_data['TestTargetName']['OnlyTestIdentifiers'],
+        ['c', 'd']
+    )
+
+  def test_without_test_filter_without_test_cases(self):
+    """Ensures tests in the run with no test_filter and no test_cases."""
+    self.tr.set_xctest_filters(test_filter=None, invert=False)
+    self.assertIsNone(
+        self.tr.xctestrun_data['TestTargetName'].get('OnlyTestIdentifiers'))
+
+  def test_invert_without_test_filter_without_test_cases(self):
+    """Ensures tests in the run invert with no test_filter and no test_cases."""
+    self.tr.set_xctest_filters(test_filter=None, invert=True)
+    self.assertIsNone(
+        self.tr.xctestrun_data['TestTargetName'].get('OnlyTestIdentifiers'))
+
+  def test_without_test_filter_with_test_cases(self):
+    """Ensures tests in the run with no test_filter but test_cases."""
+    self.tr.test_cases = ['a', 'b', 'c', 'd']
+    self.tr.set_xctest_filters(test_filter=None, invert=False)
+    self.assertEqual(
+        self.tr.xctestrun_data['TestTargetName']['OnlyTestIdentifiers'],
+        ['a', 'b', 'c', 'd']
+    )
+
+  def test_invert_without_test_filter_with_test_cases(self):
+    """Ensures tests in the run invert with no test_filter but test_cases."""
+    self.tr.test_cases = ['a', 'b', 'c', 'd']
+    self.tr.set_xctest_filters(test_filter=None, invert=True)
+    self.assertEqual(
+        self.tr.xctestrun_data['TestTargetName']['OnlyTestIdentifiers'],
+        ['a', 'b', 'c', 'd']
+    )
+
+
 if __name__ == '__main__':
   unittest.main()
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index 9afc6dc..4e594159 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -7,6 +7,12 @@
 import("//build/mac/tweak_info_plist.gni")
 import("//ios/build/chrome_build.gni")
 import("//ios/public/provider/chrome/browser/build_config.gni")
+import("//services/service_manager/public/service_manifest.gni")
+
+service_manifest("chrome_browser_manifest_overlay") {
+  source = "//ios/chrome/browser/chrome_browser_manifest_overlay.json"
+  packaged_services = [ "//services/identity:manifest" ]
+}
 
 source_set("app") {
   configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/app/resources/BUILD.gn b/ios/chrome/app/resources/BUILD.gn
index 4b00b0490..28422e4 100644
--- a/ios/chrome/app/resources/BUILD.gn
+++ b/ios/chrome/app/resources/BUILD.gn
@@ -23,10 +23,22 @@
 grit("ios_resources") {
   source = "ios_resources.grd"
   output_dir = "$root_gen_dir/ios/chrome"
+
+  # The .grd contains references to generated files.
+  source_is_generated = true
+
+  grit_flags = [
+    "-E",
+    "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+  ]
+
   outputs = [
     "grit/ios_resources.h",
     "ios_resources.pak",
   ]
+  deps = [
+    "//ios/chrome/app:chrome_browser_manifest_overlay",
+  ]
 }
 
 group("packed_resources") {
diff --git a/ios/chrome/app/resources/ios_resources.grd b/ios/chrome/app/resources/ios_resources.grd
index e09f7010..9c7dbfa 100644
--- a/ios/chrome/app/resources/ios_resources.grd
+++ b/ios/chrome/app/resources/ios_resources.grd
@@ -10,6 +10,7 @@
     <includes>
       <include name="IDR_IOS_OMAHA_HTML" file="omaha/omaha.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
       <include name="IDR_IOS_OMAHA_JS" file="omaha/omaha.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_CHROME_BROWSER_MANIFEST_OVERLAY" file="${root_gen_dir}/ios/chrome/app/chrome_browser_manifest_overlay.json" use_base_dir="false" type="BINDATA" />
     </includes>
   </release>
 </grit>
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS
index 9f73776..40b87c6 100644
--- a/ios/chrome/browser/DEPS
+++ b/ios/chrome/browser/DEPS
@@ -101,6 +101,7 @@
   "+libxml/xmlwriter.h",
   "+net",
   "+rlz/features",
+  "+services/identity/public",
   "+services/metrics/public",
   "+services/service_manager/public",
   "+third_party/breakpad/breakpad/src/client/ios",
diff --git a/ios/chrome/browser/OWNERS b/ios/chrome/browser/OWNERS
index 0adc841..fb1f7390 100644
--- a/ios/chrome/browser/OWNERS
+++ b/ios/chrome/browser/OWNERS
@@ -5,5 +5,8 @@
 
 per-file ios_chrome_flag_descriptions.*=*
 
+per-file chrome_browser_manifest_overlay.json=set noparent
+per-file chrome_browser_manifest_overlay.json=file://ipc/SECURITY_OWNERS
+
 # TEAM: ios-directory-owners@chromium.org
 # OS: iOS
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index b759fc37..fe318df 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -184,10 +184,6 @@
     {"ios-share-canonical-url", flag_descriptions::kShareCanonicalURLName,
      flag_descriptions::kShareCanonicalURLDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(activity_services::kShareCanonicalURL)},
-    {"property-animations-toolbar",
-     flag_descriptions::kPropertyAnimationsToolbarName,
-     flag_descriptions::kPropertyAnimationsToolbarDescription, flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(kPropertyAnimationsToolbar)},
     {"new-fullscreen-controller", flag_descriptions::kNewFullscreenName,
      flag_descriptions::kNewFullscreenDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(fullscreen::features::kNewFullscreen)},
diff --git a/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h b/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h
index 9ccf98b..f13d81f5 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h
+++ b/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h
@@ -29,9 +29,8 @@
       ios::ChromeBrowserState* browser_state);
   static AutocompleteClassifierFactory* GetInstance();
 
-  // Returns the default factory used to build AutocompleteClassifier. Can be
-  // registered with SetTestingFactory to use the AutocompleteClassifier
-  // instance during testing.
+  // Returns the default factory used to build AutocompleteClassifiers. Can be
+  // registered with SetTestingFactory to use real instances during testing.
   static TestingFactoryFunction GetDefaultFactory();
 
  private:
diff --git a/ios/chrome/browser/autocomplete/in_memory_url_index_factory.h b/ios/chrome/browser/autocomplete/in_memory_url_index_factory.h
index 75d4054..be1f98e 100644
--- a/ios/chrome/browser/autocomplete/in_memory_url_index_factory.h
+++ b/ios/chrome/browser/autocomplete/in_memory_url_index_factory.h
@@ -29,9 +29,8 @@
       ios::ChromeBrowserState* browser_state);
   static InMemoryURLIndexFactory* GetInstance();
 
-  // Returns the default factory used to build InMemoryURLIndex. Can be
-  // registered with SetTestingFactory to use the InMemoryURLIndex instance
-  // during testing.
+  // Returns the default factory used to build InMemoryURLIndexs. Can be
+  // registered with SetTestingFactory to use real instances during testing.
   static TestingFactoryFunction GetDefaultFactory();
 
  private:
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn
index c0a98a2..9d9c24f 100644
--- a/ios/chrome/browser/browser_state/BUILD.gn
+++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -84,6 +84,7 @@
     "//ios/chrome/browser/content_settings",
     "//ios/chrome/browser/desktop_promotion",
     "//ios/chrome/browser/dom_distiller",
+    "//ios/chrome/browser/download",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/feature_engagement",
     "//ios/chrome/browser/google",
@@ -185,3 +186,25 @@
 
   configs += [ "//build/config/compiler:enable_arc" ]
 }
+
+source_set("eg_tests") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  testonly = true
+  sources = [
+    "browser_state_services_egtest.mm",
+  ]
+  deps = [
+    ":browser_state",
+    "//base",
+    "//base/test:test_support",
+    "//ios/chrome/test/app:test_support",
+    "//ios/chrome/test/earl_grey:test_support",
+    "//ios/testing:ios_test_support",
+    "//ios/testing/earl_grey:earl_grey_support",
+    "//ios/third_party/earl_grey:earl_grey+link",
+    "//ios/web:earl_grey_test_support",
+    "//ios/web/public",
+    "//services/identity/public/interfaces",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
index 9b47482d..14de103 100644
--- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
+++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -14,6 +14,7 @@
 #include "ios/chrome/browser/content_settings/cookie_settings_factory.h"
 #include "ios/chrome/browser/desktop_promotion/desktop_promotion_sync_service_factory.h"
 #include "ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h"
+#include "ios/chrome/browser/download/browser_download_service_factory.h"
 #include "ios/chrome/browser/favicon/favicon_service_factory.h"
 #include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
 #include "ios/chrome/browser/favicon/ios_chrome_large_icon_cache_factory.h"
@@ -123,6 +124,7 @@
   TabRestoreServiceDelegateImplIOSFactory::GetInstance();
   TranslateAcceptLanguagesFactory::GetInstance();
   UrlLanguageHistogramFactory::GetInstance();
+  BrowserDownloadServiceFactory::GetInstance();
   if (base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) {
     FullscreenControllerFactory::GetInstance();
   }
diff --git a/ios/chrome/browser/browser_state/browser_state_services_egtest.mm b/ios/chrome/browser/browser_state/browser_state_services_egtest.mm
new file mode 100644
index 0000000..f2de039
--- /dev/null
+++ b/ios/chrome/browser/browser_state/browser_state_services_egtest.mm
@@ -0,0 +1,75 @@
+// 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 <EarlGrey/EarlGrey.h>
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#import "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/chrome/test/app/chrome_test_util.h"
+#import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/wait_util.h"
+#include "ios/web/public/browser_state.h"
+#include "ios/web/public/service_manager_connection.h"
+#include "services/identity/public/interfaces/constants.mojom.h"
+#include "services/identity/public/interfaces/identity_manager.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// Callback passed to identity::mojom::IdentityManager::GetPrimaryAccountInfo().
+// Sets |echo_callback_called_flag| to true to indicate that the callback was
+// invoked.
+void OnGotPrimaryAccountInfo(
+    bool* get_primary_account_info_callback_called_flag,
+    const base::Optional<AccountInfo>& account_info,
+    const identity::AccountState& account_state) {
+  GREYAssert(!account_info, @"AccountInfo has unexpected value");
+  *get_primary_account_info_callback_called_flag = true;
+}
+
+// Waits until a given callback is invoked (as signalled by that callback
+// setting |callback_called_flag| to true).
+void WaitForCallback(const std::string& callback_name,
+                     bool* callback_called_flag) {
+  GREYCondition* condition =
+      [GREYCondition conditionWithName:@"Wait for callback"
+                                 block:^BOOL {
+                                   return *callback_called_flag;
+                                 }];
+  GREYAssert([condition waitWithTimeout:testing::kWaitForUIElementTimeout],
+             @"Failed waiting for %s callback", callback_name.c_str());
+}
+}
+
+// Tests embedding of various services in ChromeBrowserState.
+@interface BrowserStateServicesTestCase : ChromeTestCase
+@end
+
+@implementation BrowserStateServicesTestCase
+
+// Tests that it is possible to connect to the Identity Service.
+- (void)testConnectionToIdentityService {
+  ios::ChromeBrowserState* browserState =
+      chrome_test_util::GetOriginalBrowserState();
+
+  // Connect to the Identity Service and bind an IdentityManager instance.
+  identity::mojom::IdentityManagerPtr identityManager;
+  web::BrowserState::GetConnectorFor(browserState)
+      ->BindInterface(identity::mojom::kServiceName,
+                      mojo::MakeRequest(&identityManager));
+
+  bool getPrimaryAccountInfoCallbackCalled = false;
+  identityManager->GetPrimaryAccountInfo(base::BindOnce(
+      &OnGotPrimaryAccountInfo, &getPrimaryAccountInfoCallbackCalled));
+
+  WaitForCallback("GetPrimaryAccountInfo",
+                  &getPrimaryAccountInfoCallbackCalled);
+}
+
+@end
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc
index 97f04cea..b19e7296 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc
@@ -31,6 +31,7 @@
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/chrome/browser/prefs/browser_prefs.h"
 #include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h"
+#include "ios/chrome/browser/signin/identity_service_creator.h"
 #include "ios/web/public/web_thread.h"
 
 namespace {
@@ -174,6 +175,13 @@
   return state_path_;
 }
 
+void ChromeBrowserStateImpl::RegisterServices(StaticServiceMap* services) {
+  // TODO(crbug.com/787794): It would be nice to avoid ChromeBrowserState/
+  // Profile needing to know explicitly about every service that it is
+  // embedding.
+  RegisterIdentityServiceForBrowserState(this, services);
+}
+
 void ChromeBrowserStateImpl::SetOffTheRecordChromeBrowserState(
     std::unique_ptr<ios::ChromeBrowserState> otr_state) {
   DCHECK(!otr_state_);
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl.h b/ios/chrome/browser/browser_state/chrome_browser_state_impl.h
index e1b428c4..2647830 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_impl.h
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl.h
@@ -51,6 +51,7 @@
   // BrowserState:
   bool IsOffTheRecord() const override;
   base::FilePath GetStatePath() const override;
+  void RegisterServices(StaticServiceMap* services) override;
 
  private:
   friend class ChromeBrowserStateManagerImpl;
diff --git a/ios/chrome/browser/chrome_browser_manifest_overlay.json b/ios/chrome/browser/chrome_browser_manifest_overlay.json
new file mode 100644
index 0000000..ece7c2a8
--- /dev/null
+++ b/ios/chrome/browser/chrome_browser_manifest_overlay.json
@@ -0,0 +1,11 @@
+{
+  "name": "web_browser",
+  "display_name": "Chrome",
+  "interface_provider_specs": {
+    "service_manager:connector": {
+      "requires": {
+        "identity": [ "identity_manager" ]
+      }
+    }
+  }
+}
diff --git a/ios/chrome/browser/download/BUILD.gn b/ios/chrome/browser/download/BUILD.gn
index 07ded7f..b004d8e 100644
--- a/ios/chrome/browser/download/BUILD.gn
+++ b/ios/chrome/browser/download/BUILD.gn
@@ -4,6 +4,10 @@
 
 source_set("download") {
   sources = [
+    "browser_download_service.h",
+    "browser_download_service.mm",
+    "browser_download_service_factory.h",
+    "browser_download_service_factory.mm",
     "pass_kit_tab_helper.h",
     "pass_kit_tab_helper.mm",
     "pass_kit_tab_helper_delegate.h",
@@ -11,6 +15,9 @@
 
   deps = [
     "//base",
+    "//components/keyed_service/core",
+    "//components/keyed_service/ios",
+    "//ios/chrome/browser/browser_state",
     "//ios/web/public",
     "//ios/web/public/download",
   ]
@@ -24,13 +31,19 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
+    "browser_download_service_factory_unittest.mm",
+    "browser_download_service_unittest.mm",
     "pass_kit_tab_helper_unittest.mm",
   ]
   deps = [
     ":test_support",
     "//base/test:test_support",
+    "//ios/chrome/browser/browser_state:test_support",
     "//ios/chrome/browser/download",
     "//ios/chrome/test/fakes",
+    "//ios/web/public",
+    "//ios/web/public/download",
+    "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//net",
     "//testing/gtest",
diff --git a/ios/chrome/browser/download/browser_download_service.h b/ios/chrome/browser/download/browser_download_service.h
new file mode 100644
index 0000000..cf831f9
--- /dev/null
+++ b/ios/chrome/browser/download/browser_download_service.h
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DOWNLOAD_BROWSER_DOWNLOAD_SERVICE_H_
+#define IOS_CHROME_BROWSER_DOWNLOAD_BROWSER_DOWNLOAD_SERVICE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "ios/web/public/download/download_controller_delegate.h"
+
+namespace web {
+class DownloadController;
+class DownloadTask;
+class WebState;
+}  // namespace web
+
+// Keyed Service which acts as web::DownloadController delegate and routes
+// download tasks to the appropriate TabHelper for download.
+class BrowserDownloadService : public KeyedService,
+                               public web::DownloadControllerDelegate {
+ public:
+  explicit BrowserDownloadService(web::DownloadController* download_controller);
+  ~BrowserDownloadService() override;
+
+ private:
+  // web::DownloadControllerDelegate overrides:
+  void OnDownloadCreated(web::DownloadController*,
+                         web::WebState*,
+                         std::unique_ptr<web::DownloadTask>) override;
+  void OnDownloadControllerDestroyed(web::DownloadController*) override;
+
+  web::DownloadController* download_controller_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(BrowserDownloadService);
+};
+
+#endif  // IOS_CHROME_BROWSER_DOWNLOAD_BROWSER_DOWNLOAD_SERVICE_H_
diff --git a/ios/chrome/browser/download/browser_download_service.mm b/ios/chrome/browser/download/browser_download_service.mm
new file mode 100644
index 0000000..080c650
--- /dev/null
+++ b/ios/chrome/browser/download/browser_download_service.mm
@@ -0,0 +1,50 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/download/browser_download_service.h"
+
+#include "base/feature_list.h"
+#import "ios/chrome/browser/download/pass_kit_tab_helper.h"
+#import "ios/web/public/download/download_controller.h"
+#import "ios/web/public/download/download_task.h"
+#include "ios/web/public/features.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+BrowserDownloadService::BrowserDownloadService(
+    web::DownloadController* download_controller)
+    : download_controller_(download_controller) {
+  DCHECK(!download_controller->GetDelegate());
+  download_controller_->SetDelegate(this);
+}
+
+BrowserDownloadService::~BrowserDownloadService() {
+  if (download_controller_) {
+    DCHECK_EQ(this, download_controller_->GetDelegate());
+    download_controller_->SetDelegate(nullptr);
+  }
+}
+
+void BrowserDownloadService::OnDownloadCreated(
+    web::DownloadController* download_controller,
+    web::WebState* web_state,
+    std::unique_ptr<web::DownloadTask> task) {
+  if (task->GetMimeType() == "application/vnd.apple.pkpass") {
+    if (base::FeatureList::IsEnabled(web::features::kNewPassKitDownload)) {
+      PassKitTabHelper* tab_helper = PassKitTabHelper::FromWebState(web_state);
+      if (tab_helper) {
+        tab_helper->Download(std::move(task));
+      }
+    }
+  }
+}
+
+void BrowserDownloadService::OnDownloadControllerDestroyed(
+    web::DownloadController* download_controller) {
+  DCHECK_EQ(this, download_controller->GetDelegate());
+  download_controller->SetDelegate(nullptr);
+  download_controller_ = nullptr;
+}
diff --git a/ios/chrome/browser/download/browser_download_service_factory.h b/ios/chrome/browser/download/browser_download_service_factory.h
new file mode 100644
index 0000000..cf66a8e
--- /dev/null
+++ b/ios/chrome/browser/download/browser_download_service_factory.h
@@ -0,0 +1,45 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DOWNLOAD_BROWSER_DOWNLOAD_SERVICE_FACTORY_H_
+#define IOS_CHROME_BROWSER_DOWNLOAD_BROWSER_DOWNLOAD_SERVICE_FACTORY_H_
+
+#include "base/macros.h"
+#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
+
+class BrowserDownloadService;
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}  // namespace base
+
+namespace web {
+class BrowserState;
+}  // namespace web
+
+// Singleton that creates BrowserDownloadService and associates that service
+// with web::BrowserState.
+class BrowserDownloadServiceFactory : public BrowserStateKeyedServiceFactory {
+ public:
+  static BrowserDownloadService* GetForBrowserState(
+      web::BrowserState* browser_state);
+  static BrowserDownloadServiceFactory* GetInstance();
+
+ private:
+  friend struct base::DefaultSingletonTraits<BrowserDownloadServiceFactory>;
+
+  BrowserDownloadServiceFactory();
+  ~BrowserDownloadServiceFactory() override;
+
+  // BrowserStateKeyedServiceFactory overrides:
+  std::unique_ptr<KeyedService> BuildServiceInstanceFor(
+      web::BrowserState* context) const override;
+  bool ServiceIsCreatedWithBrowserState() const override;
+  web::BrowserState* GetBrowserStateToUse(web::BrowserState*) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(BrowserDownloadServiceFactory);
+};
+
+#endif  // IOS_CHROME_BROWSER_DOWNLOAD_BROWSER_DOWNLOAD_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/download/browser_download_service_factory.mm b/ios/chrome/browser/download/browser_download_service_factory.mm
new file mode 100644
index 0000000..e0c9465b
--- /dev/null
+++ b/ios/chrome/browser/download/browser_download_service_factory.mm
@@ -0,0 +1,51 @@
+// 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/chrome/browser/download/browser_download_service_factory.h"
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/ios/browser_state_dependency_manager.h"
+#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
+#include "ios/chrome/browser/download/browser_download_service.h"
+#import "ios/web/public/download/download_controller.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+// static
+BrowserDownloadService* BrowserDownloadServiceFactory::GetForBrowserState(
+    web::BrowserState* browser_state) {
+  return static_cast<BrowserDownloadService*>(
+      GetInstance()->GetServiceForBrowserState(browser_state, /*create=*/true));
+}
+
+// static
+BrowserDownloadServiceFactory* BrowserDownloadServiceFactory::GetInstance() {
+  return base::Singleton<BrowserDownloadServiceFactory>::get();
+}
+
+BrowserDownloadServiceFactory::BrowserDownloadServiceFactory()
+    : BrowserStateKeyedServiceFactory(
+          "BrowserDownloadService",
+          BrowserStateDependencyManager::GetInstance()) {}
+
+BrowserDownloadServiceFactory::~BrowserDownloadServiceFactory() = default;
+
+std::unique_ptr<KeyedService>
+BrowserDownloadServiceFactory::BuildServiceInstanceFor(
+    web::BrowserState* browser_state) const {
+  web::DownloadController* download_controller =
+      web::DownloadController::FromBrowserState(browser_state);
+  return std::make_unique<BrowserDownloadService>(download_controller);
+}
+
+bool BrowserDownloadServiceFactory::ServiceIsCreatedWithBrowserState() const {
+  return true;
+}
+
+web::BrowserState* BrowserDownloadServiceFactory::GetBrowserStateToUse(
+    web::BrowserState* browser_state) const {
+  return GetBrowserStateOwnInstanceInIncognito(browser_state);
+}
diff --git a/ios/chrome/browser/download/browser_download_service_factory_unittest.mm b/ios/chrome/browser/download/browser_download_service_factory_unittest.mm
new file mode 100644
index 0000000..401213c
--- /dev/null
+++ b/ios/chrome/browser/download/browser_download_service_factory_unittest.mm
@@ -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.
+
+#include "ios/chrome/browser/download/browser_download_service_factory.h"
+
+#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+#include "ios/chrome/browser/download/browser_download_service.h"
+#import "ios/web/public/download/download_controller.h"
+#include "ios/web/public/test/test_web_thread_bundle.h"
+#include "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+// Test fixture for testing BrowserDownloadServiceFactory class.
+class BrowserDownloadServiceFactoryTest : public PlatformTest {
+ protected:
+  BrowserDownloadServiceFactoryTest()
+      : browser_state_(browser_state_builder_.Build()) {}
+  web::TestWebThreadBundle thread_bundle_;  // ChromeBrowserState needs thread.
+  TestChromeBrowserState::Builder browser_state_builder_;
+  std::unique_ptr<TestChromeBrowserState> browser_state_;
+};
+
+// Tests that BrowserDownloadServiceFactory creates BrowserDownloadService and
+// sets it as DownloadControllerDelegate.
+TEST_F(BrowserDownloadServiceFactoryTest, Delegate) {
+  web::DownloadController* download_controller =
+      web::DownloadController::FromBrowserState(browser_state_.get());
+  ASSERT_TRUE(download_controller);
+
+  BrowserDownloadService* service =
+      BrowserDownloadServiceFactory::GetForBrowserState(browser_state_.get());
+  EXPECT_EQ(service, download_controller->GetDelegate());
+}
diff --git a/ios/chrome/browser/download/browser_download_service_unittest.mm b/ios/chrome/browser/download/browser_download_service_unittest.mm
new file mode 100644
index 0000000..ccef526
--- /dev/null
+++ b/ios/chrome/browser/download/browser_download_service_unittest.mm
@@ -0,0 +1,121 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/download/browser_download_service.h"
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
+#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+#import "ios/chrome/browser/download/pass_kit_tab_helper.h"
+#import "ios/web/public/download/download_controller.h"
+#import "ios/web/public/download/download_task.h"
+#include "ios/web/public/features.h"
+#import "ios/web/public/test/fakes/fake_download_task.h"
+#import "ios/web/public/test/fakes/test_web_state.h"
+#include "ios/web/public/test/test_web_thread_bundle.h"
+#include "testing/platform_test.h"
+#include "url/gurl.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+char kUrl[] = "https://test.test/";
+char kMimeType[] = "application/vnd.apple.pkpass";
+
+// Fake Tab Helper that substitutes real PassKitTabHelper for testing.
+class StubPassKitTabHelper : public PassKitTabHelper {
+ public:
+  static void CreateForWebState(web::WebState* web_state) {
+    web_state->SetUserData(
+        UserDataKey(), base::WrapUnique(new StubPassKitTabHelper(web_state)));
+  }
+
+  // Adds the given task to tasks() lists.
+  void Download(std::unique_ptr<web::DownloadTask> task) override {
+    tasks_.push_back(std::move(task));
+  }
+
+  // Tasks added via Download() call.
+  using DownloadTasks = std::vector<std::unique_ptr<web::DownloadTask>>;
+  const DownloadTasks& tasks() const { return tasks_; }
+
+ private:
+  StubPassKitTabHelper(web::WebState* web_state)
+      : PassKitTabHelper(web_state, /*delegate=*/nil) {}
+
+  DownloadTasks tasks_;
+
+  DISALLOW_COPY_AND_ASSIGN(StubPassKitTabHelper);
+};
+
+}  // namespace
+
+// Test fixture for testing BrowserDownloadService class.
+class BrowserDownloadServiceTest : public PlatformTest {
+ protected:
+  BrowserDownloadServiceTest()
+      : browser_state_(browser_state_builder_.Build()) {
+    feature_list_.InitAndEnableFeature(web::features::kNewPassKitDownload);
+    StubPassKitTabHelper::CreateForWebState(&web_state_);
+
+    // BrowserDownloadServiceFactory sets its service as
+    // DownloadControllerDelegate. These test use separate
+    // BrowserDownloadService, not created by factory. So delegate
+    // is temporary removed for these tests to avoid DCHECKs.
+    previous_delegate_ = download_controller()->GetDelegate();
+    download_controller()->SetDelegate(nullptr);
+    service_ = std::make_unique<BrowserDownloadService>(download_controller());
+  }
+
+  ~BrowserDownloadServiceTest() override {
+    service_.reset();
+    // Return back the original delegate so service created by service factory
+    // can be destructed without DCHECKs.
+    download_controller()->SetDelegate(previous_delegate_);
+  }
+
+  web::DownloadController* download_controller() {
+    return web::DownloadController::FromBrowserState(browser_state_.get());
+  }
+
+  StubPassKitTabHelper* pass_kit_tab_helper() {
+    return static_cast<StubPassKitTabHelper*>(
+        PassKitTabHelper::FromWebState(&web_state_));
+  }
+
+  web::DownloadControllerDelegate* previous_delegate_;
+  web::TestWebThreadBundle thread_bundle_;
+  TestChromeBrowserState::Builder browser_state_builder_;
+  std::unique_ptr<TestChromeBrowserState> browser_state_;
+  std::unique_ptr<BrowserDownloadService> service_;
+  web::TestWebState web_state_;
+  base::test::ScopedFeatureList feature_list_;
+};
+
+// Tests that BrowserDownloadService downloads the task using
+// PassKitTabHelper.
+TEST_F(BrowserDownloadServiceTest, PkPassMimeType) {
+  ASSERT_TRUE(download_controller()->GetDelegate());
+  auto task = std::make_unique<web::FakeDownloadTask>(GURL(kUrl), kMimeType);
+  web::DownloadTask* task_ptr = task.get();
+  download_controller()->GetDelegate()->OnDownloadCreated(
+      download_controller(), &web_state_, std::move(task));
+  ASSERT_EQ(1U, pass_kit_tab_helper()->tasks().size());
+  EXPECT_EQ(task_ptr, pass_kit_tab_helper()->tasks()[0].get());
+}
+
+// Tests that BrowserDownloadService does not use PassKitTabHelper for pdf
+// Mime Type.
+TEST_F(BrowserDownloadServiceTest, PdfMimeType) {
+  ASSERT_TRUE(download_controller()->GetDelegate());
+  auto task =
+      std::make_unique<web::FakeDownloadTask>(GURL(kUrl), "application/pdf");
+  download_controller()->GetDelegate()->OnDownloadCreated(
+      download_controller(), &web_state_, std::move(task));
+  ASSERT_TRUE(pass_kit_tab_helper()->tasks().empty());
+}
diff --git a/ios/chrome/browser/download/pass_kit_tab_helper.mm b/ios/chrome/browser/download/pass_kit_tab_helper.mm
index 494b926..28ff215 100644
--- a/ios/chrome/browser/download/pass_kit_tab_helper.mm
+++ b/ios/chrome/browser/download/pass_kit_tab_helper.mm
@@ -24,7 +24,6 @@
                                    id<PassKitTabHelperDelegate> delegate)
     : web_state_(web_state), delegate_(delegate) {
   DCHECK(web_state_);
-  DCHECK(delegate_);
 }
 
 PassKitTabHelper::~PassKitTabHelper() {
diff --git a/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h b/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h
index 0d53e2f3..df2fa12 100644
--- a/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h
+++ b/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h
@@ -35,9 +35,8 @@
 
   static IOSChromeLargeIconServiceFactory* GetInstance();
 
-  // Returns the default factory used to build IOSChromeLargeIconServiceFactory.
-  // Can be registered with SetTestingFactory to use the
-  // IOSChromeLargeIconServiceFactory instance during testing.
+  // Returns the default factory used to build LargeIconServices. Can be
+  // registered with SetTestingFactory to use real instances during testing.
   static TestingFactoryFunction GetDefaultFactory();
 
  private:
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index a871e0b..e289a05 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -94,12 +94,6 @@
     "When enabled, the omnibox will include suggestions for web pages "
     "broadcast by devices near you.";
 
-const char kPropertyAnimationsToolbarName[] =
-    "UIViewPropertyAnimator Animated Toolbar";
-const char kPropertyAnimationsToolbarDescription[] =
-    "When enabled, Toolbar animations will be done using "
-    "UIViewPropertyAnimator";
-
 const char kSafeAreaCompatibleToolbarName[] = "Safe Area Compatible Toolbar";
 const char kSafeAreaCompatibleToolbarDescription[] =
     "When enabled, the toolbar resizes itself when the safe area changes.";
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index 2aabe1400..63c318a7 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -85,11 +85,6 @@
 extern const char kPhysicalWeb[];
 extern const char kPhysicalWebDescription[];
 
-// Title and description for the flag to have the toolbar use
-// UIViewPropertyAnimators.
-extern const char kPropertyAnimationsToolbarName[];
-extern const char kPropertyAnimationsToolbarDescription[];
-
 // Title and description for the flag to have the toolbar respect the safe area.
 extern const char kSafeAreaCompatibleToolbarName[];
 extern const char kSafeAreaCompatibleToolbarDescription[];
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc
index 6a4ce826..c2467bc 100644
--- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc
+++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc
@@ -21,12 +21,6 @@
 using ntp_snippets::ContentSuggestionsService;
 
 // static
-IOSChromeContentSuggestionsServiceFactory*
-IOSChromeContentSuggestionsServiceFactory::GetInstance() {
-  return base::Singleton<IOSChromeContentSuggestionsServiceFactory>::get();
-}
-
-// static
 ContentSuggestionsService*
 IOSChromeContentSuggestionsServiceFactory::GetForBrowserState(
     ios::ChromeBrowserState* browser_state) {
@@ -36,6 +30,12 @@
 }
 
 // static
+IOSChromeContentSuggestionsServiceFactory*
+IOSChromeContentSuggestionsServiceFactory::GetInstance() {
+  return base::Singleton<IOSChromeContentSuggestionsServiceFactory>::get();
+}
+
+// static
 BrowserStateKeyedServiceFactory::TestingFactoryFunction
 IOSChromeContentSuggestionsServiceFactory::GetDefaultFactory() {
   return &ntp_snippets::CreateChromeContentSuggestionsServiceWithProviders;
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h
index 5fa8687..587474c 100644
--- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h
+++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h
@@ -28,12 +28,13 @@
 class IOSChromeContentSuggestionsServiceFactory
     : public BrowserStateKeyedServiceFactory {
  public:
-  static IOSChromeContentSuggestionsServiceFactory* GetInstance();
   static ntp_snippets::ContentSuggestionsService* GetForBrowserState(
       ios::ChromeBrowserState* browser_state);
-  // Returns the default factory used to build ContentSuggestionsService. Can be
-  // registered with SetTestingFactory to use the ContentSuggestionsService
-  // instance during testing.
+
+  static IOSChromeContentSuggestionsServiceFactory* GetInstance();
+
+  // Returns the default factory used to build ContentSuggestionsServices. Can
+  // be registered with SetTestingFactory to use real instances during testing.
   static TestingFactoryFunction GetDefaultFactory();
 
  private:
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
index d9f8707..59396510 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
@@ -88,7 +88,6 @@
   const password_manager::CredentialsFilter* GetStoreResultFilter()
       const override;
   const password_manager::LogManager* GetLogManager() const override;
-  ukm::UkmRecorder* GetUkmRecorder() override;
   ukm::SourceId GetUkmSourceId() override;
   password_manager::PasswordManagerMetricsRecorder& GetMetricsRecorder()
       override;
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
index c08e1f7..215da21 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
@@ -182,17 +182,14 @@
   return log_manager_.get();
 }
 
-ukm::UkmRecorder* IOSChromePasswordManagerClient::GetUkmRecorder() {
-  return GetApplicationContext()->GetUkmRecorder();
-}
-
 ukm::SourceId IOSChromePasswordManagerClient::GetUkmSourceId() {
-  // TODO(crbug.com/732846): The UKM Source should be recycled (e.g. from the
-  // web contents), once the UKM framework provides a mechanism for that.
+  // TODO(crbug.com/792662): Update this to get a shared UKM SourceId (e.g.
+  // from web state), once the UKM framework provides a mechanism for that.
   if (ukm_source_url_ != delegate_.lastCommittedURL) {
     metrics_recorder_.reset();
     ukm_source_url_ = delegate_.lastCommittedURL;
     ukm_source_id_ = ukm::UkmRecorder::GetNewSourceID();
+    ukm::UkmRecorder::Get()->UpdateSourceURL(ukm_source_id_, ukm_source_url_);
   }
   return ukm_source_id_;
 }
@@ -203,7 +200,7 @@
     // Query source_id first, because that has the side effect of initializing
     // |ukm_source_url_|.
     ukm::SourceId source_id = GetUkmSourceId();
-    metrics_recorder_.emplace(GetUkmRecorder(), source_id, ukm_source_url_);
+    metrics_recorder_.emplace(source_id, ukm_source_url_);
   }
   return metrics_recorder_.value();
 }
diff --git a/ios/chrome/browser/prerender/BUILD.gn b/ios/chrome/browser/prerender/BUILD.gn
index 4e82c93..64f3b1c 100644
--- a/ios/chrome/browser/prerender/BUILD.gn
+++ b/ios/chrome/browser/prerender/BUILD.gn
@@ -55,3 +55,22 @@
     "//testing/gtest",
   ]
 }
+source_set("eg_tests") {
+  testonly = true
+  sources = [
+    "prerender_egtest.mm",
+  ]
+  deps = [
+    "//base",
+    "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant",
+    "//ios/chrome/browser/ui/omnibox:omnibox_internal",
+    "//ios/chrome/test/app:test_support",
+    "//ios/chrome/test/earl_grey:test_support",
+    "//ios/web/public/test/http_server",
+  ]
+  libs = [
+    "UIKit.framework",
+    "XCTest.framework",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
diff --git a/ios/chrome/browser/prerender/prerender_egtest.mm b/ios/chrome/browser/prerender/prerender_egtest.mm
new file mode 100644
index 0000000..5bbcbe8
--- /dev/null
+++ b/ios/chrome/browser/prerender/prerender_egtest.mm
@@ -0,0 +1,104 @@
+// 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 <EarlGrey/EarlGrey.h>
+#import <XCTest/XCTest.h>
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/sys_string_conversions.h"
+#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
+#import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
+#import "ios/chrome/browser/ui/omnibox/truncating_attributed_label.h"
+#import "ios/chrome/test/app/history_test_util.h"
+#import "ios/chrome/test/app/tab_test_util.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_matchers.h"
+#import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+const char kPageURL[] = "/test-page.html";
+const char kPageTitle[] = "Page title!";
+const char kPageLoadedString[] = "Page loaded!";
+
+// Provides responses for redirect and changed window location URLs.
+std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
+    const net::test_server::HttpRequest& request) {
+  if (request.relative_url != kPageURL) {
+    return nullptr;
+  }
+  std::unique_ptr<net::test_server::BasicHttpResponse> http_response =
+      std::make_unique<net::test_server::BasicHttpResponse>();
+  http_response->set_code(net::HTTP_OK);
+  http_response->set_content("<html><head><title>" + std::string(kPageTitle) +
+                             "</title></head><body>" +
+                             std::string(kPageLoadedString) + "</body></html>");
+  return std::move(http_response);
+}
+}  // namespace
+
+// Test case for the prerender.
+@interface PrerenderTestCase : ChromeTestCase
+
+@end
+
+@implementation PrerenderTestCase
+
+// Test that tapping the prerendered suggestions opens it.
+- (void)testTapPrerenderSuggestions {
+  chrome_test_util::ClearBrowsingHistory();
+  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
+  // Set server up.
+  self.testServer->RegisterRequestHandler(
+      base::BindRepeating(&StandardResponse));
+  GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
+  const GURL pageURL = self.testServer->GetURL(kPageURL);
+  NSString* pageString = base::SysUTF8ToNSString(pageURL.GetContent());
+
+  // Go to the page a couple of time so it shows as suggestion.
+  [ChromeEarlGrey loadURL:pageURL];
+  [ChromeEarlGrey goBack];
+  [[self class] closeAllTabs];
+  chrome_test_util::OpenNewTab();
+  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
+
+  [[EarlGrey
+      selectElementWithMatcher:grey_accessibilityID(
+                                   ntp_home::FakeOmniboxAccessibilityID())]
+      performAction:grey_typeText([pageString stringByAppendingString:@"\n"])];
+  [ChromeEarlGrey waitForPageToFinishLoading];
+  [[self class] closeAllTabs];
+  chrome_test_util::OpenNewTab();
+  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
+
+  // Type the begining of the address to have the autocomplete suggestion.
+  [[EarlGrey
+      selectElementWithMatcher:grey_accessibilityID(
+                                   ntp_home::FakeOmniboxAccessibilityID())]
+      performAction:grey_typeText(
+                        [pageString substringToIndex:[pageString length] - 6])];
+
+  // Make sure the omnibox is autocompleted.
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityLabel(pageString),
+                                          grey_ancestor(grey_kindOfClass(
+                                              [OmniboxTextFieldIOS class])),
+                                          nil)]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Open the suggestion.
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(
+                                   grey_accessibilityLabel(pageString),
+                                   grey_kindOfClass(
+                                       [OmniboxPopupTruncatingLabel class]),
+                                   nil)] performAction:grey_tap()];
+}
+
+@end
diff --git a/ios/chrome/browser/search_engines/template_url_service_factory.h b/ios/chrome/browser/search_engines/template_url_service_factory.h
index ac819c8..23445073 100644
--- a/ios/chrome/browser/search_engines/template_url_service_factory.h
+++ b/ios/chrome/browser/search_engines/template_url_service_factory.h
@@ -27,11 +27,11 @@
  public:
   static TemplateURLService* GetForBrowserState(
       ios::ChromeBrowserState* browser_state);
+
   static TemplateURLServiceFactory* GetInstance();
 
-  // Returns the default factory used to build TemplateURLService. Can be
-  // registered with SetTestingFactory to use the TemplateURLService instance
-  // during testing.
+  // Returns the default factory used to build TemplateURLServices. Can be
+  // registered with SetTestingFactory to use real instances during testing.
   static TestingFactoryFunction GetDefaultFactory();
 
  private:
diff --git a/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h b/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h
index 73daf12..a65c1d50 100644
--- a/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h
+++ b/ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h
@@ -33,9 +33,8 @@
 
   static IOSChromeTabRestoreServiceFactory* GetInstance();
 
-  // Returns the default factory used to build TabRestoreService. Can be
-  // registered with SetTestingFactory to use the TabRestoreService instance
-  // during testing.
+  // Returns the default factory used to build TabRestoreServices. Can be
+  // registered with SetTestingFactory to use real instances during testing.
   static TestingFactoryFunction GetDefaultFactory();
 
  private:
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn
index 8d5782c46..795b5ef 100644
--- a/ios/chrome/browser/signin/BUILD.gn
+++ b/ios/chrome/browser/signin/BUILD.gn
@@ -30,6 +30,8 @@
     "gaia_auth_fetcher_ios_private.h",
     "gaia_cookie_manager_service_factory.cc",
     "gaia_cookie_manager_service_factory.h",
+    "identity_service_creator.cc",
+    "identity_service_creator.h",
     "ios_chrome_signin_client.h",
     "ios_chrome_signin_client.mm",
     "ios_chrome_signin_status_metrics_provider_delegate.cc",
@@ -74,6 +76,8 @@
     "//ios/public/provider/chrome/browser/signin",
     "//ios/web",
     "//net",
+    "//services/identity:lib",
+    "//services/identity/public/interfaces",
     "//url",
   ]
 }
diff --git a/ios/chrome/browser/signin/DEPS b/ios/chrome/browser/signin/DEPS
new file mode 100644
index 0000000..a5ba9e61
--- /dev/null
+++ b/ios/chrome/browser/signin/DEPS
@@ -0,0 +1,7 @@
+specific_include_rules = {
+  # The dependence on the Identity Service implementation should be used *only*
+  # for Identity Service creation.
+  "identity_service_creator.cc": [
+    "+services/identity/identity_service.h",
+  ],
+}
diff --git a/ios/chrome/browser/signin/identity_service_creator.cc b/ios/chrome/browser/signin/identity_service_creator.cc
new file mode 100644
index 0000000..ca1787f
--- /dev/null
+++ b/ios/chrome/browser/signin/identity_service_creator.cc
@@ -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/chrome/browser/signin/identity_service_creator.h"
+
+#include "components/signin/core/browser/signin_manager.h"
+#include "ios/chrome/browser/signin/account_tracker_service_factory.h"
+#include "ios/chrome/browser/signin/oauth2_token_service_factory.h"
+#include "ios/chrome/browser/signin/signin_manager_factory.h"
+#include "services/identity/identity_service.h"
+#include "services/identity/public/interfaces/constants.mojom.h"
+
+namespace {
+
+// Creates an instance of the Identity Service for
+// |browser_state|, populating it with the appropriate instances of
+// its dependencies.
+std::unique_ptr<service_manager::Service> CreateIdentityService(
+    ios::ChromeBrowserState* browser_state) {
+  AccountTrackerService* account_tracker =
+      ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state);
+  SigninManagerBase* signin_manager =
+      ios::SigninManagerFactory::GetForBrowserState(browser_state);
+  ProfileOAuth2TokenService* token_service =
+      OAuth2TokenServiceFactory::GetForBrowserState(browser_state);
+  return base::MakeUnique<identity::IdentityService>(
+      account_tracker, signin_manager, token_service);
+}
+
+}  //  namespace
+
+void RegisterIdentityServiceForBrowserState(
+    ios::ChromeBrowserState* browser_state,
+    web::BrowserState::StaticServiceMap* services) {
+  service_manager::EmbeddedServiceInfo identity_service_info;
+
+  // The Identity Service must run on the UI thread.
+  identity_service_info.task_runner = base::ThreadTaskRunnerHandle::Get();
+
+  // NOTE: The dependencies of the Identity Service have not yet been created,
+  // so it is not possible to bind them here. Instead, bind them at the time
+  // of the actual request to create the Identity Service.
+  identity_service_info.factory = base::BindRepeating(
+      &CreateIdentityService, base::Unretained(browser_state));
+  services->insert(
+      std::make_pair(identity::mojom::kServiceName, identity_service_info));
+}
diff --git a/ios/chrome/browser/signin/identity_service_creator.h b/ios/chrome/browser/signin/identity_service_creator.h
new file mode 100644
index 0000000..e8950830
--- /dev/null
+++ b/ios/chrome/browser/signin/identity_service_creator.h
@@ -0,0 +1,16 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SIGNIN_IDENTITY_SERVICE_CREATOR_H_
+#define IOS_CHROME_BROWSER_SIGNIN_IDENTITY_SERVICE_CREATOR_H_
+
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+
+// Registers an Identity Service factory function associated with
+// |browser_state| in the given service map.
+void RegisterIdentityServiceForBrowserState(
+    ios::ChromeBrowserState* browser_state,
+    web::BrowserState::StaticServiceMap* services);
+
+#endif  // IOS_CHROME_BROWSER_SIGNIN_IDENTITY_SERVICE_CREATOR_H_
diff --git a/ios/chrome/browser/snapshots/BUILD.gn b/ios/chrome/browser/snapshots/BUILD.gn
index dd06c93..f40fd7f 100644
--- a/ios/chrome/browser/snapshots/BUILD.gn
+++ b/ios/chrome/browser/snapshots/BUILD.gn
@@ -16,8 +16,6 @@
     "snapshot_cache_web_state_list_observer.mm",
     "snapshot_constants.h",
     "snapshot_constants.mm",
-    "snapshot_manager.h",
-    "snapshot_manager.mm",
     "snapshot_overlay.h",
     "snapshot_overlay.mm",
     "snapshots_util.h",
@@ -59,13 +57,14 @@
 source_set("snapshots_internal") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "snapshot_generator.h",
+    "snapshot_generator.mm",
     "snapshot_overlay_provider.h",
-    "web_controller_snapshot_helper.h",
-    "web_controller_snapshot_helper.mm",
   ]
   deps = [
     ":snapshots",
     "//base",
+    "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/tabs",
     "//ios/chrome/browser/ui",
     "//ios/web",
diff --git a/ios/chrome/browser/snapshots/DEPS b/ios/chrome/browser/snapshots/DEPS
index 9b32181..fc8690140 100644
--- a/ios/chrome/browser/snapshots/DEPS
+++ b/ios/chrome/browser/snapshots/DEPS
@@ -1,6 +1,6 @@
 specific_include_rules = {
   # TODO(crbug.com/620089): Remove this exception.
-  "^web_controller_snapshot_helper\.mm$": [
+  "^snapshot_generator\.mm$": [
     "+ios/web/web_state/ui/crw_web_controller.h",
   ],
 }
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_factory.h b/ios/chrome/browser/snapshots/snapshot_cache_factory.h
index b3bc571..1111a92 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache_factory.h
+++ b/ios/chrome/browser/snapshots/snapshot_cache_factory.h
@@ -30,6 +30,10 @@
 
   static SnapshotCacheFactory* GetInstance();
 
+  // Returns the default factory used to build SnapshotCaches. Can be
+  // registered with SetTestingFactory to use real instances during testing.
+  static TestingFactoryFunction GetDefaultFactory();
+
  private:
   friend struct base::DefaultSingletonTraits<SnapshotCacheFactory>;
 
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_factory.mm b/ios/chrome/browser/snapshots/snapshot_cache_factory.mm
index b18a0a2..5fa9e44e 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache_factory.mm
+++ b/ios/chrome/browser/snapshots/snapshot_cache_factory.mm
@@ -49,7 +49,11 @@
   [snapshot_cache_ shutdown];
   snapshot_cache_ = nil;
 }
+
+std::unique_ptr<KeyedService> BuildSnapshotCacheWrapper(web::BrowserState*) {
+  return std::make_unique<SnapshotCacheWrapper>([[SnapshotCache alloc] init]);
 }
+}  // namespace
 
 // static
 SnapshotCache* SnapshotCacheFactory::GetForBrowserState(
@@ -64,6 +68,12 @@
   return base::Singleton<SnapshotCacheFactory>::get();
 }
 
+// static
+BrowserStateKeyedServiceFactory::TestingFactoryFunction
+SnapshotCacheFactory::GetDefaultFactory() {
+  return &BuildSnapshotCacheWrapper;
+}
+
 SnapshotCacheFactory::SnapshotCacheFactory()
     : BrowserStateKeyedServiceFactory(
           "SnapshotCache",
@@ -73,7 +83,7 @@
 
 std::unique_ptr<KeyedService> SnapshotCacheFactory::BuildServiceInstanceFor(
     web::BrowserState* context) const {
-  return base::MakeUnique<SnapshotCacheWrapper>([[SnapshotCache alloc] init]);
+  return BuildSnapshotCacheWrapper(context);
 }
 
 web::BrowserState* SnapshotCacheFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.h b/ios/chrome/browser/snapshots/snapshot_generator.h
new file mode 100644
index 0000000..dfaa95c4
--- /dev/null
+++ b/ios/chrome/browser/snapshots/snapshot_generator.h
@@ -0,0 +1,59 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_GENERATOR_H_
+#define IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_GENERATOR_H_
+
+#import <UIKit/UIKit.h>
+
+@class SnapshotOverlay;
+@class Tab;
+
+// A class that takes care of creating, storing and returning snapshots of a
+// tab's web page.
+@interface SnapshotGenerator : NSObject
+
+// Designated initializer. |tab| must not be nil.
+// TODO(crbug.com/380819): Replace the need to use Tab directly here by using a
+// delegate pattern.
+- (instancetype)initWithTab:(Tab*)tab NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
+// If |snapshotCoalescingEnabled| is YES snapshots of the web page are
+// coalesced until this method is called with |snapshotCoalescingEnabled| set to
+// NO. When snapshot coalescing is enabled, mutiple calls to generate a snapshot
+// with the same parameters may be coalesced.
+- (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled;
+
+// Gets a color snapshot for the current page, calling |callback| once it has
+// been retrieved or regenerated. |overlays| is the array of SnapshotOverlay
+// objects (views currently overlayed), can be nil.
+- (void)retrieveSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                            callback:(void (^)(UIImage*))callback;
+
+// Gets a grey snapshot for the current page, calling |callback| once it has
+// been retrieved or regenerated. |overlays| is the array of SnapshotOverlay
+// objects (views currently overlayed), can be nil.
+- (void)retrieveGreySnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                                callback:(void (^)(UIImage*))callback;
+
+// Invalidates the cached snapshot for the current page, generates and caches
+// a new snapshot. Returns the snapshot with or without the overlayed views
+// (e.g. infobar, voice search button, etc.), and either of the visible frame
+// or of the full screen. |overlays| is the array of SnapshotOverlay objects
+// (views currently overlayed), can be nil.
+- (UIImage*)updateSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                      visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+// Generates a new snapshot for the current page including optional infobars.
+// Returns the snapshot with or without the overlayed views (e.g. infobar,
+// voice search button, etc.), and either of the visible frame or of the full
+// screen. |overlays| is the array of SnapshotOverlay objects (views currently
+// overlayed), can be nil.
+- (UIImage*)generateSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                        visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_GENERATOR_H_
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm
new file mode 100644
index 0000000..8603ee6
--- /dev/null
+++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -0,0 +1,261 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/snapshots/snapshot_generator.h"
+
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/snapshots/snapshot_cache.h"
+#import "ios/chrome/browser/snapshots/snapshot_cache_factory.h"
+#import "ios/chrome/browser/snapshots/snapshot_overlay.h"
+#import "ios/chrome/browser/tabs/tab.h"
+#import "ios/chrome/browser/tabs/tab_headers_delegate.h"
+#import "ios/chrome/browser/tabs/tab_private.h"
+#import "ios/chrome/browser/ui/uikit_ui_util.h"
+#import "ios/web/web_state/ui/crw_web_controller.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+// Returns YES if |view| or any view it contains is a WKWebView.
+BOOL ViewHierarchyContainsWKWebView(UIView* view) {
+  if ([view isKindOfClass:[WKWebView class]])
+    return YES;
+  for (UIView* subview in view.subviews) {
+    if (ViewHierarchyContainsWKWebView(subview))
+      return YES;
+  }
+  return NO;
+}
+}  // namespace
+
+// Class that contains information used when caching snapshots of a web page.
+@interface CoalescingSnapshotContext : NSObject
+
+// Returns the cached snapshot if there is one matching the given parameters.
+// Returns nil otherwise.
+- (UIImage*)cachedSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                      visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+// Caches |snapshot| for the given |overlays| and |visibleFrameOnly|.
+- (void)setCachedSnapshot:(UIImage*)snapshot
+             withOverlays:(NSArray<SnapshotOverlay*>*)overlays
+         visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+@end
+
+@implementation CoalescingSnapshotContext {
+  UIImage* _cachedSnapshot;
+}
+
+// Returns whether a snapshot should be cached in a page loaded context.
+// Note: Returns YES if |overlays| is nil or empty and if |visibleFrameOnly| is
+// YES as this is the only case when the snapshot taken for the page is reused.
+- (BOOL)shouldCacheSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                       visibleFrameOnly:(BOOL)visibleFrameOnly {
+  return visibleFrameOnly && ![overlays count];
+}
+
+- (UIImage*)cachedSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                      visibleFrameOnly:(BOOL)visibleFrameOnly {
+  if ([self shouldCacheSnapshotWithOverlays:overlays
+                           visibleFrameOnly:visibleFrameOnly]) {
+    return _cachedSnapshot;
+  }
+  return nil;
+}
+
+- (void)setCachedSnapshot:(UIImage*)snapshot
+             withOverlays:(NSArray<SnapshotOverlay*>*)overlays
+         visibleFrameOnly:(BOOL)visibleFrameOnly {
+  if ([self shouldCacheSnapshotWithOverlays:overlays
+                           visibleFrameOnly:visibleFrameOnly]) {
+    DCHECK(!_cachedSnapshot);
+    _cachedSnapshot = snapshot;
+  }
+}
+
+@end
+
+@interface SnapshotGenerator ()
+
+// Takes a snapshot for the supplied view (which should correspond to the given
+// type of web view). Returns an autoreleased image cropped and scaled
+// appropriately. The image can also contain overlays (if |overlays| is not
+// nil and not empty).
+- (UIImage*)generateSnapshotForView:(UIView*)view
+                           withRect:(CGRect)rect
+                           overlays:(NSArray<SnapshotOverlay*>*)overlays;
+
+@end
+
+@implementation SnapshotGenerator {
+  CoalescingSnapshotContext* _coalescingSnapshotContext;
+  __weak Tab* _tab;
+}
+
+- (instancetype)initWithTab:(Tab*)tab {
+  if ((self = [super init])) {
+    DCHECK(tab);
+    DCHECK(tab.tabId);
+    DCHECK(tab.webController);
+    _tab = tab;
+  }
+  return self;
+}
+
+- (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled {
+  if (snapshotCoalescingEnabled) {
+    DCHECK(!_coalescingSnapshotContext);
+    _coalescingSnapshotContext = [[CoalescingSnapshotContext alloc] init];
+  } else {
+    DCHECK(_coalescingSnapshotContext);
+    _coalescingSnapshotContext = nil;
+  }
+}
+
+- (void)retrieveSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                            callback:(void (^)(UIImage*))callback {
+  DCHECK(callback);
+  void (^wrappedCallback)(UIImage*) = ^(UIImage* image) {
+    if (!image) {
+      image = [self updateSnapshotWithOverlays:overlays visibleFrameOnly:YES];
+    }
+    callback(image);
+  };
+
+  [[self snapshotCache] retrieveImageForSessionID:_tab.tabId
+                                         callback:wrappedCallback];
+}
+
+- (void)retrieveGreySnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                                callback:(void (^)(UIImage*))callback {
+  DCHECK(callback);
+  void (^wrappedCallback)(UIImage*) = ^(UIImage* image) {
+    if (!image) {
+      image = [self updateSnapshotWithOverlays:overlays visibleFrameOnly:YES];
+      image = GreyImage(image);
+    }
+    callback(image);
+  };
+
+  [[self snapshotCache] retrieveGreyImageForSessionID:_tab.tabId
+                                             callback:wrappedCallback];
+}
+
+- (UIImage*)updateSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                      visibleFrameOnly:(BOOL)visibleFrameOnly {
+  UIImage* snapshot = [self generateSnapshotWithOverlays:overlays
+                                        visibleFrameOnly:visibleFrameOnly];
+
+  // Return default snapshot without caching it if the generation failed.
+  if (!snapshot)
+    return [CRWWebController defaultSnapshotImage];
+
+  UIImage* snapshotToCache = snapshot;
+  if (!visibleFrameOnly && [_tab legacyFullscreenControllerDelegate]) {
+    // Crops the bottom of the fullscreen snapshot.
+    CGRect cropRect =
+        CGRectMake(0, [[_tab tabHeadersDelegate] headerHeightForTab:_tab],
+                   [snapshot size].width, [snapshot size].height);
+    snapshotToCache = CropImage(snapshot, cropRect);
+  }
+  [[self snapshotCache] setImage:snapshotToCache withSessionID:_tab.tabId];
+  return snapshot;
+}
+
+- (UIImage*)generateSnapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays
+                        visibleFrameOnly:(BOOL)visibleFrameOnly {
+  if (![_tab.webController canUseViewForGeneratingOverlayPlaceholderView])
+    return nil;
+
+  CGRect visibleFrame = (visibleFrameOnly ? [_tab snapshotContentArea]
+                                          : [_tab.webController.view bounds]);
+  if (CGRectIsEmpty(visibleFrame))
+    return nil;
+
+  UIImage* snapshot =
+      [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays
+                                            visibleFrameOnly:visibleFrameOnly];
+  if (snapshot)
+    return snapshot;
+
+  [_tab willUpdateSnapshot];
+  snapshot = [self generateSnapshotForView:_tab.webController.view
+                                  withRect:visibleFrame
+                                  overlays:overlays];
+  [_coalescingSnapshotContext setCachedSnapshot:snapshot
+                                   withOverlays:overlays
+                               visibleFrameOnly:visibleFrameOnly];
+  return snapshot;
+}
+
+#pragma mark - Private methods
+
+- (UIImage*)generateSnapshotForView:(UIView*)view
+                           withRect:(CGRect)rect
+                           overlays:(NSArray<SnapshotOverlay*>*)overlays {
+  DCHECK(view);
+  CGSize size = rect.size;
+  DCHECK(std::isnormal(size.width) && (size.width > 0))
+      << ": size.width=" << size.width;
+  DCHECK(std::isnormal(size.height) && (size.height > 0))
+      << ": size.height=" << size.height;
+  const CGFloat kScale = [[self snapshotCache] snapshotScaleForDevice];
+  UIGraphicsBeginImageContextWithOptions(size, YES, kScale);
+  CGContext* context = UIGraphicsGetCurrentContext();
+  if (!context) {
+    NOTREACHED();
+    return nil;
+  }
+
+  // TODO(crbug.com/636188): -drawViewHierarchyInRect:afterScreenUpdates: is
+  // buggy on iOS 8/9/10 (and state is unknown for iOS 11) causing GPU glitches,
+  // screen redraws during animations, broken pinch to dismiss on tablet, etc.
+  // For the moment, only use it for WKWebView with depends on it. Remove this
+  // check and always use -drawViewHierarchyInRect:afterScreenUpdates: once it
+  // is working correctly in all version of iOS supported.
+  BOOL useDrawViewHierarchy = ViewHierarchyContainsWKWebView(view);
+
+  BOOL snapshotSuccess = YES;
+  CGContextSaveGState(context);
+  CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);
+  if (useDrawViewHierarchy) {
+    snapshotSuccess =
+        [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
+  } else {
+    [[view layer] renderInContext:context];
+  }
+  if ([overlays count]) {
+    for (SnapshotOverlay* overlay in overlays) {
+      // Render the overlay view at the desired offset. It is achieved
+      // by shifting origin of context because view frame is ignored when
+      // drawing to context.
+      CGContextSaveGState(context);
+      CGContextTranslateCTM(context, 0, overlay.yOffset);
+      if (useDrawViewHierarchy) {
+        [overlay.view drawViewHierarchyInRect:overlay.view.bounds
+                           afterScreenUpdates:YES];
+      } else {
+        [[overlay.view layer] renderInContext:context];
+      }
+      CGContextRestoreGState(context);
+    }
+  }
+  UIImage* image = nil;
+  if (snapshotSuccess)
+    image = UIGraphicsGetImageFromCurrentImageContext();
+  CGContextRestoreGState(context);
+  UIGraphicsEndImageContext();
+  return image;
+}
+
+- (SnapshotCache*)snapshotCache {
+  return SnapshotCacheFactory::GetForBrowserState(
+      ios::ChromeBrowserState::FromBrowserState(
+          _tab.webController.webState->GetBrowserState()));
+}
+
+@end
diff --git a/ios/chrome/browser/snapshots/snapshot_manager.h b/ios/chrome/browser/snapshots/snapshot_manager.h
deleted file mode 100644
index 1bcdf3b..0000000
--- a/ios/chrome/browser/snapshots/snapshot_manager.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_MANAGER_H_
-#define IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_MANAGER_H_
-
-#import <UIKit/UIKit.h>
-
-namespace web {
-class WebState;
-}
-
-// Snapshot manager for contents of a tab. A snapshot is a full-screen image
-// of the contents of the page at the current scroll offset and zoom level,
-// used to stand in for the web view if it has been purged from memory or when
-// quickly switching tabs. Uses |SnapshotCache| to cache (and persist)
-// snapshots.
-//
-// The snapshots are identified by a "session id" which is unique per tab. This
-// allows quick identification and replacement as a tab changes pages.
-@interface SnapshotManager : NSObject
-
-// Designated initializer. The |webState| must not be null.
-- (instancetype)initWithWebState:(web::WebState*)webState
-    NS_DESIGNATED_INITIALIZER;
-
-- (instancetype)init NS_UNAVAILABLE;
-
-// Takes a snapshot for the supplied view (which should correspond to the given
-// type of web view). Returns an autoreleased image cropped and scaled
-// appropriately.
-// The image is not yet cached.
-// The image can also contain overlays (if |overlays| is not nil and not empty).
-- (UIImage*)generateSnapshotForView:(UIView*)view
-                           withRect:(CGRect)rect
-                           overlays:(NSArray*)overlays;
-
-// Retrieve a cached snapshot for the |sessionID| and return it via the callback
-// if it exists. The callback is guaranteed to be called synchronously if the
-// image is in memory. It will be called asynchronously if the image is on disk
-// or with nil if the image is not present at all.
-- (void)retrieveImageForSessionID:(NSString*)sessionID
-                         callback:(void (^)(UIImage*))callback;
-
-// Request the session's grey snapshot. If the image is already loaded in
-// memory, this will immediately call back on |callback|.  Otherwise, the grey
-// image will be loaded off disk or created by converting an existing color
-// snapshot to grey.
-- (void)retrieveGreyImageForSessionID:(NSString*)sessionID
-                             callback:(void (^)(UIImage*))callback;
-
-// Stores the supplied thumbnail for the specified |sessionID|.
-- (void)setImage:(UIImage*)image withSessionID:(NSString*)sessionID;
-
-// Removes the cached thumbnail for the specified |sessionID|.
-- (void)removeImageWithSessionID:(NSString*)sessionID;
-
-// Request the grey image from the in-memory cache only.
-- (void)greyImageForSessionID:(NSString*)sessionID
-                     callback:(void (^)(UIImage*))callback;
-@end
-
-#endif  // IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_MANAGER_H_
diff --git a/ios/chrome/browser/snapshots/snapshot_manager.mm b/ios/chrome/browser/snapshots/snapshot_manager.mm
deleted file mode 100644
index 1367dfb..0000000
--- a/ios/chrome/browser/snapshots/snapshot_manager.mm
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/snapshots/snapshot_manager.h"
-
-#import <QuartzCore/QuartzCore.h>
-#import <WebKit/WebKit.h>
-
-#include "base/logging.h"
-#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/snapshots/snapshot_cache.h"
-#import "ios/chrome/browser/snapshots/snapshot_cache_factory.h"
-#import "ios/chrome/browser/snapshots/snapshot_overlay.h"
-#import "ios/web/public/web_state/web_state.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-// Returns YES if |view| or any view it contains is a WKWebView.
-BOOL ViewHierarchyContainsWKWebView(UIView* view) {
-  if ([view isKindOfClass:[WKWebView class]])
-    return YES;
-  for (UIView* subview in view.subviews) {
-    if (ViewHierarchyContainsWKWebView(subview))
-      return YES;
-  }
-  return NO;
-}
-}  // namespace
-
-@implementation SnapshotManager {
-  web::WebState* _webState;
-}
-
-- (instancetype)initWithWebState:(web::WebState*)webState {
-  if ((self = [super init])) {
-    DCHECK(webState);
-    _webState = webState;
-  }
-  return self;
-}
-
-- (UIImage*)generateSnapshotForView:(UIView*)view
-                           withRect:(CGRect)rect
-                           overlays:(NSArray*)overlays {
-  DCHECK(view);
-  CGSize size = rect.size;
-  DCHECK(std::isnormal(size.width) && (size.width > 0))
-      << ": size.width=" << size.width;
-  DCHECK(std::isnormal(size.height) && (size.height > 0))
-      << ": size.height=" << size.height;
-  const CGFloat kScale = [[self snapshotCache] snapshotScaleForDevice];
-  UIGraphicsBeginImageContextWithOptions(size, YES, kScale);
-  CGContext* context = UIGraphicsGetCurrentContext();
-  if (!context) {
-    NOTREACHED();
-    return nil;
-  }
-
-  // -drawViewHierarchyInRect:afterScreenUpdates:YES is buggy as of iOS 8.3.
-  // Using it afterScreenUpdates:YES creates unexpected GPU glitches, screen
-  // redraws during animations, broken pinch to dismiss on tablet, etc.  For now
-  // only using this with WKWebView, which depends on -drawViewHierarchyInRect.
-  // TODO(justincohen): Remove this (and always use drawViewHierarchyInRect)
-  // once the iOS 8 bugs have been fixed.
-  BOOL useDrawViewHierarchy = ViewHierarchyContainsWKWebView(view);
-
-  BOOL snapshotSuccess = YES;
-  CGContextSaveGState(context);
-  CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);
-  if (useDrawViewHierarchy) {
-    snapshotSuccess =
-        [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
-  } else {
-    [[view layer] renderInContext:context];
-  }
-  if ([overlays count]) {
-    for (SnapshotOverlay* overlay in overlays) {
-      // Render the overlay view at the desired offset. It is achieved
-      // by shifting origin of context because view frame is ignored when
-      // drawing to context.
-      CGContextSaveGState(context);
-      CGContextTranslateCTM(context, 0, overlay.yOffset);
-      if (useDrawViewHierarchy) {
-        [overlay.view drawViewHierarchyInRect:overlay.view.bounds
-                           afterScreenUpdates:YES];
-      } else {
-        [[overlay.view layer] renderInContext:context];
-      }
-      CGContextRestoreGState(context);
-    }
-  }
-  UIImage* image = nil;
-  if (snapshotSuccess)
-    image = UIGraphicsGetImageFromCurrentImageContext();
-  CGContextRestoreGState(context);
-  UIGraphicsEndImageContext();
-  return image;
-}
-
-- (void)retrieveImageForSessionID:(NSString*)sessionID
-                         callback:(void (^)(UIImage*))callback {
-  [[self snapshotCache] retrieveImageForSessionID:sessionID callback:callback];
-}
-
-- (void)retrieveGreyImageForSessionID:(NSString*)sessionID
-                             callback:(void (^)(UIImage*))callback {
-  [[self snapshotCache] retrieveGreyImageForSessionID:sessionID
-                                             callback:callback];
-}
-
-- (void)setImage:(UIImage*)image withSessionID:(NSString*)sessionID {
-  [[self snapshotCache] setImage:image withSessionID:sessionID];
-}
-
-- (void)removeImageWithSessionID:(NSString*)sessionID {
-  [[self snapshotCache] removeImageWithSessionID:sessionID];
-}
-
-- (void)greyImageForSessionID:(NSString*)sessionID
-                     callback:(void (^)(UIImage*))callback {
-  [[self snapshotCache] greyImageForSessionID:sessionID callback:callback];
-}
-
-#pragma mark - Private methods.
-
-- (SnapshotCache*)snapshotCache {
-  return SnapshotCacheFactory::GetForBrowserState(
-      ios::ChromeBrowserState::FromBrowserState(_webState->GetBrowserState()));
-}
-
-@end
diff --git a/ios/chrome/browser/snapshots/web_controller_snapshot_helper.h b/ios/chrome/browser/snapshots/web_controller_snapshot_helper.h
deleted file mode 100644
index 6b53243..0000000
--- a/ios/chrome/browser/snapshots/web_controller_snapshot_helper.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_SNAPSHOTS_WEB_CONTROLLER_SNAPSHOT_HELPER_H_
-#define IOS_CHROME_BROWSER_SNAPSHOTS_WEB_CONTROLLER_SNAPSHOT_HELPER_H_
-
-#import <UIKit/UIKit.h>
-
-@class CRWWebController;
-@class SnapshotManager;
-@class Tab;
-
-// A class that takes care of creating, storing and returning snapshots of a
-// WebController's web page.
-// TODO(crbug.com/661642): There is a lot of overlap/common functionality
-// between this class and SnapshotManager, coalesce these 2 classes.
-@interface WebControllerSnapshotHelper : NSObject
-
-// Designated initializer. |snapshotManager|, |sessionID|, |webController|
-// should not be nil.
-// TODO(crbug.com/661641): Since we already retain a CRWWebController* and that
-// is the  same which is passed to these methods, remove the CRWWebController
-// param from the following methods.
-// TODO(crbug.com/380819): Replace the need to use Tab directly here by using a
-// delegate pattern.
-- (instancetype)initWithSnapshotManager:(SnapshotManager*)snapshotManager
-                                    tab:(Tab*)tab;
-
-// If |snapshotCoalescingEnabled| is YES snapshots of the web page are
-// coalesced until this method is called with |snapshotCoalescingEnabled| set to
-// NO. When snapshot coalescing is enabled, mutiple calls to generate a snapshot
-// with the same parameters may be coalesced.
-- (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled;
-
-// Gets a color snapshot for the WebController's page, calling |callback| if it
-// is found. |overlays| is the array of SnapshotOverlay objects (views currently
-// overlayed), can be nil.
-- (void)retrieveSnapshotForWebController:(CRWWebController*)webController
-                               sessionID:(NSString*)sessionID
-                            withOverlays:(NSArray*)overlays
-                                callback:(void (^)(UIImage* image))callback;
-
-// Gets a grey snapshot for the webController's current page, calling |callback|
-// if it is found. |overlays| is the array of SnapshotOverlay objects
-// (views currently overlayed), can be nil.
-- (void)retrieveGreySnapshotForWebController:(CRWWebController*)webController
-                                   sessionID:(NSString*)sessionID
-                                withOverlays:(NSArray*)overlays
-                                    callback:(void (^)(UIImage* image))callback;
-
-// Invalidates the cached snapshot for the controller's current session and
-// forces a more recent snapshot to be generated and stored. Returns the
-// snapshot with or without the overlayed views (e.g. infobar, voice search
-// button, etc.), and either of the visible frame or of the full screen.
-// |overlays| is the array of SnapshotOverlay objects (views currently
-// overlayed), can be nil.
-- (UIImage*)updateSnapshotForWebController:(CRWWebController*)webController
-                                 sessionID:(NSString*)sessionID
-                              withOverlays:(NSArray*)overlays
-                          visibleFrameOnly:(BOOL)visibleFrameOnly;
-
-// Takes a snapshot image for the current page including optional infobars.
-// Returns an autoreleased image cropped and scaled appropriately, with or
-// without the overlayed views (e.g. infobar, voice search button, etc.), and
-// either of the visible frame or of the full screen.
-// Returns nil if a snapshot cannot be generated.
-// |overlays| is the array of SnapshotOverlay objects (views currently
-// overlayed), can be nil.
-- (UIImage*)generateSnapshotForWebController:(CRWWebController*)webController
-                                withOverlays:(NSArray*)overlays
-                            visibleFrameOnly:(BOOL)visibleFrameOnly;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_SNAPSHOTS_WEB_CONTROLLER_SNAPSHOT_HELPER_H_
diff --git a/ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm b/ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm
deleted file mode 100644
index b6ed641f..0000000
--- a/ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/snapshots/web_controller_snapshot_helper.h"
-
-#import "ios/chrome/browser/snapshots/snapshot_manager.h"
-#import "ios/chrome/browser/tabs/tab.h"
-#import "ios/chrome/browser/tabs/tab_headers_delegate.h"
-#import "ios/chrome/browser/tabs/tab_private.h"
-#import "ios/chrome/browser/ui/uikit_ui_util.h"
-#import "ios/web/web_state/ui/crw_web_controller.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-@interface WebControllerSnapshotHelper ()
-
-// Takes a snapshot image for the WebController's current page. Returns an
-// autoreleased image cropped and scaled appropriately. Returns a default image
-// if a snapshot cannot be generated.
-- (UIImage*)generateSnapshotOrDefaultForWebController:
-                (CRWWebController*)webController
-                                         withOverlays:(NSArray*)overlays
-                                     visibleFrameOnly:(BOOL)visibleFrameOnly;
-
-// Returns the cached snapshot if there is one matching the given parameters.
-// Returns nil otherwise or if there is no |_coalescingSnapshotContext|.
-- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
-                      visibleFrameOnly:(BOOL)visibleFrameOnly;
-
-// Caches |snapshot| for the given |overlays| and |visibleFrameOnly|. Does
-// nothing if there is no |_coalescingSnapshotContext|.
-- (void)setCachedSnapshot:(UIImage*)snapshot
-             withOverlays:(NSArray*)overlays
-         visibleFrameOnly:(BOOL)visibleFrameOnly;
-@end
-
-// Class that contains information used when caching snapshots of a web page.
-@interface CoalescingSnapshotContext : NSObject
-
-// Returns the cached snapshot if there is one matching the given parameters.
-// Returns nil otherwise.
-- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
-                      visibleFrameOnly:(BOOL)visibleFrameOnly;
-
-// Caches |snapshot| for the given |overlays| and |visibleFrameOnly|.
-- (void)setCachedSnapshot:(UIImage*)snapshot
-             withOverlays:(NSArray*)overlays
-         visibleFrameOnly:(BOOL)visibleFrameOnly;
-
-@end
-
-@implementation CoalescingSnapshotContext {
-  UIImage* _cachedSnapshot;
-}
-
-// Returns whether a snapshot should be cached in a page loaded context.
-// Note: Returns YES if |overlays| is nil or empty and if |visibleFrameOnly| is
-// YES as this is the only case when the snapshot taken by the CRWWebController
-// is reused.
-- (BOOL)shouldCacheSnapshotWithOverlays:(NSArray*)overlays
-                       visibleFrameOnly:(BOOL)visibleFrameOnly {
-  return ![overlays count] && visibleFrameOnly;
-}
-
-- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
-                      visibleFrameOnly:(BOOL)visibleFrameOnly {
-  if ([self shouldCacheSnapshotWithOverlays:overlays
-                           visibleFrameOnly:visibleFrameOnly]) {
-    return _cachedSnapshot;
-  }
-  return nil;
-}
-
-- (void)setCachedSnapshot:(UIImage*)snapshot
-             withOverlays:(NSArray*)overlays
-         visibleFrameOnly:(BOOL)visibleFrameOnly {
-  if ([self shouldCacheSnapshotWithOverlays:overlays
-                           visibleFrameOnly:visibleFrameOnly]) {
-    DCHECK(!_cachedSnapshot);
-    _cachedSnapshot = snapshot;
-  }
-}
-
-@end
-
-@implementation WebControllerSnapshotHelper {
-  CoalescingSnapshotContext* _coalescingSnapshotContext;
-  SnapshotManager* _snapshotManager;
-  __weak CRWWebController* _webController;
-  // Owns this WebControllerSnapshotHelper.
-  __weak Tab* _tab;
-}
-
-- (instancetype)init {
-  NOTREACHED();
-  return nil;
-}
-
-- (instancetype)initWithSnapshotManager:(SnapshotManager*)snapshotManager
-                                    tab:(Tab*)tab {
-  self = [super init];
-  if (self) {
-    DCHECK(snapshotManager);
-    DCHECK(tab);
-    DCHECK(tab.tabId);
-    DCHECK([tab webController]);
-    _snapshotManager = snapshotManager;
-    _webController = [tab webController];
-    _tab = tab;
-  }
-  return self;
-}
-
-- (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled {
-  if (snapshotCoalescingEnabled) {
-    DCHECK(!_coalescingSnapshotContext);
-    _coalescingSnapshotContext = [[CoalescingSnapshotContext alloc] init];
-  } else {
-    DCHECK(_coalescingSnapshotContext);
-    _coalescingSnapshotContext = nil;
-  }
-}
-
-- (UIImage*)generateSnapshotOrDefaultForWebController:
-                (CRWWebController*)webController
-                                         withOverlays:(NSArray*)overlays
-                                     visibleFrameOnly:(BOOL)visibleFrameOnly {
-  UIImage* result = [self generateSnapshotForWebController:webController
-                                              withOverlays:overlays
-                                          visibleFrameOnly:visibleFrameOnly];
-  return result ? result : [[self class] defaultSnapshotImage];
-}
-
-- (void)retrieveSnapshotForWebController:(CRWWebController*)webController
-                               sessionID:(NSString*)sessionID
-                            withOverlays:(NSArray*)overlays
-                                callback:(void (^)(UIImage* image))callback {
-  [_snapshotManager
-      retrieveImageForSessionID:sessionID
-                       callback:^(UIImage* image) {
-                         if (image) {
-                           callback(image);
-                         } else {
-                           callback([self
-                               updateSnapshotForWebController:webController
-                                                    sessionID:sessionID
-                                                 withOverlays:overlays
-                                             visibleFrameOnly:YES]);
-                         }
-                       }];
-}
-
-- (void)retrieveGreySnapshotForWebController:(CRWWebController*)webController
-                                   sessionID:(NSString*)sessionID
-                                withOverlays:(NSArray*)overlays
-                                    callback:
-                                        (void (^)(UIImage* image))callback {
-  [_snapshotManager
-      retrieveGreyImageForSessionID:sessionID
-                           callback:^(UIImage* image) {
-                             if (image) {
-                               callback(image);
-                             } else {
-                               callback(GreyImage([self
-                                   updateSnapshotForWebController:webController
-                                                        sessionID:sessionID
-                                                     withOverlays:overlays
-                                                 visibleFrameOnly:YES]));
-                             }
-                           }];
-}
-
-- (UIImage*)updateSnapshotForWebController:(CRWWebController*)webController
-                                 sessionID:(NSString*)sessionID
-                              withOverlays:(NSArray*)overlays
-                          visibleFrameOnly:(BOOL)visibleFrameOnly {
-  // TODO(crbug.com/661641): This is a temporary solution to make sure the
-  // webController retained by us is the same being passed in in this method.
-  // Remove this when all uses of the "CRWWebController" are dropped from the
-  // methods names since it is already retained by us and not necessary to be
-  // passed in.
-  DCHECK_EQ([_tab webController], webController);
-  UIImage* snapshot =
-      [self generateSnapshotOrDefaultForWebController:webController
-                                         withOverlays:overlays
-                                     visibleFrameOnly:visibleFrameOnly];
-  // If the snapshot is the default one, return it without caching it.
-  if (snapshot == [[self class] defaultSnapshotImage])
-    return snapshot;
-
-  UIImage* snapshotToCache = nil;
-  // TODO(crbug.com/370994): Remove all code that references a Tab's delegates
-  // from this file.
-  if (visibleFrameOnly || ![_tab legacyFullscreenControllerDelegate]) {
-    snapshotToCache = snapshot;
-  } else {
-    // Crops the bottom of the fullscreen snapshot.
-    CGRect cropRect =
-        CGRectMake(0, [[_tab tabHeadersDelegate] headerHeightForTab:_tab],
-                   [snapshot size].width, [snapshot size].height);
-    snapshotToCache = CropImage(snapshot, cropRect);
-  }
-  [_snapshotManager setImage:snapshotToCache withSessionID:sessionID];
-  return snapshot;
-}
-
-- (UIImage*)generateSnapshotForWebController:(CRWWebController*)webController
-                                withOverlays:(NSArray*)overlays
-                            visibleFrameOnly:(BOOL)visibleFrameOnly {
-  if (![webController canUseViewForGeneratingOverlayPlaceholderView])
-    return nil;
-  CGRect visibleFrame = (visibleFrameOnly ? [_tab snapshotContentArea]
-                                          : [webController.view bounds]);
-  if (CGRectIsEmpty(visibleFrame))
-    return nil;
-  UIImage* snapshot = [self cachedSnapshotWithOverlays:overlays
-                                      visibleFrameOnly:visibleFrameOnly];
-  if (!snapshot) {
-    [_tab willUpdateSnapshot];
-    snapshot = [_snapshotManager generateSnapshotForView:webController.view
-                                                withRect:visibleFrame
-                                                overlays:overlays];
-    [self setCachedSnapshot:snapshot
-               withOverlays:overlays
-           visibleFrameOnly:visibleFrameOnly];
-  }
-  return snapshot;
-}
-
-// TODO(crbug.com/661642): This code is shared with SnapshotManager. Remove this
-// and add it as part of WebDelegate delegate API such that a default image is
-// returned immediately.
-+ (UIImage*)defaultSnapshotImage {
-  static UIImage* defaultImage = nil;
-
-  if (!defaultImage) {
-    CGRect frame = CGRectMake(0, 0, 2, 2);
-    UIGraphicsBeginImageContext(frame.size);
-    [[UIColor whiteColor] setFill];
-    CGContextFillRect(UIGraphicsGetCurrentContext(), frame);
-
-    UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-
-    defaultImage = [result stretchableImageWithLeftCapWidth:1 topCapHeight:1];
-  }
-  return defaultImage;
-}
-
-- (void)setCachedSnapshot:(UIImage*)snapshot
-             withOverlays:(NSArray*)overlays
-         visibleFrameOnly:(BOOL)visibleFrameOnly {
-  return [_coalescingSnapshotContext setCachedSnapshot:snapshot
-                                          withOverlays:overlays
-                                      visibleFrameOnly:visibleFrameOnly];
-}
-
-- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
-                      visibleFrameOnly:(BOOL)visibleFrameOnly {
-  return
-      [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays
-                                            visibleFrameOnly:visibleFrameOnly];
-}
-
-@end
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index 0c72fe4..93eeb9ce 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -60,9 +60,10 @@
 #include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
 #include "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #include "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h"
-#import "ios/chrome/browser/snapshots/snapshot_manager.h"
+#import "ios/chrome/browser/snapshots/snapshot_cache.h"
+#import "ios/chrome/browser/snapshots/snapshot_cache_factory.h"
+#import "ios/chrome/browser/snapshots/snapshot_generator.h"
 #import "ios/chrome/browser/snapshots/snapshot_overlay_provider.h"
-#import "ios/chrome/browser/snapshots/web_controller_snapshot_helper.h"
 #import "ios/chrome/browser/tabs/legacy_tab_helper.h"
 #import "ios/chrome/browser/tabs/tab_delegate.h"
 #import "ios/chrome/browser/tabs/tab_dialog_delegate.h"
@@ -173,7 +174,7 @@
 
   // Handles retrieving, generating and updating snapshots of CRWWebController's
   // web page.
-  WebControllerSnapshotHelper* _webControllerSnapshotHelper;
+  SnapshotGenerator* _snapshotGenerator;
 
   // WebStateImpl for this tab.
   web::WebStateImpl* _webStateImpl;
@@ -191,9 +192,6 @@
   UIImageView* _pagePlaceholder;
 }
 
-// Handles caching and retrieving of snapshots.
-@property(nonatomic, strong) SnapshotManager* snapshotManager;
-
 // Returns the OpenInController for this tab.
 - (OpenInController*)openInController;
 
@@ -268,7 +266,6 @@
 @synthesize tabHeadersDelegate = tabHeadersDelegate_;
 @synthesize legacyFullscreenControllerDelegate =
     legacyFullscreenControllerDelegate_;
-@synthesize snapshotManager = _snapshotManager;
 
 - (instancetype)initWithWebState:(web::WebState*)webState {
   DCHECK(webState);
@@ -286,10 +283,7 @@
     [self updateLastVisitedTimestamp];
     [[self webController] setDelegate:self];
 
-    _snapshotManager = [[SnapshotManager alloc] initWithWebState:webState];
-    _webControllerSnapshotHelper = [[WebControllerSnapshotHelper alloc]
-        initWithSnapshotManager:_snapshotManager
-                            tab:self];
+    _snapshotGenerator = [[SnapshotGenerator alloc] initWithTab:self];
   }
   return self;
 }
@@ -351,11 +345,8 @@
 }
 
 - (void)retrieveSnapshot:(void (^)(UIImage*))callback {
-  [_webControllerSnapshotHelper
-      retrieveSnapshotForWebController:self.webController
-                             sessionID:self.tabId
-                          withOverlays:[self snapshotOverlays]
-                              callback:callback];
+  [_snapshotGenerator retrieveSnapshotWithOverlays:[self snapshotOverlays]
+                                          callback:callback];
 }
 
 - (NSString*)title {
@@ -458,19 +449,6 @@
 }
 
 - (void)webDidUpdateSessionForLoadWithURL:(const GURL&)URL {
-  // After a crash the NTP is loaded by default.
-  if (URL.host() != kChromeUINewTabHost) {
-    static BOOL hasLoadedPage = NO;
-    if (!hasLoadedPage) {
-      // As soon as load is initialted, a crash shouldn't be counted as a
-      // startup crash. Since initiating a url load requires user action and is
-      // a significant source of crashes that could lead to false positives in
-      // crash loop detection.
-      crash_util::ResetFailedStartupAttemptCount();
-      hasLoadedPage = YES;
-    }
-  }
-
   web::NavigationItem* navigationItem =
       [self navigationManager]->GetPendingItem();
 
@@ -821,6 +799,19 @@
 
 - (void)webState:(web::WebState*)webState
     didStartNavigation:(web::NavigationContext*)navigation {
+  // After a crash the NTP is loaded by default.
+  if (navigation->GetUrl().host() != kChromeUINewTabHost) {
+    static BOOL hasLoadedPage = NO;
+    if (!hasLoadedPage) {
+      // As soon as load is initialted, a crash shouldn't be counted as a
+      // startup crash. Since initiating a url load requires user action and is
+      // a significant source of crashes that could lead to false positives in
+      // crash loop detection.
+      crash_util::ResetFailedStartupAttemptCount();
+      hasLoadedPage = YES;
+    }
+  }
+
   if (!navigation->IsSameDocument() &&
       !base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) {
     // Move the toolbar to visible during page load.
@@ -903,7 +894,7 @@
     wasPost = lastCommittedItem->HasPostData();
     lastCommittedURL = lastCommittedItem->GetVirtualURL();
   }
-  [_webControllerSnapshotHelper setSnapshotCoalescingEnabled:YES];
+  [_snapshotGenerator setSnapshotCoalescingEnabled:YES];
   if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen) &&
       !loadSuccess) {
     [_legacyFullscreenController disableFullScreen];
@@ -939,7 +930,7 @@
 
   if (loadSuccess)
     [self updateSnapshotWithOverlay:YES visibleFrameOnly:YES];
-  [_webControllerSnapshotHelper setSnapshotCoalescingEnabled:NO];
+  [_snapshotGenerator setSnapshotCoalescingEnabled:NO];
 }
 
 - (void)webState:(web::WebState*)webState
@@ -984,10 +975,6 @@
   return [snapshotOverlayProvider_ snapshotOverlaysForTab:self];
 }
 
-- (void)webViewRemoved {
-  [_openInController disable];
-}
-
 - (BOOL)webController:(CRWWebController*)webController
         shouldOpenURL:(const GURL&)url
       mainDocumentURL:(const GURL&)mainDocumentURL {
@@ -1033,25 +1020,21 @@
   // In other cases, such as during startup, either disk access or a greyspace
   // conversion is required, as there will be no grey snapshots in memory.
   if (useGreyImageCache_) {
-    [self.snapshotManager greyImageForSessionID:sessionID
-                                       callback:completionHandler];
+    [SnapshotCacheFactory::GetForBrowserState(self.browserState)
+        greyImageForSessionID:sessionID
+                     callback:completionHandler];
   } else {
-    [_webControllerSnapshotHelper
-        retrieveGreySnapshotForWebController:self.webController
-                                   sessionID:sessionID
-                                withOverlays:[self snapshotOverlays]
-                                    callback:completionHandler];
+    [_snapshotGenerator retrieveGreySnapshotWithOverlays:[self snapshotOverlays]
+                                                callback:completionHandler];
   }
 }
 
 - (UIImage*)updateSnapshotWithOverlay:(BOOL)shouldAddOverlay
                      visibleFrameOnly:(BOOL)visibleFrameOnly {
   NSArray* overlays = shouldAddOverlay ? [self snapshotOverlays] : nil;
-  UIImage* snapshot = [_webControllerSnapshotHelper
-      updateSnapshotForWebController:self.webController
-                           sessionID:self.tabId
-                        withOverlays:overlays
-                    visibleFrameOnly:visibleFrameOnly];
+  UIImage* snapshot =
+      [_snapshotGenerator updateSnapshotWithOverlays:overlays
+                                    visibleFrameOnly:visibleFrameOnly];
   [_parentTabModel notifyTabSnapshotChanged:self withImage:snapshot];
   return snapshot;
 }
@@ -1059,15 +1042,12 @@
 - (UIImage*)generateSnapshotWithOverlay:(BOOL)shouldAddOverlay
                        visibleFrameOnly:(BOOL)visibleFrameOnly {
   NSArray* overlays = shouldAddOverlay ? [self snapshotOverlays] : nil;
-  return [_webControllerSnapshotHelper
-      generateSnapshotForWebController:self.webController
-                          withOverlays:overlays
-                      visibleFrameOnly:visibleFrameOnly];
+  return [_snapshotGenerator generateSnapshotWithOverlays:overlays
+                                         visibleFrameOnly:visibleFrameOnly];
 }
 
 - (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled {
-  [_webControllerSnapshotHelper
-      setSnapshotCoalescingEnabled:snapshotCoalescingEnabled];
+  [_snapshotGenerator setSnapshotCoalescingEnabled:snapshotCoalescingEnabled];
 }
 
 - (CGRect)snapshotContentArea {
@@ -1094,7 +1074,8 @@
 
 - (void)removeSnapshot {
   DCHECK(self.tabId);
-  [self.snapshotManager removeImageWithSessionID:self.tabId];
+  [SnapshotCacheFactory::GetForBrowserState(self.browserState)
+      removeImageWithSessionID:self.tabId];
 }
 
 #pragma mark - CRWWebDelegate and CRWWebStateObserver protocol methods
diff --git a/ios/chrome/browser/tabs/tab_unittest.mm b/ios/chrome/browser/tabs/tab_unittest.mm
index cb17c6d1..ccaf7b9 100644
--- a/ios/chrome/browser/tabs/tab_unittest.mm
+++ b/ios/chrome/browser/tabs/tab_unittest.mm
@@ -24,7 +24,8 @@
 #import "ios/chrome/browser/chrome_url_util.h"
 #include "ios/chrome/browser/history/history_service_factory.h"
 #include "ios/chrome/browser/history/history_tab_helper.h"
-#import "ios/chrome/browser/snapshots/snapshot_manager.h"
+#import "ios/chrome/browser/snapshots/snapshot_cache.h"
+#import "ios/chrome/browser/snapshots/snapshot_cache_factory.h"
 #import "ios/chrome/browser/tabs/legacy_tab_helper.h"
 #import "ios/chrome/browser/tabs/tab.h"
 #import "ios/chrome/browser/tabs/tab_helper_util.h"
@@ -52,11 +53,21 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
+#import "third_party/ocmock/gtest_support.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
+// When C++ exceptions are disabled, the C++ library defines |try| and
+// |catch| so as to allow exception-expecting C++ code to build properly when
+// language support for exceptions is not present.  These macros interfere
+// with the use of |@try| and |@catch| in Objective-C files such as this one.
+// Undefine these macros here, after everything has been #included, since
+// there will be no C++ uses and only Objective-C uses from this point on.
+#undef try
+#undef catch
+
 namespace {
 const char kAppSettingsUrl[] = "app-settings://";
 const char kNewTabUrl[] = "chrome://newtab/";
@@ -74,10 +85,6 @@
 const char kValidFilenameUrl[] = "http://www.hostname.com/filename.pdf";
 }  // namespace
 
-@interface Tab (Testing)
-@property(nonatomic, strong) SnapshotManager* snapshotManager;
-@end
-
 @interface ArrayTabModel : TabModel {
  @private
   NSMutableArray* _tabsForTesting;
@@ -166,6 +173,9 @@
 
     // Set up the testing profiles.
     TestChromeBrowserState::Builder test_cbs_builder;
+    test_cbs_builder.AddTestingFactory(
+        SnapshotCacheFactory::GetInstance(),
+        SnapshotCacheFactory::GetDefaultFactory());
     chrome_browser_state_ = test_cbs_builder.Build();
     chrome_browser_state_->CreateBookmarkModel(false);
     bookmarks::test::WaitForBookmarkModelToLoad(
@@ -408,26 +418,29 @@
   EXPECT_NSEQ(@"Document.pdf", [[tab_ openInController] suggestedFilename]);
 }
 
-TEST_F(TabTest, SnapshotIsNotRemovedDuringShutdown) {
-  id mockSnapshotManager = OCMClassMock([SnapshotManager class]);
-  tab_.snapshotManager = mockSnapshotManager;
-  [[mockSnapshotManager reject] removeImageWithSessionID:[OCMArg any]];
-  web_state_impl_.reset();
-}
-
 TEST_F(TabTest, ClosingWebStateDoesNotRemoveSnapshot) {
-  id mockSnapshotManager = OCMClassMock([SnapshotManager class]);
-  tab_.snapshotManager = mockSnapshotManager;
-  [[mockSnapshotManager reject] removeImageWithSessionID:[OCMArg any]];
-  web_state_impl_.reset();
+  id partialMock = OCMPartialMock(
+      SnapshotCacheFactory::GetForBrowserState(tab_.browserState));
+  [[partialMock reject] removeImageWithSessionID:tab_.tabId];
+
+  // Use @try/@catch as -reject raises an exception.
+  @try {
+    web_state_impl_.reset();
+    EXPECT_OCMOCK_VERIFY(partialMock);
+  } @catch (NSException* exception) {
+    // The exception is raised when -removeImageWithSessionID: is invoked. As
+    // this should not happen, mark the test as failed.
+    GTEST_FAIL();
+  }
 }
 
 TEST_F(TabTest, CallingRemoveSnapshotRemovesSnapshot) {
-  id mockSnapshotManager = OCMClassMock([SnapshotManager class]);
-  tab_.snapshotManager = mockSnapshotManager;
+  id partialMock = OCMPartialMock(
+      SnapshotCacheFactory::GetForBrowserState(tab_.browserState));
+  OCMExpect([partialMock removeImageWithSessionID:tab_.tabId]);
+
   [tab_ removeSnapshot];
-  [[mockSnapshotManager verify] removeImageWithSessionID:[OCMArg any]];
-  web_state_impl_.reset();
+  EXPECT_OCMOCK_VERIFY(partialMock);
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h b/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h
index 2a4ec84..166c22d 100644
--- a/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h
+++ b/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h
@@ -12,9 +12,16 @@
 // Methods used for the EarlGrey tests.
 @interface SigninEarlGreyUtils : NSObject
 
-// Checks that the sign-in promo view is visible using the right mode.
+// Checks that the sign-in promo view (with a close button) is visible using the
+// right mode.
 + (void)checkSigninPromoVisibleWithMode:(SigninPromoViewMode)mode;
 
+// Checks that the sign-in promo view is visible using the right mode. If
+// |closeButton| is set to YES, the close button in the sign-in promo has to be
+// visible.
++ (void)checkSigninPromoVisibleWithMode:(SigninPromoViewMode)mode
+                            closeButton:(BOOL)closeButton;
+
 // Checks that the sign-in promo view is not visible.
 + (void)checkSigninPromoNotVisible;
 
diff --git a/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm b/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm
index 7797e0a..4d9d77a 100644
--- a/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm
+++ b/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm
@@ -25,6 +25,11 @@
 @implementation SigninEarlGreyUtils
 
 + (void)checkSigninPromoVisibleWithMode:(SigninPromoViewMode)mode {
+  [self checkSigninPromoVisibleWithMode:mode closeButton:YES];
+}
+
++ (void)checkSigninPromoVisibleWithMode:(SigninPromoViewMode)mode
+                            closeButton:(BOOL)closeButton {
   [[EarlGrey
       selectElementWithMatcher:grey_allOf(
                                    grey_accessibilityID(kSigninPromoViewId),
@@ -48,11 +53,13 @@
           assertWithMatcher:grey_notNil()];
       break;
   }
-  [[EarlGrey
-      selectElementWithMatcher:grey_allOf(grey_accessibilityID(
-                                              kSigninPromoCloseButtonId),
-                                          grey_sufficientlyVisible(), nil)]
-      assertWithMatcher:grey_notNil()];
+  if (closeButton) {
+    [[EarlGrey
+        selectElementWithMatcher:grey_allOf(grey_accessibilityID(
+                                                kSigninPromoCloseButtonId),
+                                            grey_sufficientlyVisible(), nil)]
+        assertWithMatcher:grey_notNil()];
+  }
 }
 
 + (void)checkSigninPromoNotVisible {
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
index ef531c3b..2ec49e9 100644
--- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
+++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
@@ -9,34 +9,26 @@
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/autofill/core/browser/autofill_client.h"
+#include "components/autofill/core/browser/card_unmask_delegate.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h"
-#import "components/autofill/ios/browser/autofill_client_ios.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #import "components/autofill/ios/browser/autofill_client_ios_bridge.h"
-
-class IdentityProvider;
-
-namespace infobars {
-class InfoBarManager;
-}
-
-namespace ios {
-class ChromeBrowserState;
-}
-
-namespace password_manager {
-class PasswordGenerationManager;
-}
-
-namespace web {
-class WebState;
-}
+#include "components/infobars/core/infobar_manager.h"
+#include "components/password_manager/core/browser/password_generation_manager.h"
+#include "components/prefs/pref_service.h"
+#include "components/sync/driver/sync_service.h"
+#include "google_apis/gaia/identity_provider.h"
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/web/public/web_state/web_state.h"
 
 namespace autofill {
 
-// Chrome iOS implementation of AutofillClientIOS.
-class ChromeAutofillClientIOS : public AutofillClientIOS {
+// Chrome iOS implementation of AutofillClient.
+class ChromeAutofillClientIOS : public AutofillClient {
  public:
   ChromeAutofillClientIOS(
       ios::ChromeBrowserState* browser_state,
@@ -48,8 +40,14 @@
   ~ChromeAutofillClientIOS() override;
 
   // AutofillClientIOS implementation.
+  PersonalDataManager* GetPersonalDataManager() override;
+  PrefService* GetPrefs() override;
+  syncer::SyncService* GetSyncService() override;
+  IdentityProvider* GetIdentityProvider() override;
   ukm::UkmRecorder* GetUkmRecorder() override;
   AddressNormalizer* GetAddressNormalizer() override;
+  SaveCardBubbleController* GetSaveCardBubbleController() override;
+  void ShowAutofillSettings() override;
   void ShowUnmaskPrompt(const CreditCard& card,
                         UnmaskCardReason reason,
                         base::WeakPtr<CardUnmaskDelegate> delegate) override;
@@ -65,15 +63,39 @@
                                    const base::Closure& callback) override;
   void LoadRiskData(
       const base::Callback<void(const std::string&)>& callback) override;
+  bool HasCreditCardScanFeature() override;
+  void ScanCreditCard(const CreditCardScanCallback& callback) override;
+  void ShowAutofillPopup(
+      const gfx::RectF& element_bounds,
+      base::i18n::TextDirection text_direction,
+      const std::vector<Suggestion>& suggestions,
+      base::WeakPtr<AutofillPopupDelegate> delegate) override;
+  void HideAutofillPopup() override;
+  bool IsAutocompleteEnabled() override;
+  void UpdateAutofillPopupDataListValues(
+      const std::vector<base::string16>& values,
+      const std::vector<base::string16>& labels) override;
   void PropagateAutofillPredictions(
       content::RenderFrameHost* rfh,
       const std::vector<FormStructure*>& forms) override;
+  void DidFillOrPreviewField(const base::string16& autofilled_value,
+                             const base::string16& profile_full_name) override;
+  scoped_refptr<AutofillWebDataService> GetDatabase() override;
   void DidInteractWithNonsecureCreditCardInput() override;
+  bool IsContextSecure() override;
+  bool ShouldShowSigninPromo() override;
+  bool IsAutofillSupported() override;
+  void ExecuteCommand(int id) override;
 
  private:
+  PrefService* pref_service_;
+  PersonalDataManager* personal_data_manager_;
+  web::WebState* web_state_;
+  __weak id<AutofillClientIOSBridge> bridge_;
+  std::unique_ptr<IdentityProvider> identity_provider_;
+  scoped_refptr<AutofillWebDataService> autofill_web_data_service_;
   infobars::InfoBarManager* infobar_manager_;
   password_manager::PasswordGenerationManager* password_generation_manager_;
-  std::unique_ptr<IdentityProvider> identity_provider_;
   CardUnmaskPromptControllerImpl unmask_controller_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeAutofillClientIOS);
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
index 8e19c92e..2faa2a7 100644
--- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
+++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/feature_list.h"
+#include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h"
 #include "components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h"
@@ -16,22 +17,17 @@
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
+#include "components/autofill/ios/browser/autofill_util.h"
 #include "components/infobars/core/infobar.h"
-#include "components/infobars/core/infobar_manager.h"
 #include "components/keyed_service/core/service_access_type.h"
-#include "components/password_manager/core/browser/password_generation_manager.h"
-#include "components/prefs/pref_service.h"
-#include "google_apis/gaia/identity_provider.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/autofill/address_normalizer_factory.h"
 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
-#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/infobars/infobar_utils.h"
 #import "ios/chrome/browser/ssl/insecure_input_tab_helper.h"
 #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h"
 #include "ios/chrome/browser/web_data_service_factory.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-#import "ios/web/public/web_state/web_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -46,13 +42,13 @@
     id<AutofillClientIOSBridge> bridge,
     password_manager::PasswordGenerationManager* password_generation_manager,
     std::unique_ptr<IdentityProvider> identity_provider)
-    : AutofillClientIOS(
-          browser_state->GetPrefs(),
-          PersonalDataManagerFactory::GetForBrowserState(
-              browser_state->GetOriginalChromeBrowserState()),
-          web_state,
-          bridge,
-          std::move(identity_provider),
+    : pref_service_(browser_state->GetPrefs()),
+      personal_data_manager_(PersonalDataManagerFactory::GetForBrowserState(
+          browser_state->GetOriginalChromeBrowserState())),
+      web_state_(web_state),
+      bridge_(bridge),
+      identity_provider_(std::move(identity_provider)),
+      autofill_web_data_service_(
           ios::WebDataServiceFactory::GetAutofillWebDataForBrowserState(
               browser_state,
               ServiceAccessType::EXPLICIT_ACCESS)),
@@ -61,7 +57,26 @@
       unmask_controller_(browser_state->GetPrefs(),
                          browser_state->IsOffTheRecord()) {}
 
-ChromeAutofillClientIOS::~ChromeAutofillClientIOS() {}
+ChromeAutofillClientIOS::~ChromeAutofillClientIOS() {
+  HideAutofillPopup();
+}
+
+PersonalDataManager* ChromeAutofillClientIOS::GetPersonalDataManager() {
+  return personal_data_manager_;
+}
+
+PrefService* ChromeAutofillClientIOS::GetPrefs() {
+  return pref_service_;
+}
+
+// TODO(crbug.com/535784): Implement this when adding credit card upload.
+syncer::SyncService* ChromeAutofillClientIOS::GetSyncService() {
+  return nullptr;
+}
+
+IdentityProvider* ChromeAutofillClientIOS::GetIdentityProvider() {
+  return identity_provider_.get();
+}
 
 ukm::UkmRecorder* ChromeAutofillClientIOS::GetUkmRecorder() {
   return GetApplicationContext()->GetUkmRecorder();
@@ -73,6 +88,15 @@
   return nullptr;
 }
 
+SaveCardBubbleController*
+ChromeAutofillClientIOS::GetSaveCardBubbleController() {
+  return nullptr;
+}
+
+void ChromeAutofillClientIOS::ShowAutofillSettings() {
+  NOTREACHED();
+}
+
 void ChromeAutofillClientIOS::ShowUnmaskPrompt(
     const CreditCard& card,
     UnmaskCardReason reason,
@@ -131,6 +155,38 @@
   callback.Run(ios::GetChromeBrowserProvider()->GetRiskData());
 }
 
+bool ChromeAutofillClientIOS::HasCreditCardScanFeature() {
+  return false;
+}
+
+void ChromeAutofillClientIOS::ScanCreditCard(
+    const CreditCardScanCallback& callback) {
+  NOTREACHED();
+}
+
+void ChromeAutofillClientIOS::ShowAutofillPopup(
+    const gfx::RectF& element_bounds,
+    base::i18n::TextDirection text_direction,
+    const std::vector<Suggestion>& suggestions,
+    base::WeakPtr<AutofillPopupDelegate> delegate) {
+  [bridge_ showAutofillPopup:suggestions popupDelegate:delegate];
+}
+
+void ChromeAutofillClientIOS::HideAutofillPopup() {
+  [bridge_ hideAutofillPopup];
+}
+
+bool ChromeAutofillClientIOS::IsAutocompleteEnabled() {
+  // For browser, Autocomplete is always enabled as part of Autofill.
+  return GetPrefs()->GetBoolean(prefs::kAutofillEnabled);
+}
+
+void ChromeAutofillClientIOS::UpdateAutofillPopupDataListValues(
+    const std::vector<base::string16>& values,
+    const std::vector<base::string16>& labels) {
+  NOTREACHED();
+}
+
 void ChromeAutofillClientIOS::PropagateAutofillPredictions(
     content::RenderFrameHost* rfh,
     const std::vector<FormStructure*>& forms) {
@@ -139,9 +195,33 @@
   }
 }
 
+void ChromeAutofillClientIOS::DidFillOrPreviewField(
+    const base::string16& autofilled_value,
+    const base::string16& profile_full_name) {}
+
+scoped_refptr<AutofillWebDataService> ChromeAutofillClientIOS::GetDatabase() {
+  return autofill_web_data_service_;
+}
+
 void ChromeAutofillClientIOS::DidInteractWithNonsecureCreditCardInput() {
-  InsecureInputTabHelper::GetOrCreateForWebState(web_state())
+  InsecureInputTabHelper::GetOrCreateForWebState(web_state_)
       ->DidInteractWithNonsecureCreditCardInput();
 }
 
+bool ChromeAutofillClientIOS::IsContextSecure() {
+  return IsContextSecureForWebState(web_state_);
+}
+
+bool ChromeAutofillClientIOS::ShouldShowSigninPromo() {
+  return false;
+}
+
+void ChromeAutofillClientIOS::ExecuteCommand(int id) {
+  NOTIMPLEMENTED();
+}
+
+bool ChromeAutofillClientIOS::IsAutofillSupported() {
+  return true;
+}
+
 }  // namespace autofill
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
index 3b403003..5cc6a5e1e 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -1067,19 +1067,20 @@
   const BookmarkNode* node = bookmark_utils_ios::FindFolderById(
       self.bookmarks, [[mutablePath firstObject] longLongValue]);
   DCHECK(node);
-  if (node) {
-    BookmarkHomeViewController* controller =
-        [self createControllerWithRootFolder:node];
-    // We only scroll to the last viewing position for the leaf
-    // node.
-    if (mutablePath.count == 1 && pathCache.position) {
-      [controller
-          setCachedContentPosition:[NSNumber
-                                       numberWithFloat:pathCache.position]];
-    }
-    controller.isReconstructingFromCache = YES;
-    [self.navigationController pushViewController:controller animated:NO];
+  // if node is an empty permanent node, return.
+  if (node->empty() && IsPrimaryPermanentNode(node, self.bookmarks)) {
+    return;
   }
+
+  BookmarkHomeViewController* controller =
+      [self createControllerWithRootFolder:node];
+  // Only scroll to the last viewing position for the leaf node.
+  if (mutablePath.count == 1 && pathCache.position) {
+    [controller
+        setCachedContentPosition:[NSNumber numberWithFloat:pathCache.position]];
+  }
+  controller.isReconstructingFromCache = YES;
+  [self.navigationController pushViewController:controller animated:NO];
 }
 
 // Set up context bar for the new UI.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_new_generation_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_new_generation_egtest.mm
index 1646025..e44fb4e 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmarks_new_generation_egtest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmarks_new_generation_egtest.mm
@@ -2355,7 +2355,8 @@
       assertWithMatcher:grey_sufficientlyVisible()];
 }
 
-- (void)testCachePositionIsRecreatedWhenNodeIsDeleted {
+// Verify root node is opened when cache position is deleted.
+- (void)testCachePositionIsResetWhenNodeIsDeleted {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(kBookmarkNewGeneration);
 
@@ -2371,7 +2372,7 @@
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder 2")]
       performAction:grey_tap()];
 
-  // Close bookmarks
+  // Close bookmarks, it will store Folder 2 as the cache position.
   [[EarlGrey selectElementWithMatcher:BookmarksDoneButton()]
       performAction:grey_tap()];
 
@@ -2381,7 +2382,37 @@
   // Reopen bookmarks.
   [BookmarksNewGenTestCase openBookmarks];
 
-  // Ensure the root node is opened, by verifying folders at this level.
+  // Ensure the root node is opened, by verifying Mobile Bookmarks is seen in a
+  // table cell.
+  [BookmarksNewGenTestCase verifyBookmarkFolderIsSeen:@"Mobile Bookmarks"];
+}
+
+// Verify root node is opened when cache position is a permanent node and is
+// empty.
+- (void)testCachePositionIsResetWhenNodeIsPermanentAndEmpty {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(kBookmarkNewGeneration);
+
+  [BookmarksNewGenTestCase setupStandardBookmarks];
+  [BookmarksNewGenTestCase openBookmarks];
+  [BookmarksNewGenTestCase openMobileBookmarks];
+
+  // Close bookmarks, it will store Mobile Bookmarks as the cache position.
+  [[EarlGrey selectElementWithMatcher:BookmarksDoneButton()]
+      performAction:grey_tap()];
+
+  // Delete all bookmarks and folders under Mobile Bookmarks.
+  [BookmarksNewGenTestCase removeBookmarkWithTitle:@"Folder 1.1"];
+  [BookmarksNewGenTestCase removeBookmarkWithTitle:@"Folder 1"];
+  [BookmarksNewGenTestCase removeBookmarkWithTitle:@"French URL"];
+  [BookmarksNewGenTestCase removeBookmarkWithTitle:@"Second URL"];
+  [BookmarksNewGenTestCase removeBookmarkWithTitle:@"First URL"];
+
+  // Reopen bookmarks.
+  [BookmarksNewGenTestCase openBookmarks];
+
+  // Ensure the root node is opened, by verifying Mobile Bookmarks is seen in a
+  // table cell.
   [BookmarksNewGenTestCase verifyBookmarkFolderIsSeen:@"Mobile Bookmarks"];
 }
 
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 436f4b9..95453e9a 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -1748,7 +1748,7 @@
           // animation.
           Tab* currentTab = [_model currentTab];
           if (currentTab) {
-            [self tabSelected:currentTab];
+            [self tabSelected:currentTab notifyToolbar:NO];
           }
           startVoiceSearchIfNecessaryBlock();
 
@@ -2589,7 +2589,9 @@
 
 // Called when a tab is selected in the model. Make any required view changes.
 // The notification will not be sent when the tab is already the selected tab.
-- (void)tabSelected:(Tab*)tab {
+// |notifyToolbar| indicates whether the toolbar is notified that the tab has
+// changed.
+- (void)tabSelected:(Tab*)tab notifyToolbar:(BOOL)notifyToolbar {
   DCHECK(tab);
 
   // Ignore changes while the tab stack view is visible (or while suspended).
@@ -2597,7 +2599,7 @@
   if (!self.visible || ![_model webUsageEnabled])
     return;
 
-  [self displayTab:tab isNewSelection:YES];
+  [self displayTab:tab isNewSelection:notifyToolbar];
 
   if (_expectingForegroundTab && !self.inNewTabAnimation) {
     // Now that the new tab has been displayed, return to normal. Rather than
@@ -4912,7 +4914,7 @@
 
   [_paymentRequestManager setActiveWebState:newTab.webState];
 
-  [self tabSelected:newTab];
+  [self tabSelected:newTab notifyToolbar:YES];
 }
 
 // Observer method, tab changed.
diff --git a/ios/chrome/browser/ui/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view_controller_unittest.mm
index 348efca4..43b73d6 100644
--- a/ios/chrome/browser/ui/browser_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view_controller_unittest.mm
@@ -81,7 +81,7 @@
     Testing)<CRWNativeContentProvider, PassKitDialogProvider>
 - (void)pageLoadStarted:(NSNotification*)notification;
 - (void)pageLoadComplete:(NSNotification*)notification;
-- (void)tabSelected:(Tab*)tab;
+- (void)tabSelected:(Tab*)tab notifyToolbar:(BOOL)notifyToolbar;
 - (void)tabDeselected:(NSNotification*)notification;
 - (void)tabCountChanged:(NSNotification*)notification;
 @end
@@ -363,7 +363,7 @@
 TEST_F(BrowserViewControllerTest, TestTabSelected) {
   id tabMock = (id)tab_;
   [[tabMock expect] wasShown];
-  [bvc_ tabSelected:tab_];
+  [bvc_ tabSelected:tab_ notifyToolbar:YES];
   EXPECT_EQ([[tab_ view] superview], static_cast<UIView*>([bvc_ contentArea]));
   EXPECT_OCMOCK_VERIFY(tabMock);
 }
@@ -375,7 +375,7 @@
   id tabMock = (id)tab_;
   [tabMock onSelector:@selector(url) callBlockExpectation:block];
   [[tabMock expect] wasShown];
-  [bvc_ tabSelected:tab_];
+  [bvc_ tabSelected:tab_ notifyToolbar:YES];
   EXPECT_EQ([[tab_ view] superview], static_cast<UIView*>([bvc_ contentArea]));
   EXPECT_OCMOCK_VERIFY(tabMock);
 }
diff --git a/ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome_unittest.mm b/ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome_unittest.mm
index 2434f79..97873956 100644
--- a/ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome_unittest.mm
+++ b/ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome_unittest.mm
@@ -46,8 +46,7 @@
   EXPECT_EQ(1, item.configureCount);
 }
 
-// TODO(crbug.com/776593): Enable this test.
-TEST_F(MDCCollectionViewCellChrome, FLAKY_PreferredHeight) {
+TEST_F(MDCCollectionViewCellChrome, PreferredHeight) {
   CollectionViewFooterItem* footerItem =
       [[CollectionViewFooterItem alloc] initWithType:0];
   footerItem.text = @"This is a pretty lengthy sentence.";
diff --git a/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm b/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm
index 373772e..26583e54 100644
--- a/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_chrome_signin_view_controller.mm
@@ -119,7 +119,7 @@
 
 - (void)willStartSignIn:(ChromeSigninViewController*)controller {
   DCHECK_EQ(self, controller);
-  controller.shouldClearData = SHOULD_CLEAR_DATA_CLEAR_DATA;
+  controller.shouldClearData = SHOULD_CLEAR_DATA_MERGE_DATA;
   [_firstRunConfig setSignInAttempted:YES];
 }
 
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model.h b/ios/chrome/browser/ui/fullscreen/fullscreen_model.h
index 70df003..217ca62 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_model.h
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model.h
@@ -67,19 +67,10 @@
   void SetScrollViewIsScrolling(bool scrolling);
   bool ISScrollViewScrolling() const;
 
-  // Setter for whether the scroll view is being dragged.  Unlocked base offsets
-  // will be reset to all y content offset values received while the user is
-  // not dragging.
+  // Setter for whether the scroll view is being dragged.
   void SetScrollViewIsDragging(bool dragging);
   bool IsScrollViewDragging() const;
 
-  // Setter for whether the base content offset is locked.  If the base offset
-  // is locked, the toolbar's location will be tied with a specific content
-  // offset of the scroll view, rather than being able to be shown mid-way
-  // through the page.
-  void SetBaseOffsetLocked(bool locked);
-  bool IsBaseOffsetLocked() const;
-
  private:
   // Setter for |progress_|.  Notifies observers of the new value if
   // |notify_observers| is true.
@@ -113,8 +104,6 @@
   bool scrolling_ = false;
   // Whether the main content is being dragged.
   bool dragging_ = false;
-  // Whether |base_offset_| is locked.
-  bool locked_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(FullscreenModel);
 };
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
index 4f0b8857..974a934e 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
@@ -67,7 +67,7 @@
   if (scrolling_) {
     CGFloat delta = base_offset_ - y_content_offset_;
     SetProgress(1.0 + delta / toolbar_height_);
-  } else if (!locked_) {
+  } else {
     UpdateBaseOffset();
   }
 }
@@ -96,7 +96,7 @@
     return;
   dragging_ = dragging;
   // Update the base offset when dragging occurs.
-  if (dragging_ && !locked_)
+  if (dragging_)
     UpdateBaseOffset();
 }
 
@@ -104,14 +104,6 @@
   return dragging_;
 }
 
-void FullscreenModel::SetBaseOffsetLocked(bool locked) {
-  locked_ = locked;
-}
-
-bool FullscreenModel::IsBaseOffsetLocked() const {
-  return locked_;
-}
-
 void FullscreenModel::SetProgress(CGFloat progress) {
   progress = std::min(static_cast<CGFloat>(1.0), progress);
   progress = std::max(static_cast<CGFloat>(0.0), progress);
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
index e7f1ee23..0e94a3d 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
@@ -90,8 +90,11 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/bookmarks:features",
     "//ios/chrome/browser/ui",
+    "//ios/chrome/browser/ui/authentication:eg_test_support",
+    "//ios/chrome/browser/ui/ntp/recent_tabs",
     "//ios/chrome/test/app:test_support",
     "//ios/chrome/test/earl_grey:test_support",
+    "//ios/public/provider/chrome/browser/signin:test_support",
     "//ios/third_party/earl_grey:earl_grey+link",
     "//ios/web/public/test/http_server",
     "//ui/base",
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm
index aa173ea..4557dae 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm
@@ -11,6 +11,8 @@
 #include "base/test/scoped_feature_list.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/bookmarks/bookmark_new_generation_features.h"
+#import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h"
+#import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/app/tab_test_util.h"
@@ -18,6 +20,7 @@
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h"
 #import "ios/web/public/test/http_server/http_server.h"
 #include "ios/web/public/test/http_server/http_server_util.h"
 #import "ui/base/l10n/l10n_util.h"
@@ -81,6 +84,8 @@
       web::test::HttpServer::MakeUrl(kURLOfTestPage),
       std::string(kHTMLOfTestPage),
   }});
+  [NSUserDefaults.standardUserDefaults setObject:@{}
+                                          forKey:kCollapsedSectionsKey];
 }
 
 - (void)tearDown {
@@ -101,6 +106,23 @@
   }
 }
 
+- (void)closeRecentTabs {
+  // Get rid of the Recent Tabs Panel.
+  if (IsIPadIdiom()) {
+    // On iPad, the Recent Tabs panel is a new page in the navigation history.
+    // Go back to the previous page to restore the test page.
+    [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
+        performAction:grey_tap()];
+    [ChromeEarlGrey waitForPageToFinishLoading];
+  } else {
+    // On iPhone, the Recent Tabs panel is shown in a modal view.
+    // Close that modal.
+    CloseRecentTabsPanelOnIphone();
+    // Wait until the recent tabs panel is dismissed.
+    [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
+  }
+}
+
 // Tests that a closed tab appears in the Recent Tabs panel, and that tapping
 // the entry in the Recent Tabs panel re-opens the closed tab.
 - (void)testClosedTabAppearsInRecentTabsPanel {
@@ -119,21 +141,7 @@
   OpenRecentTabsPanel();
   [[EarlGrey selectElementWithMatcher:TitleOfTestPage()]
       assertWithMatcher:grey_nil()];
-
-  // Get rid of the Recent Tabs Panel.
-  if (IsIPadIdiom()) {
-    // On iPad, the Recent Tabs panel is a new page in the navigation history.
-    // Go back to the previous page to restore the test page.
-    [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
-        performAction:grey_tap()];
-    [ChromeEarlGrey waitForPageToFinishLoading];
-  } else {
-    // On iPhone, the Recent Tabs panel is shown in a modal view.
-    // Close that modal.
-    CloseRecentTabsPanelOnIphone();
-    // Wait until the recent tabs panel is dismissed.
-    [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
-  }
+  [self closeRecentTabs];
 
   // Close the tab containing the test page and wait for the stack view to
   // appear.
@@ -188,4 +196,66 @@
   chrome_test_util::CloseCurrentTab();
 }
 
+// Tests that the sign-in promo can be reloaded correctly.
+- (void)testRecentTabSigninPromoReloaded {
+  // TODO(crbug.com/782551): Rewrite this egtest for the new bookmark.
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(kBookmarkNewGeneration);
+
+  OpenRecentTabsPanel();
+  // Sign-in promo should be visible with cold state.
+  [SigninEarlGreyUtils
+      checkSigninPromoVisibleWithMode:SigninPromoViewModeColdState
+                          closeButton:NO];
+  ChromeIdentity* identity = [SigninEarlGreyUtils fakeIdentity1];
+  ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
+      identity);
+  // Sign-in promo should be visible with warm state.
+  [SigninEarlGreyUtils
+      checkSigninPromoVisibleWithMode:SigninPromoViewModeWarmState
+                          closeButton:NO];
+  [self closeRecentTabs];
+  ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()
+      ->RemoveIdentity(identity);
+}
+
+// Tests that the sign-in promo can be reloaded correctly while being hidden.
+// crbug.com/776939
+- (void)testRecentTabSigninPromoReloadedWhileHidden {
+  // TODO(crbug.com/782551): Rewrite this egtest for the new bookmark.
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(kBookmarkNewGeneration);
+
+  OpenRecentTabsPanel();
+  [SigninEarlGreyUtils
+      checkSigninPromoVisibleWithMode:SigninPromoViewModeColdState
+                          closeButton:NO];
+
+  // Tap on "Other Devices", to hide the sign-in promo.
+  [[EarlGrey
+      selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabel(
+                                   l10n_util::GetNSString(
+                                       IDS_IOS_RECENT_TABS_OTHER_DEVICES))]
+      performAction:grey_tap()];
+  [SigninEarlGreyUtils checkSigninPromoNotVisible];
+
+  // Add an account.
+  ChromeIdentity* identity = [SigninEarlGreyUtils fakeIdentity1];
+  ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
+      identity);
+
+  // Tap on "Other Devcies", to show the sign-in promo.
+  [[EarlGrey
+      selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabel(
+                                   l10n_util::GetNSString(
+                                       IDS_IOS_RECENT_TABS_OTHER_DEVICES))]
+      performAction:grey_tap()];
+  [SigninEarlGreyUtils
+      checkSigninPromoVisibleWithMode:SigninPromoViewModeWarmState
+                          closeButton:NO];
+  [self closeRecentTabs];
+  ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()
+      ->RemoveIdentity(identity);
+}
+
 @end
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h
index cea788a..347f5e8 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h
@@ -21,6 +21,9 @@
 @protocol ApplicationCommands;
 @protocol RecentTabsHandsetViewControllerCommand;
 
+// Key for saving collapsed session state in the UserDefaults.
+extern NSString* const kCollapsedSectionsKey;
+
 @protocol RecentTabsTableViewControllerDelegate<NSObject>
 // Tells the delegate when the table view content scrolled or changed size.
 - (void)recentTabsTableViewContentMoved:(UITableView*)tableView;
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
index 4b989d1..a5f1ede 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
@@ -53,11 +53,11 @@
 #error "This file requires ARC support."
 #endif
 
-namespace {
-
 // Key for saving collapsed session state in the UserDefaults.
 NSString* const kCollapsedSectionsKey = @"ChromeRecentTabsCollapsedSections";
 
+namespace {
+
 // Key for saving whether the Other Device section is collapsed.
 NSString* const kOtherDeviceCollapsedKey = @"OtherDevicesCollapsed";
 
@@ -1005,6 +1005,8 @@
             (SigninPromoViewConfigurator*)configurator
                              identityChanged:(BOOL)identityChanged {
   DCHECK(_signinPromoViewMediator);
+  if ([self sectionIsCollapsed:kOtherDeviceCollapsedKey])
+    return;
   NSInteger sectionIndex =
       [self sectionIndexForSectionType:OTHER_DEVICES_SECTION];
   DCHECK(sectionIndex != NSNotFound);
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn
index ca010ce..e0803e0 100644
--- a/ios/chrome/browser/ui/omnibox/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -95,6 +95,7 @@
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/toolbar/public",
+    "//ios/chrome/browser/ui/toolbar/public:toolbar_base_feature",
     "//ios/chrome/common",
     "//ios/public/provider/chrome/browser",
     "//ios/third_party/material_components_ios",
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
index 23d14134..3e40a3e 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -21,6 +21,7 @@
 #include "ios/chrome/browser/ui/omnibox/omnibox_util.h"
 #import "ios/chrome/browser/ui/reversed_animation.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
+#import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h"
 #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -492,7 +493,7 @@
   textRectLayout.position.leading += textInset + kTextAreaLeadingOffset;
   textRectLayout.size.width -= textInset - kTextAreaLeadingOffset;
 
-  if (IsIPadIdiom()) {
+  if (IsIPadIdiom() && !base::FeatureList::IsEnabled(kCleanToolbar)) {
     if (!IsCompactTablet()) {
       // Adjust the width so that the text doesn't overlap with the bookmark and
       // voice search buttons which are displayed inside the omnibox.
@@ -930,7 +931,8 @@
   if ([self rightView]) {
     CGSize rightViewSize = self.rightView.bounds.size;
     CGFloat leadingOffset = 0;
-    if (IsIPadIdiom() && !IsCompactTablet()) {
+    if (IsIPadIdiom() && !IsCompactTablet() &&
+        !base::FeatureList::IsEnabled(kCleanToolbar)) {
       leadingOffset = bounds.size.width - kVoiceSearchButtonWidth -
                       rightViewSize.width - kClearButtonRightMarginIpad;
     } else {
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_controller_perftest.mm b/ios/chrome/browser/ui/stack_view/stack_view_controller_perftest.mm
index f98c218..aafc2e9 100644
--- a/ios/chrome/browser/ui/stack_view/stack_view_controller_perftest.mm
+++ b/ios/chrome/browser/ui/stack_view/stack_view_controller_perftest.mm
@@ -10,7 +10,6 @@
 #include "base/macros.h"
 #include "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
-#import "ios/chrome/browser/snapshots/snapshot_manager.h"
 #import "ios/chrome/browser/tabs/tab.h"
 #import "ios/chrome/browser/tabs/tab_model.h"
 #include "ios/chrome/browser/test/perf_test_with_bvc_ios.h"
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn
index e87ac058..56b4a345 100644
--- a/ios/chrome/browser/ui/toolbar/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -7,6 +7,8 @@
   sources = [
     "legacy_toolbar_coordinator.h",
     "legacy_toolbar_coordinator.mm",
+    "legacy_toolbar_view.h",
+    "legacy_toolbar_view.mm",
     "new_tab_button.h",
     "new_tab_button.mm",
     "omnibox_focuser.h",
@@ -22,8 +24,6 @@
     "toolbar_model_ios.h",
     "toolbar_owner.h",
     "toolbar_snapshot_providing.h",
-    "toolbar_view.h",
-    "toolbar_view.mm",
     "toolbar_view_delegate.h",
     "tools_menu_button_observer_bridge.h",
     "tools_menu_button_observer_bridge.mm",
diff --git a/ios/chrome/browser/ui/toolbar/clean/BUILD.gn b/ios/chrome/browser/ui/toolbar/clean/BUILD.gn
index 3634e8d..54ea7da 100644
--- a/ios/chrome/browser/ui/toolbar/clean/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/clean/BUILD.gn
@@ -56,6 +56,8 @@
     "toolbar_button_updater.h",
     "toolbar_button_updater.mm",
     "toolbar_consumer.h",
+    "toolbar_view.h",
+    "toolbar_view.mm",
     "toolbar_view_controller.h",
     "toolbar_view_controller.mm",
   ]
@@ -70,6 +72,7 @@
     "//ios/chrome/browser/ui/history_popup/requirements",
     "//ios/chrome/browser/ui/toolbar/public",
     "//ios/chrome/browser/ui/voice",
+    "//ios/chrome/common",
     "//ios/third_party/material_components_ios",
   ]
   libs = [ "UIKit.framework" ]
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h
index 0549da4..c6039c1 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h
@@ -19,6 +19,10 @@
 // Style of this configuration.
 @property(nonatomic, assign) ToolbarStyle style;
 
+// Background color of the NTP. Used to do as if the toolbar was transparent and
+// the NTP is visible behind it.
+@property(nonatomic, readonly) UIColor* NTPBackgroundColor;
+
 // Background color of the toolbar.
 @property(nonatomic, readonly) UIColor* backgroundColor;
 
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm
index 0887309..d801c7e 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h"
 
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h"
+#import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -23,6 +24,16 @@
   return self;
 }
 
+- (UIColor*)NTPBackgroundColor {
+  switch (self.style) {
+    case NORMAL:
+      return [UIColor whiteColor];
+    case INCOGNITO:
+      return [UIColor colorWithWhite:kNTPBackgroundColorBrightnessIncognito
+                               alpha:1.0];
+  }
+}
+
 - (UIColor*)backgroundColor {
   switch (self.style) {
     case NORMAL:
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h
index 4854334..cab69ef 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h
@@ -8,6 +8,8 @@
 #import <CoreGraphics/CoreGraphics.h>
 #import <Foundation/Foundation.h>
 
+#include "ios/chrome/browser/ui/rtl_geometry.h"
+
 // All kxxxColor constants are RGB values stored in a Hex integer. These will be
 // converted into UIColors using the UIColorFromRGB() function, from
 // uikit_ui_util.h
@@ -47,4 +49,7 @@
 // Maximum number of tabs displayed by the button containing the tab count.
 extern const NSInteger kShowTabStripButtonMaxTabCount;
 
+// Animation constants.
+extern const LayoutOffset kToolbarButtonAnimationOffset;
+
 #endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_TOOLBAR_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm
index 20a0ddc..0a00d79 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm
@@ -36,3 +36,5 @@
 const CGFloat kForwardButtonImageInset = -7;
 
 const NSInteger kShowTabStripButtonMaxTabCount = 99;
+
+const LayoutOffset kToolbarButtonAnimationOffset = -10.0;
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm
index a055576..3a1181c 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm
@@ -230,7 +230,7 @@
   web::NavigationItem* item =
       webState->GetNavigationManager()->GetVisibleItem();
   GURL URL = item ? item->GetURL().GetOrigin() : GURL::EmptyGURL();
-  BOOL isNTP = URL == GURL(kChromeUINewTabURL);
+  BOOL isNTP = (URL == GURL(kChromeUINewTabURL));
 
   // Don't do anything for a live non-ntp tab.
   if (webState == [self getWebState] && !isNTP) {
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_view.h
new file mode 100644
index 0000000..bc6464e
--- /dev/null
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view.h
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_TOOLBAR_VIEW_H_
+#define IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_TOOLBAR_VIEW_H_
+
+#import <UIKit/UIKit.h>
+
+// TODO(crbug.com/792440): Once the new notification for fullscreen is
+// completed, this protocol can be removed. Protocol handling the fullscreen for
+// the Toolbar.
+@protocol ToolbarViewFullscreenDelegate
+// Called when the frame of the Toolbar View has changed.
+- (void)toolbarViewFrameChanged;
+@end
+
+// The view displaying the toolbar.
+@interface ToolbarView : UIView
+
+// The delegate used to handle frame changes.
+@property(nonatomic, weak) id<ToolbarViewFullscreenDelegate> delegate;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_TOOLBAR_VIEW_H_
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view.mm
new file mode 100644
index 0000000..ec8af3f
--- /dev/null
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view.mm
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/toolbar/clean/toolbar_view.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation ToolbarView
+
+@synthesize delegate = _delegate;
+
+- (void)setFrame:(CGRect)frame {
+  [super setFrame:frame];
+  [self.delegate toolbarViewFrameChanged];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
index e9adf26b..a809e05 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
@@ -18,10 +18,12 @@
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_tools_menu_button.h"
+#import "ios/chrome/browser/ui/toolbar/clean/toolbar_view.h"
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_constants.h"
 #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/material_timing.h"
 #include "ios/chrome/grit/ios_theme_resources.h"
 #import "ios/third_party/material_components_ios/src/components/ProgressView/src/MaterialProgressView.h"
 
@@ -29,7 +31,7 @@
 #error "This file requires ARC support."
 #endif
 
-@interface ToolbarViewController ()
+@interface ToolbarViewController ()<ToolbarViewFullscreenDelegate>
 @property(nonatomic, strong) ToolbarButtonFactory* buttonFactory;
 @property(nonatomic, strong) ToolbarButtonUpdater* buttonUpdater;
 
@@ -40,8 +42,10 @@
 @property(nonatomic, strong) UIView* locationBarContainer;
 @property(nonatomic, strong) UIStackView* trailingStackView;
 
-// Array containing all the toolbar buttons, lazily instantiated.
-@property(nonatomic, strong) NSArray<ToolbarButton*>* allButtons;
+// Array containing all the |_leadingStackView| buttons, lazily instantiated.
+@property(nonatomic, strong) NSArray<ToolbarButton*>* leadingStackViewButtons;
+// Array containing all the |_trailingStackView| buttons, lazily instantiated.
+@property(nonatomic, strong) NSArray<ToolbarButton*>* trailingStackViewButtons;
 @property(nonatomic, strong) ToolbarButton* backButton;
 @property(nonatomic, strong) ToolbarButton* forwardButton;
 @property(nonatomic, strong) ToolbarButton* tabSwitchStripButton;
@@ -73,10 +77,14 @@
 // Top anchor at the bottom of the safeAreaLayoutGuide. Used so views don't
 // overlap with the Status Bar.
 @property(nonatomic, strong) NSLayoutYAxisAnchor* topSafeAnchor;
+
+@property(nonatomic, strong) ToolbarView* view;
 @end
 
 @implementation ToolbarViewController
-@synthesize allButtons = _allButtons;
+@dynamic view;
+@synthesize leadingStackViewButtons = _leadingStackViewButtons;
+@synthesize trailingStackViewButtons = _trailingStackViewButtons;
 @synthesize backgroundView = _backgroundView;
 @synthesize buttonFactory = _buttonFactory;
 @synthesize buttonUpdater = _buttonUpdater;
@@ -129,10 +137,37 @@
   DCHECK(!IsIPadIdiom());
   [NSLayoutConstraint deactivateConstraints:self.regularToolbarConstraints];
   [NSLayoutConstraint activateConstraints:self.expandedToolbarConstraints];
+  // By unhiding the button we will make it layout into the correct position in
+  // the StackView.
+  self.contractButton.hidden = NO;
+  self.contractButton.alpha = 0;
   [animator addAnimations:^{
     [self.view layoutIfNeeded];
-    self.contractButton.hidden = NO;
-    self.contractButton.alpha = 1;
+    [self setHorizontalTranslationOffset:-kToolbarButtonAnimationOffset
+                              forButtons:self.leadingStackViewButtons];
+    [self setHorizontalTranslationOffset:kToolbarButtonAnimationOffset
+                              forButtons:self.trailingStackViewButtons];
+    [self setAllVisibleToolbarButtonsOpacity:0];
+  }];
+  // When the locationBarContainer has been expanded the Contract button will
+  // fade in.
+  [animator addCompletion:^(UIViewAnimatingPosition finalPosition) {
+    [self setHorizontalTranslationOffset:kToolbarButtonAnimationOffset
+                              forButtons:@[ self.contractButton ]];
+
+    [UIViewPropertyAnimator
+        runningPropertyAnimatorWithDuration:ios::material::kDuration1
+                                      delay:ios::material::kDuration4
+                                    options:UIViewAnimationOptionCurveEaseOut
+                                 animations:^{
+                                   self.contractButton.alpha = 1;
+                                   [self
+                                       setHorizontalTranslationOffset:0
+                                                           forButtons:@[
+                                                             self.contractButton
+                                                           ]];
+                                 }
+                                 completion:nil];
   }];
   [animator addCompletion:^(UIViewAnimatingPosition finalPosition) {
     CGFloat borderWidth = (finalPosition == UIViewAnimatingPositionEnd)
@@ -149,21 +184,56 @@
   DCHECK(!IsIPadIdiom());
   [NSLayoutConstraint deactivateConstraints:self.expandedToolbarConstraints];
   [NSLayoutConstraint activateConstraints:self.regularToolbarConstraints];
+  // Change the Toolbar buttons opacity to 0 since these will fade in once the
+  // locationBarContainer has been contracted.
+  [self setAllVisibleToolbarButtonsOpacity:0];
   [animator addAnimations:^{
     self.locationBarContainer.layer.borderWidth = kLocationBarBorderWidth;
     [self.view layoutIfNeeded];
     self.contractButton.hidden = YES;
     self.contractButton.alpha = 0;
   }];
+  // Once the locationBarContainer has been contracted fade in ToolbarButtons.
+  [animator addCompletion:^(UIViewAnimatingPosition finalPosition) {
+    [self setHorizontalTranslationOffset:kToolbarButtonAnimationOffset
+                              forButtons:self.leadingStackViewButtons];
+    [self setHorizontalTranslationOffset:-kToolbarButtonAnimationOffset
+                              forButtons:self.trailingStackViewButtons];
+    [UIViewPropertyAnimator
+        runningPropertyAnimatorWithDuration:ios::material::kDuration1
+                                      delay:ios::material::kDuration4
+                                    options:UIViewAnimationOptionCurveEaseOut
+                                 animations:^{
+                                   [self.view layoutIfNeeded];
+                                   [self
+                                       setHorizontalTranslationOffset:0
+                                                           forButtons:
+                                                 self.leadingStackViewButtons];
+                                   [self
+                                       setHorizontalTranslationOffset:0
+                                                           forButtons:
+                                                self.trailingStackViewButtons];
+                                   [self setAllVisibleToolbarButtonsOpacity:1];
+                                 }
+                                 completion:nil];
+  }];
   self.expanded = NO;
 }
 
 - (void)updateForSideSwipeSnapshotOnNTP:(BOOL)onNTP {
-  // TODO(crbug.com/785756): Implement this.
+  self.progressBar.hidden = YES;
+  if (onNTP) {
+    self.backgroundView.alpha = 1;
+    self.locationBarContainer.hidden = YES;
+    // The back button is visible only if the forward button is enabled.
+    self.backButton.hiddenInCurrentState = !self.forwardButton.enabled;
+  }
 }
 
 - (void)resetAfterSideSwipeSnapshot {
-  // TODO(crbug.com/785756): Implement this.
+  self.backgroundView.alpha = 0;
+  self.locationBarContainer.hidden = NO;
+  self.backButton.hiddenInCurrentState = NO;
 }
 
 - (void)setBackgroundToIncognitoNTPColorWithAlpha:(CGFloat)alpha {
@@ -191,6 +261,11 @@
 
 #pragma mark - View lifecyle
 
+- (void)loadView {
+  self.view = [[ToolbarView alloc] init];
+  self.view.delegate = self;
+}
+
 - (void)viewDidLoad {
   // The view can be obstructed by the background view.
   self.view.backgroundColor =
@@ -570,9 +645,12 @@
   self.stopButton.hiddenInCurrentState = !loading;
   if (!loading) {
     [self stopProgressBar];
-  } else {
+  } else if (self.progressBar.hidden) {
     [self.progressBar setProgress:0];
     [self.progressBar setHidden:NO animated:YES completion:nil];
+    // Layout if needed the progress bar to avoir having the progress bar going
+    // backward when opening a page from the NTP.
+    [self.progressBar layoutIfNeeded];
   }
 }
 
@@ -635,13 +713,28 @@
   self.shareButton.enabled = enabled;
 }
 
+#pragma mark - ToolbarViewFullscreenDelegate
+
+- (void)toolbarViewFrameChanged {
+  CGRect frame = self.view.frame;
+  CGFloat distanceOffscreen =
+      IsIPadIdiom()
+          ? fmax((kIPadToolbarY - frame.origin.y) - kScrollFadeDistance, 0)
+          : -1 * frame.origin.y;
+  CGFloat fraction = 1 - fmin(distanceOffscreen / kScrollFadeDistance, 1);
+
+  self.leadingStackView.alpha = fraction;
+  self.locationBarContainer.alpha = fraction;
+  self.trailingStackView.alpha = fraction;
+}
+
 #pragma mark - ActivityServicePositioner
 
 - (UIView*)shareButtonView {
   return self.shareButton;
 }
 
-#pragma mark = BubbleViewAnchorPointProvider
+#pragma mark - BubbleViewAnchorPointProvider
 
 - (CGPoint)anchorPointForTabSwitcherButton:(BubbleArrowDirection)direction {
   CGPoint anchorPoint =
@@ -663,22 +756,32 @@
 
 // Updates all Buttons visibility to match any recent WebState change.
 - (void)updateAllButtonsVisibility {
-  for (ToolbarButton* button in self.allButtons) {
+  NSMutableArray* allButtons = [[NSMutableArray alloc] init];
+  [allButtons addObjectsFromArray:self.leadingStackViewButtons];
+  [allButtons addObjectsFromArray:self.trailingStackViewButtons];
+  [allButtons
+      addObjectsFromArray:@[ self.voiceSearchButton, self.bookmarkButton ]];
+  for (ToolbarButton* button in allButtons) {
     [button updateHiddenInCurrentSizeClass];
   }
 }
 
 #pragma mark - Setters & Getters.
 
-- (NSArray<ToolbarButton*>*)allButtons {
-  if (!_allButtons) {
-    _allButtons = [NSArray
-        arrayWithObjects:self.backButton, self.forwardButton, self.reloadButton,
-                         self.stopButton, self.shareButton,
-                         self.tabSwitchStripButton, self.toolsMenuButton,
-                         self.bookmarkButton, self.voiceSearchButton, nil];
+- (NSArray<ToolbarButton*>*)leadingStackViewButtons {
+  if (!_leadingStackViewButtons) {
+    _leadingStackViewButtons =
+        [self toolbarButtonsInStackView:self.leadingStackView];
   }
-  return _allButtons;
+  return _leadingStackViewButtons;
+}
+
+- (NSArray<ToolbarButton*>*)trailingStackViewButtons {
+  if (!_trailingStackViewButtons) {
+    _trailingStackViewButtons =
+        [self toolbarButtonsInStackView:self.trailingStackView];
+  }
+  return _trailingStackViewButtons;
 }
 
 - (UIView*)backgroundView {
@@ -686,8 +789,7 @@
     _backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
     _backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
     _backgroundView.backgroundColor =
-        [UIColor colorWithWhite:kNTPBackgroundColorBrightnessIncognito
-                          alpha:1.0];
+        self.buttonFactory.toolbarConfiguration.NTPBackgroundColor;
     [self.view insertSubview:_backgroundView atIndex:0];
     AddSameConstraints(self.view, _backgroundView);
   }
@@ -787,4 +889,37 @@
   [self.dispatcher startVoiceSearch:command];
 }
 
+// Sets all Visible Toolbar Buttons opacity to |alpha|.
+- (void)setAllVisibleToolbarButtonsOpacity:(CGFloat)alpha {
+  for (UIButton* button in [self.leadingStackViewButtons
+           arrayByAddingObjectsFromArray:self.trailingStackViewButtons]) {
+    if (!button.hidden)
+      button.alpha = alpha;
+  }
+}
+
+// Offsets the horizontal translation transform of all visible Toolbar Buttons
+// in |array| by |offset|. Used for fade in animations.
+- (void)setHorizontalTranslationOffset:(LayoutOffset)offset
+                            forButtons:(NSArray<ToolbarButton*>*)array {
+  for (UIButton* button in array) {
+    if (!button.hidden)
+      button.transform = (offset != 0)
+                             ? CGAffineTransformMakeTranslation(offset, 0)
+                             : CGAffineTransformIdentity;
+  }
+}
+
+// Returns all the ToolbarButtons in a given UIStackView.
+- (NSArray<ToolbarButton*>*)toolbarButtonsInStackView:(UIStackView*)stackView {
+  NSMutableArray<ToolbarButton*>* buttons = [[NSMutableArray alloc] init];
+  for (UIView* view in stackView.arrangedSubviews) {
+    if ([view isKindOfClass:[ToolbarButton class]]) {
+      ToolbarButton* button = base::mac::ObjCCastStrict<ToolbarButton>(view);
+      [buttons addObject:button];
+    }
+  }
+  return buttons;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_view.h b/ios/chrome/browser/ui/toolbar/legacy_toolbar_view.h
similarity index 74%
rename from ios/chrome/browser/ui/toolbar/toolbar_view.h
rename to ios/chrome/browser/ui/toolbar/legacy_toolbar_view.h
index d37320b..283c861 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_view.h
+++ b/ios/chrome/browser/ui/toolbar/legacy_toolbar_view.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_VIEW_H_
-#define IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_VIEW_H_
+#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_LEGACY_TOOLBAR_VIEW_H_
+#define IOS_CHROME_BROWSER_UI_TOOLBAR_LEGACY_TOOLBAR_VIEW_H_
 
 #import <UIKit/UIKit.h>
 
@@ -11,7 +11,7 @@
 
 @protocol ToolbarViewDelegate;
 
-@interface ToolbarView : UIView<RelaxedBoundsConstraintsHitTestSupport>
+@interface LegacyToolbarView : UIView<RelaxedBoundsConstraintsHitTestSupport>
 - (instancetype)initWithNibName:(NSString*)name
                          bundle:(NSBundle*)bundle NS_UNAVAILABLE;
 - (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE;
@@ -25,4 +25,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_VIEW_H_
+#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_LEGACY_TOOLBAR_VIEW_H_
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_view.mm b/ios/chrome/browser/ui/toolbar/legacy_toolbar_view.mm
similarity index 96%
rename from ios/chrome/browser/ui/toolbar/toolbar_view.mm
rename to ios/chrome/browser/ui/toolbar/legacy_toolbar_view.mm
index da7df372..0fc4d61 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_view.mm
+++ b/ios/chrome/browser/ui/toolbar/legacy_toolbar_view.mm
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/toolbar/toolbar_view.h"
+#import "ios/chrome/browser/ui/toolbar/legacy_toolbar_view.h"
 
 #import "ios/chrome/browser/ui/toolbar/toolbar_view_delegate.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 
-@implementation ToolbarView
+@implementation LegacyToolbarView
 
 @synthesize delegate = delegate_;
 @synthesize animatingTransition = animatingTransition_;
diff --git a/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h b/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h
index a0e0e10d..567eb1a 100644
--- a/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h
+++ b/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h
@@ -7,9 +7,6 @@
 
 #include "base/feature_list.h"
 
-// Feature to choose whether the toolbar uses UIViewPropertyAnimators.
-extern const base::Feature kPropertyAnimationsToolbar;
-
 // Feature to choose whether to use the clean Toolbar stack or
 // WebToolbarController.
 extern const base::Feature kCleanToolbar;
diff --git a/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.mm b/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.mm
index 9ee1640..6ab790b 100644
--- a/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.mm
+++ b/ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.mm
@@ -8,8 +8,5 @@
 #error "This file requires ARC support."
 #endif
 
-const base::Feature kPropertyAnimationsToolbar{
-    "PropertyAnimationsToolbar", base::FEATURE_DISABLED_BY_DEFAULT};
-
 const base::Feature kCleanToolbar{"CleanToolbar",
                                   base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h b/ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h
index 6ca0809..77de5c40 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h
+++ b/ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h
@@ -14,14 +14,6 @@
 // kToolbarTransitionAnimationKey.
 @property(nonatomic, readonly) NSMutableArray* transitionLayers;
 
-// UIViewPropertyAnimator for expanding the location bar.
-@property(nonatomic, strong)
-    UIViewPropertyAnimator* omniboxExpanderAnimator API_AVAILABLE(ios(10.0));
-
-// UIViewPropertyAnimator for contracting the location bar.
-@property(nonatomic, strong)
-    UIViewPropertyAnimator* omniboxContractorAnimator API_AVAILABLE(ios(10.0));
-
 // The view containing all the content of the toolbar. It respects the trailing
 // and leading anchors of the safe area.
 @property(nonatomic, readonly, strong) UIView* contentView;
@@ -93,13 +85,6 @@
 // animation used for Material.
 - (void)animateStandardControlsForOmniboxExpansion:(BOOL)growOmnibox;
 
-// Animates in the standard Toolbar buttons when the Location bar is
-// contracting.
-- (void)configureFadeInAnimation API_AVAILABLE(ios(10.0));
-
-// Animates out the standard Toolbar buttons when the Location bar is expanding.
-- (void)configureFadeOutAnimation API_AVAILABLE(ios(10.0));
-
 // Sets up |button| with images named by the given |imageEnum| and the current
 // toolbar style.  Sets images synchronously for |initialState|, and
 // asynchronously for the other states. Optionally sets the image for the
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_controller.h b/ios/chrome/browser/ui/toolbar/toolbar_controller.h
index 21eb9d11..31ce060 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_controller.h
+++ b/ios/chrome/browser/ui/toolbar/toolbar_controller.h
@@ -10,9 +10,9 @@
 #import "base/mac/scoped_nsobject.h"
 #import "ios/chrome/browser/ui/activity_services/requirements/activity_service_positioner.h"
 #import "ios/chrome/browser/ui/bubble/bubble_view_anchor_point_provider.h"
+#import "ios/chrome/browser/ui/toolbar/legacy_toolbar_view.h"
 #import "ios/chrome/browser/ui/toolbar/public/abstract_toolbar.h"
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_constants.h"
-#import "ios/chrome/browser/ui/toolbar/toolbar_view.h"
 #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_presentation_provider.h"
 #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_presentation_state_provider.h"
 
@@ -31,7 +31,7 @@
                                                 ToolsMenuPresentationProvider>
 
 // The top-level toolbar view.
-@property(nonatomic, strong) ToolbarView* view;
+@property(nonatomic, strong) LegacyToolbarView* view;
 // The view for the toolbar shadow image.  This is a subview of |view| to
 // allow clients to alter the visibility of the shadow without affecting other
 // components of the toolbar.
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
index 14d0f9b..3974f40c 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
@@ -81,12 +81,6 @@
   NSArray* standardButtons_;
   ToolsMenuButtonObserverBridge* toolsMenuButtonObserverBridge_;
   ToolbarControllerStyle style_;
-
-  // Backing object for |self.omniboxExpanderAnimator|.
-  API_AVAILABLE(ios(10.0)) UIViewPropertyAnimator* _omniboxExpanderAnimator;
-
-  // Backing object for |self.omniboxContractorAnimator|.
-  API_AVAILABLE(ios(10.0)) UIViewPropertyAnimator* _omniboxContractorAnimator;
 }
 
 // Leading and trailing safe area constraint for faking a safe area. These
@@ -153,7 +147,7 @@
       toolsMenuButtonFrame.origin.y += statusBarOffset;
     }
 
-    self.view = [[ToolbarView alloc] initWithFrame:viewFrame];
+    self.view = [[LegacyToolbarView alloc] initWithFrame:viewFrame];
     if (IsSafeAreaCompatibleToolbarEnabled()) {
       [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
     }
@@ -610,23 +604,6 @@
     [self fadeInStandardControls];
 }
 
-- (UIViewPropertyAnimator*)omniboxExpanderAnimator {
-  return _omniboxExpanderAnimator;
-}
-
-- (void)setOmniboxExpanderAnimator:
-    (UIViewPropertyAnimator*)omniboxExpanderAnimator {
-  _omniboxExpanderAnimator = omniboxExpanderAnimator;
-}
-
-- (UIViewPropertyAnimator*)omniboxContractorAnimator {
-  return _omniboxContractorAnimator;
-}
-
-- (void)setOmniboxContractorAnimator:
-    (UIViewPropertyAnimator*)omniboxContractorAnimator {
-  _omniboxContractorAnimator = omniboxContractorAnimator;
-}
 
 #pragma mark - ToolsMenuPresentationProvider
 
@@ -686,34 +663,6 @@
                    }];
 }
 
-- (void)configureFadeOutAnimation API_AVAILABLE(ios(10.0)) {
-  __weak NSArray* weakStandardButtons = standardButtons_;
-  __weak UIView* weakShadowView = shadowView_;
-  __weak UIView* weakFullBleedShadowView = fullBleedShadowView_;
-  [self.omniboxExpanderAnimator addAnimations:^{
-    // Animate the opacity of the buttons to 0 and 10 pixels in the
-    // leading-to-trailing direction.
-    for (UIButton* button in weakStandardButtons) {
-      if (![button isHidden])
-        button.alpha = 0;
-      button.frame = CGRectOffset(button.frame, kButtonFadeOutXOffset, 0);
-    }
-
-    // Fade to the full bleed shadow.
-    weakShadowView.alpha = 0;
-    weakFullBleedShadowView.alpha = 1;
-  }];
-
-  // After the animation is done and the buttons are hidden, move the buttons
-  // back to the position they originally were.
-  [self.omniboxExpanderAnimator
-      addCompletion:^(UIViewAnimatingPosition finalPosition) {
-        for (UIButton* button in weakStandardButtons) {
-          button.frame = CGRectOffset(button.frame, -kButtonFadeOutXOffset, 0);
-        }
-      }];
-}
-
 - (void)fadeInStandardControls {
   for (UIButton* button in standardButtons_) {
     [self fadeInView:button
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
index 186e94e0d..4913c7ec 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
@@ -193,10 +193,10 @@
       chrome_test_util::ButtonWithAccessibilityLabelId(IDS_IOS_ACCNAME_RELOAD);
   id<GREYMatcher> bookmarkButton =
       chrome_test_util::ButtonWithAccessibilityLabelId(IDS_TOOLTIP_STAR);
-  id<GREYMatcher> voiceSearchButton =
-      grey_allOf(chrome_test_util::ButtonWithAccessibilityLabelId(
-                     IDS_IOS_ACCNAME_VOICE_SEARCH),
-                 grey_ancestor(grey_kindOfClass([ToolbarView class])), nil);
+  id<GREYMatcher> voiceSearchButton = grey_allOf(
+      chrome_test_util::ButtonWithAccessibilityLabelId(
+          IDS_IOS_ACCNAME_VOICE_SEARCH),
+      grey_ancestor(grey_kindOfClass([LegacyToolbarView class])), nil);
   NSString* ntpOmniboxLabel = l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT);
   NSString* focusedOmniboxLabel = l10n_util::GetNSString(IDS_ACCNAME_LOCATION);
   NSString* omniboxLabel =
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
index 24547a08..17df181 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -885,28 +885,12 @@
 
 - (void)locationBarHasBecomeFirstResponder {
   [self.delegate locationBarDidBecomeFirstResponder];
-  if (@available(iOS 10, *)) {
-    if (base::FeatureList::IsEnabled(kPropertyAnimationsToolbar)) {
-      [self expandOmnibox];
-    } else {
-      [self animateMaterialOmnibox];
-    }
-  } else {
-    [self animateMaterialOmnibox];
-  }
+  [self animateMaterialOmnibox];
 }
 
 - (void)locationBarHasResignedFirstResponder {
   [self.delegate locationBarDidResignFirstResponder];
-  if (@available(iOS 10, *)) {
-    if (base::FeatureList::IsEnabled(kPropertyAnimationsToolbar)) {
-      [self contractOmnibox];
-    } else {
-      [self animateMaterialOmnibox];
-    }
-  } else {
-    [self animateMaterialOmnibox];
-  }
+  [self animateMaterialOmnibox];
 }
 
 - (void)locationBarBeganEdit {
@@ -1457,184 +1441,6 @@
 
 #pragma mark Omnibox Animation.
 
-- (void)expandOmnibox API_AVAILABLE(ios(10.0)) {
-  if (IsIPadIdiom())
-    return [self layoutOmnibox];
-
-  // Return if PropertyAnimator is already running.
-  if (self.omniboxExpanderAnimator.isRunning)
-    return;
-
-  CGRect newOmniboxFrame = [self newOmniboxFrame];
-  // Determine the starting and ending bounds and position for |_omniBox|.
-  // Increasing the height of _omniBox results in the text inside it jumping
-  // vertically during the animation, so the height change will not be animated.
-  LayoutRect toLayout =
-      LayoutRectForRectInBoundingRect(newOmniboxFrame, [_webToolbar bounds]);
-  CGRect omniboxRect = LayoutRectGetRect(kOmniboxFrame[IPHONE_IDIOM]);
-
-  toLayout.size = CGSizeMake([_webToolbar bounds].size.width -
-                                 self.cancelButton.frame.size.width -
-                                 kCancelButtonLeadingMargin,
-                             omniboxRect.size.height);
-  toLayout.position.leading = 0;
-  if (_incognito) {
-    // Adjust the width and leading of the omnibox to account for the
-    // incognito icon.
-    // TODO(crbug.com/525943): Refactor so this value isn't calculated here, and
-    // instead is calculated in -newOmniboxFrame?
-    // (include in (crbug/525943) refactor).
-    LayoutRect incognitioIconLayout = LayoutRectForRectInBoundingRect(
-        [_incognitoIcon frame], [_webToolbar frame]);
-    CGFloat trailingEdge = LayoutRectGetTrailingEdge(incognitioIconLayout);
-    toLayout.size.width -= trailingEdge;
-    toLayout.position.leading = trailingEdge;
-  }
-
-  CGRect toBounds = LayoutRectGetBoundsRect(toLayout);
-
-  // Grow the background to cover the whole toolbar.
-  CGRect backgroundToBounds = [_clippingView bounds];
-  // Increase the bounds of the background so that the border extends past the
-  // toolbar and is clipped.
-  backgroundToBounds = CGRectInset(backgroundToBounds, -2, -2);
-
-  if (_incognito)
-    _incognitoIcon.frame = CGRectMake(
-        _incognitoIcon.frame.origin.x + kPositionAnimationLeadingOffset,
-        _incognitoIcon.frame.origin.y, _incognitoIcon.frame.size.width,
-        _incognitoIcon.frame.size.height);
-
-  // Create animator and add animations.
-  self.omniboxExpanderAnimator = [[UIViewPropertyAnimator alloc]
-      initWithDuration:ios::material::kDuration1
-                 curve:UIViewAnimationCurveEaseInOut
-            animations:^{
-              CGFloat omniboxLeadingPadding = 10;
-
-              // Incognito.
-              if (_incognito) {
-                _incognitoIcon.alpha = 1;
-                _incognitoIcon.frame =
-                    CGRectMake(_incognitoIcon.frame.origin.x -
-                                   kPositionAnimationLeadingOffset,
-                               _incognitoIcon.frame.origin.y,
-                               _incognitoIcon.frame.size.width,
-                               _incognitoIcon.frame.size.height);
-                omniboxLeadingPadding =
-                    omniboxLeadingPadding + _incognitoIcon.frame.size.width;
-              }
-
-              // Omnibox and OmniboxBackground.
-              _locationBarView.frame =
-                  CGRectMake(newOmniboxFrame.origin.x + omniboxLeadingPadding,
-                             _locationBarView.frame.origin.y,
-                             toBounds.size.width - 10, toBounds.size.height);
-              _omniboxBackground.frame = CGRectMake(
-                  self.view.bounds.origin.x, self.view.bounds.origin.y,
-                  backgroundToBounds.size.width,
-                  backgroundToBounds.size.height);
-            }];
-
-  // Perfom cancel button animation on completion.
-  [_cancelButton setHidden:NO];
-  __weak UIButton* weakCancelButton = _cancelButton;
-  _cancelButton.alpha = 0;
-  [self.omniboxExpanderAnimator addCompletion:^(
-                                    UIViewAnimatingPosition finalPosition) {
-    CGRect finalCancelButtonFrame = weakCancelButton.frame;
-    weakCancelButton.frame = CGRectLayoutOffset(
-        weakCancelButton.frame, kPositionAnimationLeadingOffset);
-    // Create and start the cancel button animation.
-    [UIViewPropertyAnimator
-        runningPropertyAnimatorWithDuration:0.2
-                                      delay:0.1
-                                    options:UIViewAnimationOptionCurveEaseOut
-                                 animations:^{
-                                   weakCancelButton.alpha = 1.0;
-                                   weakCancelButton.frame =
-                                       finalCancelButtonFrame;
-                                 }
-                                 completion:nil];
-  }];
-
-  // Add standard Toolbar buttons animations.
-  [self configureFadeOutAnimation];
-
-  // Add navigation buttons animations.
-  [self configureFadeOutNavigationControlsAnimation];
-
-  // Set the _omnibox animator.
-  [_locationBarView addExpandOmniboxAnimations:self.omniboxExpanderAnimator];
-
-  [self.omniboxExpanderAnimator startAnimation];
-}
-
-- (void)contractOmnibox API_AVAILABLE(ios(10.0)) {
-  if (IsIPadIdiom())
-    return [self layoutOmnibox];
-
-  // Return if PropertyAnimator is already running.
-  if (self.omniboxContractorAnimator.isRunning)
-    return;
-
-  CGRect newOmniboxFrame = [self newOmniboxFrame];
-
-  __weak UIButton* weakCancelButton = _cancelButton;
-  self.omniboxContractorAnimator = [[UIViewPropertyAnimator alloc]
-      initWithDuration:ios::material::kDuration1
-                 curve:UIViewAnimationCurveEaseInOut
-            animations:^{
-
-              if (_incognito) {
-                _incognitoIcon.alpha = 0;
-                _incognitoIcon.frame =
-                    CGRectMake(_incognitoIcon.frame.origin.x +
-                                   kPositionAnimationLeadingOffset,
-                               _incognitoIcon.frame.origin.y,
-                               _incognitoIcon.frame.size.width,
-                               _incognitoIcon.frame.size.height);
-              }
-
-              // Cancel Button.
-              weakCancelButton.alpha = 0;
-              weakCancelButton.frame =
-                  CGRectMake(weakCancelButton.frame.origin.x +
-                                 kPositionAnimationLeadingOffset,
-                             weakCancelButton.frame.origin.y,
-                             weakCancelButton.frame.size.width,
-                             weakCancelButton.frame.size.height);
-
-              // Omnibox and OmniboxBackground bounds.
-              _locationBarView.frame = CGRectMake(
-                  newOmniboxFrame.origin.x, _locationBarView.frame.origin.y,
-                  newOmniboxFrame.size.width - 10, newOmniboxFrame.size.height);
-              _omniboxBackground.frame = CGRectMake(
-                  newOmniboxFrame.origin.x,
-                  newOmniboxFrame.origin.y + StatusBarHeight(),
-                  newOmniboxFrame.size.width - 10, newOmniboxFrame.size.height);
-
-            }];
-
-  // Hide cancel button on completion.
-  [self.omniboxContractorAnimator
-      addCompletion:^(UIViewAnimatingPosition finalPosition) {
-        weakCancelButton.hidden = YES;
-      }];
-
-  // Add standard Toolbar buttons animations.
-  [self configureFadeInAnimation];
-
-  // Add navigation buttons animations.
-  [self configureFadeInNavigationControlsAnimation];
-
-  // Set the _omnibox animator.
-  [_locationBarView
-      addContractOmniboxAnimations:self.omniboxContractorAnimator];
-
-  [self.omniboxContractorAnimator startAnimation];
-}
-
 - (void)animateMaterialOmnibox {
   // The iPad omnibox does not animate.
   if (IsIPadIdiom())
@@ -1935,31 +1741,6 @@
   }
 }
 
-- (void)configureFadeInNavigationControlsAnimation API_AVAILABLE(ios(10.0)) {
-  CGRect finalBackButtonFrame = _backButton.frame;
-  CGRect shifted =
-      CGRectLayoutOffset(_backButton.frame, kPositionAnimationLeadingOffset);
-  _backButton.frame = shifted;
-  __weak UIButton* weakBackButton = _backButton;
-  [self.omniboxContractorAnimator addAnimations:^{
-    weakBackButton.alpha = 1.0;
-    weakBackButton.frame = finalBackButtonFrame;
-  }
-                                    delayFactor:ios::material::kDuration1];
-
-  if ([_forwardButton isEnabled]) {
-    CGRect finalForwardButtonFrame = _forwardButton.frame;
-    _forwardButton.frame = CGRectLayoutOffset(_forwardButton.frame,
-                                              kPositionAnimationLeadingOffset);
-    __weak UIButton* weakForwardButton = _forwardButton;
-    [self.omniboxContractorAnimator addAnimations:^{
-      weakForwardButton.alpha = 1.0;
-      weakForwardButton.frame = finalForwardButtonFrame;
-    }
-                                      delayFactor:ios::material::kDuration3];
-  }
-}
-
 - (void)fadeOutNavigationControls {
   [CATransaction begin];
   [CATransaction setAnimationDuration:ios::material::kDuration2];
@@ -2002,35 +1783,6 @@
   [CATransaction commit];
 }
 
-- (void)configureFadeOutNavigationControlsAnimation API_AVAILABLE(ios(10.0)) {
-  // Animate the navigation buttons 10 pixels to the left and opacity to 0;
-  CGRect originalBackFrame = _backButton.frame;
-  __weak UIButton* weakBackButton = _backButton;
-  [self.omniboxExpanderAnimator addAnimations:^{
-    weakBackButton.alpha = 0.0;
-    weakBackButton.frame = CGRectLayoutOffset(weakBackButton.frame,
-                                              kPositionAnimationLeadingOffset);
-  }];
-  [self.omniboxExpanderAnimator
-      addCompletion:^(UIViewAnimatingPosition finalPosition) {
-        weakBackButton.frame = originalBackFrame;
-      }];
-
-  if ([_forwardButton isEnabled]) {
-    CGRect originalForwardFrame = _forwardButton.frame;
-    __weak UIButton* weakForwardButton = _forwardButton;
-    [self.omniboxExpanderAnimator addAnimations:^{
-      weakForwardButton.alpha = 0.0;
-      weakForwardButton.frame = CGRectLayoutOffset(
-          weakForwardButton.frame, kPositionAnimationLeadingOffset);
-    }];
-    [self.omniboxExpanderAnimator
-        addCompletion:^(UIViewAnimatingPosition finalPosition) {
-          weakForwardButton.frame = originalForwardFrame;
-        }];
-  }
-}
-
 #pragma mark Omnibox Cancel Button.
 
 - (UIButton*)cancelButton {
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index 6fb19257..f71a8ec 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -156,6 +156,7 @@
     "//components/strings",
     "//components/task_scheduler_util/browser",
     "//components/version_info",
+    "//ios/chrome/app/resources:ios_resources",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser",
     "//ios/chrome/browser:browser_impl",
diff --git a/ios/chrome/browser/web/chrome_web_client.h b/ios/chrome/browser/web/chrome_web_client.h
index 0f7a8cf..3b0d2a9 100644
--- a/ios/chrome/browser/web/chrome_web_client.h
+++ b/ios/chrome/browser/web/chrome_web_client.h
@@ -33,6 +33,8 @@
       int resource_id,
       ui::ScaleFactor scale_factor) const override;
   base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override;
+  std::unique_ptr<base::Value> GetServiceManifestOverlay(
+      base::StringPiece name) override;
   void GetAdditionalWebUISchemes(
       std::vector<std::string>* additional_schemes) override;
   void PostBrowserURLRewriterCreation(
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm
index 3e63a8d..5b5a14f6 100644
--- a/ios/chrome/browser/web/chrome_web_client.mm
+++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -8,6 +8,7 @@
 #include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/ios/ios_util.h"
+#include "base/json/json_reader.h"
 #include "base/mac/bundle_locations.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/sys_string_conversions.h"
@@ -27,10 +28,12 @@
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/chrome/browser/ssl/ios_ssl_error_handler.h"
 #import "ios/chrome/browser/ui/chrome_web_view_factory.h"
+#include "ios/chrome/grit/ios_resources.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #include "ios/public/provider/chrome/browser/voice/audio_session_controller.h"
 #include "ios/public/provider/chrome/browser/voice/voice_search_provider.h"
 #include "ios/web/public/browser_url_rewriter.h"
+#include "ios/web/public/service_names.mojom.h"
 #include "ios/web/public/user_agent.h"
 #include "net/http/http_util.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -153,6 +156,21 @@
       resource_id);
 }
 
+std::unique_ptr<base::Value> ChromeWebClient::GetServiceManifestOverlay(
+    base::StringPiece name) {
+  int identifier = -1;
+  if (name == web::mojom::kBrowserServiceName)
+    identifier = IDR_CHROME_BROWSER_MANIFEST_OVERLAY;
+
+  if (identifier == -1)
+    return nullptr;
+
+  base::StringPiece manifest_contents =
+      ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
+          identifier, ui::ScaleFactor::SCALE_FACTOR_NONE);
+  return base::JSONReader::Read(manifest_contents);
+}
+
 void ChromeWebClient::GetAdditionalWebUISchemes(
     std::vector<std::string>* additional_schemes) {
   additional_schemes->push_back(dom_distiller::kDomDistillerScheme);
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn
index f086fc72..b840deea 100644
--- a/ios/chrome/test/earl_grey/BUILD.gn
+++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -25,6 +25,7 @@
 chrome_ios_eg_test("ios_chrome_integration_egtests") {
   deps = [
     "//ios/chrome/browser/autofill:eg_tests",
+    "//ios/chrome/browser/browser_state:eg_tests",
     "//ios/chrome/browser/context_menu:eg_tests",
     "//ios/chrome/browser/device_sharing:eg_tests",
     "//ios/chrome/browser/feature_engagement:eg_tests",
@@ -32,6 +33,7 @@
     "//ios/chrome/browser/net:eg_tests",
     "//ios/chrome/browser/ntp_tiles:eg_tests",
     "//ios/chrome/browser/passwords:eg_tests",
+    "//ios/chrome/browser/prerender:eg_tests",
   ]
 }
 
diff --git a/ios/web/download/download_controller_impl.h b/ios/web/download/download_controller_impl.h
index c1f6443..f58fe6a 100644
--- a/ios/web/download/download_controller_impl.h
+++ b/ios/web/download/download_controller_impl.h
@@ -10,6 +10,7 @@
 #include <set>
 
 #include "base/macros.h"
+#include "base/sequence_checker.h"
 #include "base/supports_user_data.h"
 #import "ios/web/download/download_task_impl.h"
 #import "ios/web/public/download/download_controller.h"
@@ -34,6 +35,7 @@
                           int64_t total_bytes,
                           const std::string& mime_type) override;
   void SetDelegate(DownloadControllerDelegate* delegate) override;
+  DownloadControllerDelegate* GetDelegate() const override;
 
   // DownloadTaskImpl::Delegate overrides:
   void OnTaskDestroyed(DownloadTaskImpl* task) override;
@@ -45,6 +47,7 @@
   // Set of tasks which are currently alive.
   std::set<DownloadTaskImpl*> alive_tasks_;
   DownloadControllerDelegate* delegate_ = nullptr;
+  SEQUENCE_CHECKER(my_sequence_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(DownloadControllerImpl);
 };
diff --git a/ios/web/download/download_controller_impl.mm b/ios/web/download/download_controller_impl.mm
index 49395c6..3b8727a 100644
--- a/ios/web/download/download_controller_impl.mm
+++ b/ios/web/download/download_controller_impl.mm
@@ -7,7 +7,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "ios/web/public/browser_state.h"
 #import "ios/web/public/download/download_controller_delegate.h"
-#include "ios/web/public/web_thread.h"
 #import "net/base/mac/url_conversions.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -35,7 +34,7 @@
 DownloadControllerImpl::DownloadControllerImpl() = default;
 
 DownloadControllerImpl::~DownloadControllerImpl() {
-  DCHECK_CURRENTLY_ON(web::WebThread::UI);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   for (DownloadTaskImpl* task : alive_tasks_)
     task->ShutDown();
 
@@ -52,7 +51,7 @@
     const std::string& content_disposition,
     int64_t total_bytes,
     const std::string& mime_type) {
-  DCHECK_CURRENTLY_ON(web::WebThread::UI);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   if (!delegate_)
     return;
 
@@ -64,12 +63,17 @@
 }
 
 void DownloadControllerImpl::SetDelegate(DownloadControllerDelegate* delegate) {
-  DCHECK_CURRENTLY_ON(web::WebThread::UI);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   delegate_ = delegate;
 }
 
+DownloadControllerDelegate* DownloadControllerImpl::GetDelegate() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  return delegate_;
+}
+
 void DownloadControllerImpl::OnTaskDestroyed(DownloadTaskImpl* task) {
-  DCHECK_CURRENTLY_ON(web::WebThread::UI);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   auto it = alive_tasks_.find(task);
   DCHECK(it != alive_tasks_.end());
   alive_tasks_.erase(it);
diff --git a/ios/web/download/download_controller_impl_unittest.mm b/ios/web/download/download_controller_impl_unittest.mm
index dcd3c9d..3657f13 100644
--- a/ios/web/download/download_controller_impl_unittest.mm
+++ b/ios/web/download/download_controller_impl_unittest.mm
@@ -44,6 +44,11 @@
   FakeDownloadControllerDelegate delegate_;
 };
 
+// Tests that DownloadController::GetDelegate returns delegate_.
+TEST_F(DownloadControllerImplTest, Delegate) {
+  ASSERT_EQ(&delegate_, download_controller()->GetDelegate());
+}
+
 // Tests that DownloadController::FromBrowserState returns the same object for
 // each call.
 TEST_F(DownloadControllerImplTest, FromBrowserState) {
diff --git a/ios/web/public/download/download_controller.h b/ios/web/public/download/download_controller.h
index 1b8a97ed..43e2af96 100644
--- a/ios/web/public/download/download_controller.h
+++ b/ios/web/public/download/download_controller.h
@@ -106,6 +106,9 @@
   // DownloadControllerDelegate::OnDownloadControllerDestroyed().
   virtual void SetDelegate(DownloadControllerDelegate* delegate) = 0;
 
+  // Returns DownloadControllerDelegate.
+  virtual DownloadControllerDelegate* GetDelegate() const = 0;
+
   DownloadController() = default;
   virtual ~DownloadController() = default;
 
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 1777878..37f782b 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -289,9 +289,6 @@
   // TODO(crbug.com/549616): Remove this in favor of just updating the
   // navigation manager and treating that as authoritative.
   GURL _documentURL;
-  // Last URL change reported to webWill/DidStartLoadingURL. Used to detect page
-  // location changes (client redirects) in practice.
-  GURL _lastRegisteredRequestURL;
   // Page loading phase.
   web::LoadPhase _loadPhase;
   // The web::PageDisplayState recorded when the page starts loading.
@@ -1053,6 +1050,15 @@
 - (void)setWebUsageEnabled:(BOOL)enabled {
   if (_webUsageEnabled == enabled)
     return;
+  // WKWebView autoreleases its WKProcessPool on removal from superview.
+  // Deferring WKProcessPool deallocation may lead to issues with cookie
+  // clearing and and Browsing Data Partitioning implementation.
+  @autoreleasepool {
+    if (!enabled) {
+      [self removeWebView];
+    }
+  }
+
   _webUsageEnabled = enabled;
 
   // WKWebView autoreleases its WKProcessPool on removal from superview.
@@ -1064,7 +1070,6 @@
       // Don't create the web view; let it be lazy created as needed.
     } else {
       _webStateImpl->ClearTransientContent();
-      [self removeWebView];
       _touchTrackingRecognizer.touchTrackingDelegate = nil;
       _touchTrackingRecognizer = nil;
       [self resetContainerView];
@@ -1391,7 +1396,6 @@
   }
 
   _loadPhase = web::LOAD_REQUESTED;
-  _lastRegisteredRequestURL = requestURL;
 
   if (!redirect) {
     if (!self.nativeController) {
@@ -1554,21 +1558,7 @@
     [script appendString:[self javaScriptToDispatchHashChangeWithOldURL:oldURL
                                                                  newURL:URL]];
   }
-  __weak CRWWebController* weakSelf = self;
-  [self executeJavaScript:script
-        completionHandler:^(id, NSError*) {
-          CRWWebController* strongSelf = weakSelf;
-          if (strongSelf &&
-              !strongSelf->_isBeingDestroyed
-              // Make sure that no new navigation has started since URL value
-              // was captured to avoid clobbering _lastRegisteredRequestURL.
-              // See crbug.com/788231.
-              // TODO(crbug.com/788465): simplify history state handling to
-              // avoid this hack.
-              && currentItem == self.currentNavItem) {
-            strongSelf->_lastRegisteredRequestURL = URL;
-          }
-        }];
+  [self executeJavaScript:script completionHandler:nil];
 }
 
 // Load the current URL in a web view, first ensuring the web view is visible.
@@ -1991,28 +1981,6 @@
 
   [self optOutScrollsToTopForSubviews];
 
-  DCHECK((currentURL == _lastRegisteredRequestURL) ||  // latest navigation
-         // previous navigation
-         ![[_navigationStates lastAddedNavigation] isEqual:navigation] ||
-         // invalid URL load
-         (!_lastRegisteredRequestURL.is_valid() &&
-          _documentURL.spec() == url::kAboutBlankURL) ||
-         // about URL was changed by WebKit (e.g. about:newtab -> about:blank)
-         (_lastRegisteredRequestURL.scheme() == url::kAboutScheme &&
-          currentURL.spec() == url::kAboutBlankURL) ||
-         // In a very unfortunate edge case, window.history.didReplaceState
-         // message can arrive between the |webView:didCommitNavigation| and
-         // |webView:didFinishNavigation| callbacks of the page that contains
-         // the replaceState call. In this case, _lastRegisteredRequestURL and
-         // webView.URL are already updated to the replace state URL, but
-         // currentURL is still the old URL. See crbug.com/788464.
-         // TODO(crbug.com/788465): simplify history state handling to avoid
-         // this hack.
-         (_lastRegisteredRequestURL == net::GURLWithNSURL(_webView.URL)))
-      << std::endl
-      << "currentURL = [" << currentURL << "]" << std::endl
-      << "_lastRegisteredRequestURL = [" << _lastRegisteredRequestURL << "]";
-
   // Perform post-load-finished updates.
   [self didFinishWithURL:currentURL loadSuccess:loadSuccess];
 
@@ -2609,7 +2577,6 @@
     return NO;
   }
   NSString* stateObject = base::SysUTF8ToNSString(stateObjectJSON);
-  _lastRegisteredRequestURL = pushURL;
 
   // If the user interacted with the page, categorize it as a link navigation.
   // If not, categorize it is a client redirect as it occurred without user
@@ -2676,7 +2643,6 @@
     return NO;
   }
   NSString* stateObject = base::SysUTF8ToNSString(stateObjectJSON);
-  _lastRegisteredRequestURL = replaceURL;
   [self replaceStateWithPageURL:replaceURL stateObject:stateObject];
   NSString* replaceStateJS = [self javaScriptToReplaceWebViewURL:replaceURL
                                                  stateObjectJSON:stateObject];
@@ -4395,8 +4361,6 @@
         item->SetVirtualURL(webViewURL);
         item->SetURL(webViewURL);
       }
-
-      _lastRegisteredRequestURL = webViewURL;
     }
     _webStateImpl->OnNavigationStarted(context);
     return;
@@ -4556,10 +4520,6 @@
   BOOL isLastNavigation =
       !navigation ||
       [[_navigationStates lastAddedNavigation] isEqual:navigation];
-  DCHECK(_documentURL == _lastRegisteredRequestURL ||  // latest navigation
-         !isLastNavigation ||                          // previous navigation
-         (!_lastRegisteredRequestURL.is_valid() &&     // invalid URL load
-          _documentURL.spec() == url::kAboutBlankURL));
 
   // Update HTTP response headers.
   _webStateImpl->UpdateHttpResponseHeaders(_documentURL);
@@ -4866,6 +4826,9 @@
     return;
   }
 
+  web::NavigationContextImpl* existingContext =
+      [self contextForPendingNavigationWithURL:webViewURL];
+
   if (!navigationWasCommitted && ![_pendingNavigationInfo cancelled]) {
     // A fast back-forward navigation does not call |didCommitNavigation:|, so
     // signal page change explicitly.
@@ -4875,14 +4838,19 @@
     [self setDocumentURL:webViewURL];
     [self webPageChanged];
 
-    web::NavigationContextImpl* existingContext =
-        [self contextForPendingNavigationWithURL:webViewURL];
     if (!existingContext) {
       // This URL was not seen before, so register new load request.
       std::unique_ptr<web::NavigationContextImpl> newContext =
           [self registerLoadRequestForURL:webViewURL
                    sameDocumentNavigation:isSameDocumentNavigation];
       _webStateImpl->OnNavigationFinished(newContext.get());
+      // TODO(crbug.com/792515): It is OK, but very brittle, to call
+      // |didFinishNavigation:| here because the gating condition is mutually
+      // exclusive with the condition below. Refactor this method after
+      // deprecating _pendingNavigationInfo.
+      if (newContext->GetWKNavigationType() == WKNavigationTypeBackForward) {
+        [self didFinishNavigation:nil];
+      }
     } else {
       // Same document navigation does not contain response headers.
       net::HttpResponseHeaders* headers =
@@ -4896,9 +4864,10 @@
 
   [self updateSSLStatusForCurrentNavigationItem];
 
-  // Fast back forward navigation may not call |didFinishNavigation:|, so
-  // signal did finish navigation explicitly.
-  if (_lastRegisteredRequestURL == _documentURL) {
+  // WKWebView does not trigger |webView:didFinishNavigation| for back-forward
+  // navigations. So signal did finish navigation explicitly.
+  if (existingContext &&
+      existingContext->GetWKNavigationType() == WKNavigationTypeBackForward) {
     [self didFinishNavigation:nil];
   }
 }
@@ -5281,7 +5250,6 @@
 - (void)injectWebViewContentView:(CRWWebViewContentView*)webViewContentView {
   [self removeWebView];
 
-  _lastRegisteredRequestURL = _defaultURL;
   [_containerView displayWebViewContentView:webViewContentView];
   [self setWebView:static_cast<WKWebView*>(webViewContentView.webView)];
 }
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index a346f02..8602727c 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -65,6 +65,8 @@
   "internal/autofill/cwv_autofill_controller_internal.h",
   "internal/autofill/cwv_autofill_suggestion.mm",
   "internal/autofill/cwv_autofill_suggestion_internal.h",
+  "internal/autofill/web_view_autofill_client_ios.h",
+  "internal/autofill/web_view_autofill_client_ios.mm",
   "internal/autofill/web_view_personal_data_manager_factory.cc",
   "internal/autofill/web_view_personal_data_manager_factory.h",
   "internal/content_settings/web_view_cookie_settings_factory.cc",
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
index aa9fad5..1ae3fecd 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -12,7 +12,6 @@
 #include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/popup_item_ids.h"
 #import "components/autofill/ios/browser/autofill_agent.h"
-#import "components/autofill/ios/browser/autofill_client_ios.h"
 #include "components/autofill/ios/browser/autofill_driver_ios.h"
 #include "components/autofill/ios/browser/autofill_driver_ios_bridge.h"
 #import "components/autofill/ios/browser/js_autofill_manager.h"
@@ -24,6 +23,7 @@
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "ios/web_view/internal/app/application_context.h"
 #import "ios/web_view/internal/autofill/cwv_autofill_suggestion_internal.h"
+#import "ios/web_view/internal/autofill/web_view_autofill_client_ios.h"
 #include "ios/web_view/internal/autofill/web_view_personal_data_manager_factory.h"
 #include "ios/web_view/internal/signin/web_view_oauth2_token_service_factory.h"
 #include "ios/web_view/internal/signin/web_view_signin_manager_factory.h"
@@ -48,7 +48,7 @@
   autofill::AutofillManager* _autofillManager;
 
   // Autofill client associated with |webState|.
-  std::unique_ptr<autofill::AutofillClientIOS> _autofillClient;
+  std::unique_ptr<autofill::WebViewAutofillClientIOS> _autofillClient;
 
   // Javascript autofill manager associated with |webState|.
   JsAutofillManager* _JSAutofillManager;
@@ -83,7 +83,7 @@
             ios_web_view::WebViewOAuth2TokenServiceFactory::GetForBrowserState(
                 browserState),
             base::Closure()));
-    _autofillClient.reset(new autofill::AutofillClientIOS(
+    _autofillClient.reset(new autofill::WebViewAutofillClientIOS(
         browserState->GetPrefs(),
         ios_web_view::WebViewPersonalDataManagerFactory::GetForBrowserState(
             browserState),
diff --git a/components/autofill/ios/browser/autofill_client_ios.h b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
similarity index 77%
rename from components/autofill/ios/browser/autofill_client_ios.h
rename to ios/web_view/internal/autofill/web_view_autofill_client_ios.h
index 8f850eb..b6e341ee 100644
--- a/components/autofill/ios/browser/autofill_client_ios.h
+++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
@@ -1,47 +1,39 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// 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_AUTOFILL_IOS_BROWSER_AUTOFILL_CLIENT_IOS_H_
-#define COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_CLIENT_IOS_H_
+#ifndef IOS_WEB_VIEW_INTERNAL_AUTOFILL_WEB_VIEW_AUTOFILL_CLIENT_IOS_H_
+#define IOS_WEB_VIEW_INTERNAL_AUTOFILL_WEB_VIEW_AUTOFILL_CLIENT_IOS_H_
 
 #include <memory>
 #include <string>
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "components/autofill/core/browser/autofill_client.h"
-#include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h"
+#include "components/autofill/core/browser/card_unmask_delegate.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #import "components/autofill/ios/browser/autofill_client_ios_bridge.h"
-
-class IdentityProvider;
-
-namespace syncer {
-class SyncService;
-}
-
-namespace web {
-class WebState;
-}
-
-class PrefService;
+#include "components/prefs/pref_service.h"
+#include "components/sync/driver/sync_service.h"
+#include "google_apis/gaia/identity_provider.h"
+#import "ios/web/public/web_state/web_state.h"
 
 namespace autofill {
 
-class PersonalDataManager;
-
-// iOS implementation of AutofillClient.
-class AutofillClientIOS : public AutofillClient {
+// WebView implementation of AutofillClient.
+class WebViewAutofillClientIOS : public AutofillClient {
  public:
-  AutofillClientIOS(
+  WebViewAutofillClientIOS(
       PrefService* pref_service,
       PersonalDataManager* personal_data_manager,
       web::WebState* web_state,
       id<AutofillClientIOSBridge> bridge,
       std::unique_ptr<IdentityProvider> identity_provider,
       scoped_refptr<AutofillWebDataService> autofill_web_data_service);
-  ~AutofillClientIOS() override;
+  ~WebViewAutofillClientIOS() override;
 
   // AutofillClient implementation.
   PersonalDataManager* GetPersonalDataManager() override;
@@ -91,9 +83,6 @@
   bool IsAutofillSupported() override;
   void ExecuteCommand(int id) override;
 
- protected:
-  web::WebState* web_state() { return web_state_; }
-
  private:
   PrefService* pref_service_;
   PersonalDataManager* personal_data_manager_;
@@ -102,9 +91,9 @@
   std::unique_ptr<IdentityProvider> identity_provider_;
   scoped_refptr<AutofillWebDataService> autofill_web_data_service_;
 
-  DISALLOW_COPY_AND_ASSIGN(AutofillClientIOS);
+  DISALLOW_COPY_AND_ASSIGN(WebViewAutofillClientIOS);
 };
 
 }  // namespace autofill
 
-#endif  // COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_CLIENT_IOS_H_
+#endif  // IOS_WEB_VIEW_INTERNAL_AUTOFILL_WEB_VIEW_AUTOFILL_CLIENT_IOS_H_
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
new file mode 100644
index 0000000..fc3ac81d
--- /dev/null
+++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
@@ -0,0 +1,159 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/web_view/internal/autofill/web_view_autofill_client_ios.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "components/autofill/core/common/autofill_pref_names.h"
+#include "components/autofill/ios/browser/autofill_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace autofill {
+
+WebViewAutofillClientIOS::WebViewAutofillClientIOS(
+    PrefService* pref_service,
+    PersonalDataManager* personal_data_manager,
+    web::WebState* web_state,
+    id<AutofillClientIOSBridge> bridge,
+    std::unique_ptr<IdentityProvider> identity_provider,
+    scoped_refptr<AutofillWebDataService> autofill_web_data_service)
+    : pref_service_(pref_service),
+      personal_data_manager_(personal_data_manager),
+      web_state_(web_state),
+      bridge_(bridge),
+      identity_provider_(std::move(identity_provider)),
+      autofill_web_data_service_(autofill_web_data_service) {}
+
+WebViewAutofillClientIOS::~WebViewAutofillClientIOS() {
+  HideAutofillPopup();
+}
+
+PersonalDataManager* WebViewAutofillClientIOS::GetPersonalDataManager() {
+  return personal_data_manager_;
+}
+
+PrefService* WebViewAutofillClientIOS::GetPrefs() {
+  return pref_service_;
+}
+
+// TODO(crbug.com/535784): Implement this when adding credit card upload.
+syncer::SyncService* WebViewAutofillClientIOS::GetSyncService() {
+  return nullptr;
+}
+
+IdentityProvider* WebViewAutofillClientIOS::GetIdentityProvider() {
+  return identity_provider_.get();
+}
+
+ukm::UkmRecorder* WebViewAutofillClientIOS::GetUkmRecorder() {
+  return nullptr;
+}
+
+AddressNormalizer* WebViewAutofillClientIOS::GetAddressNormalizer() {
+  return nullptr;
+}
+
+SaveCardBubbleController*
+WebViewAutofillClientIOS::GetSaveCardBubbleController() {
+  return nullptr;
+}
+
+void WebViewAutofillClientIOS::ShowAutofillSettings() {
+  NOTREACHED();
+}
+
+void WebViewAutofillClientIOS::ShowUnmaskPrompt(
+    const CreditCard& card,
+    UnmaskCardReason reason,
+    base::WeakPtr<CardUnmaskDelegate> delegate) {}
+
+void WebViewAutofillClientIOS::OnUnmaskVerificationResult(
+    PaymentsRpcResult result) {}
+
+void WebViewAutofillClientIOS::ConfirmSaveCreditCardLocally(
+    const CreditCard& card,
+    const base::Closure& callback) {}
+
+void WebViewAutofillClientIOS::ConfirmSaveCreditCardToCloud(
+    const CreditCard& card,
+    std::unique_ptr<base::DictionaryValue> legal_message,
+    bool should_cvc_be_requested,
+    const base::Closure& callback) {}
+
+void WebViewAutofillClientIOS::ConfirmCreditCardFillAssist(
+    const CreditCard& card,
+    const base::Closure& callback) {}
+
+void WebViewAutofillClientIOS::LoadRiskData(
+    const base::Callback<void(const std::string&)>& callback) {}
+
+bool WebViewAutofillClientIOS::HasCreditCardScanFeature() {
+  return false;
+}
+
+void WebViewAutofillClientIOS::ScanCreditCard(
+    const CreditCardScanCallback& callback) {
+  NOTREACHED();
+}
+
+void WebViewAutofillClientIOS::ShowAutofillPopup(
+    const gfx::RectF& element_bounds,
+    base::i18n::TextDirection text_direction,
+    const std::vector<Suggestion>& suggestions,
+    base::WeakPtr<AutofillPopupDelegate> delegate) {
+  [bridge_ showAutofillPopup:suggestions popupDelegate:delegate];
+}
+
+void WebViewAutofillClientIOS::HideAutofillPopup() {
+  [bridge_ hideAutofillPopup];
+}
+
+bool WebViewAutofillClientIOS::IsAutocompleteEnabled() {
+  // For browser, Autocomplete is always enabled as part of Autofill.
+  return GetPrefs()->GetBoolean(prefs::kAutofillEnabled);
+}
+
+void WebViewAutofillClientIOS::UpdateAutofillPopupDataListValues(
+    const std::vector<base::string16>& values,
+    const std::vector<base::string16>& labels) {
+  NOTREACHED();
+}
+
+void WebViewAutofillClientIOS::PropagateAutofillPredictions(
+    content::RenderFrameHost* rfh,
+    const std::vector<FormStructure*>& forms) {}
+
+void WebViewAutofillClientIOS::DidFillOrPreviewField(
+    const base::string16& autofilled_value,
+    const base::string16& profile_full_name) {}
+
+scoped_refptr<AutofillWebDataService> WebViewAutofillClientIOS::GetDatabase() {
+  return autofill_web_data_service_;
+}
+
+void WebViewAutofillClientIOS::DidInteractWithNonsecureCreditCardInput() {}
+
+bool WebViewAutofillClientIOS::IsContextSecure() {
+  return IsContextSecureForWebState(web_state_);
+}
+
+bool WebViewAutofillClientIOS::ShouldShowSigninPromo() {
+  return false;
+}
+
+void WebViewAutofillClientIOS::ExecuteCommand(int id) {
+  NOTIMPLEMENTED();
+}
+
+bool WebViewAutofillClientIOS::IsAutofillSupported() {
+  return true;
+}
+
+}  // namespace autofill
diff --git a/ipc/SECURITY_OWNERS b/ipc/SECURITY_OWNERS
index 8bb1091..46e858e 100644
--- a/ipc/SECURITY_OWNERS
+++ b/ipc/SECURITY_OWNERS
@@ -1,5 +1,11 @@
-# Changes to IPC messages require a security review to avoid introducing
-# new sandbox escapes.
+# Changes to IPC messages require a security review to avoid introducing sandbox
+# escapes. The shared memory implementation code needs review from a security
+# owner. (Shared memory call sites should be reviewed as part of normal IPC
+# security review.)
+#
+# Security team: If you are uncomfortable reviewing a particular bit of code
+# yourself, don't hesitate to seek help from another security team member!
+# Nobody knows everything, and the only way to learn is from experience.
 dcheng@chromium.org
 estark@chromium.org
 kenrb@chromium.org
diff --git a/media/audio/cras/audio_manager_cras.cc b/media/audio/cras/audio_manager_cras.cc
index c3afdb0..844fb19 100644
--- a/media/audio/cras/audio_manager_cras.cc
+++ b/media/audio/cras/audio_manager_cras.cc
@@ -29,11 +29,6 @@
 #include "media/base/limits.h"
 #include "media/base/localized_strings.h"
 
-// cras_util.h headers pull in min/max macros...
-// TODO(dgreid): Fix headers such that these aren't imported.
-#undef min
-#undef max
-
 namespace media {
 namespace {
 
diff --git a/media/audio/fuchsia/audio_output_stream_fuchsia.cc b/media/audio/fuchsia/audio_output_stream_fuchsia.cc
index 5604bbd..896d5689 100644
--- a/media/audio/fuchsia/audio_output_stream_fuchsia.cc
+++ b/media/audio/fuchsia/audio_output_stream_fuchsia.cc
@@ -57,7 +57,6 @@
 }
 
 void AudioOutputStreamFuchsia::Stop() {
-  DCHECK(callback_);
   callback_ = nullptr;
   started_time_ = base::TimeTicks();
   timer_.Stop();
diff --git a/media/audio/mac/audio_device_listener_mac.cc b/media/audio/mac/audio_device_listener_mac.cc
index 5054d31..4c2691e 100644
--- a/media/audio/mac/audio_device_listener_mac.cc
+++ b/media/audio/mac/audio_device_listener_mac.cc
@@ -4,6 +4,8 @@
 
 #include "media/audio/mac/audio_device_listener_mac.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
@@ -13,29 +15,53 @@
 
 namespace media {
 
-// Property address to monitor for device changes.
+// Property property to monitor for device changes.
 const AudioObjectPropertyAddress
-AudioDeviceListenerMac::kDeviceChangePropertyAddress = {
-  kAudioHardwarePropertyDefaultOutputDevice,
-  kAudioObjectPropertyScopeGlobal,
-  kAudioObjectPropertyElementMaster
+    AudioDeviceListenerMac::kDefaultOutputDeviceChangePropertyAddress = {
+        kAudioHardwarePropertyDefaultOutputDevice,
+        kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster};
+
+const AudioObjectPropertyAddress
+    AudioDeviceListenerMac::kDefaultInputDeviceChangePropertyAddress = {
+        kAudioHardwarePropertyDefaultInputDevice,
+        kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster};
+
+const AudioObjectPropertyAddress
+    AudioDeviceListenerMac::kDevicesPropertyAddress = {
+        kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal,
+        kAudioObjectPropertyElementMaster};
+
+class AudioDeviceListenerMac::PropertyListener {
+ public:
+  PropertyListener(const AudioObjectPropertyAddress* property,
+                   AudioDeviceListenerMac* device_listener)
+      : address_(property), device_listener_(device_listener) {}
+
+  base::RepeatingClosure& callback() { return device_listener_->listener_cb_; }
+  const AudioObjectPropertyAddress* property() { return address_; }
+
+ private:
+  const AudioObjectPropertyAddress* address_;
+  AudioDeviceListenerMac* device_listener_;
 };
 
-// Callback from the system when the default device changes; this must be called
-// on the MessageLoop that created the AudioManager.
+// Callback from the system when an event occurs; this must be called on the
+// MessageLoop that created the AudioManager.
 // static
-OSStatus AudioDeviceListenerMac::OnDefaultDeviceChanged(
-    AudioObjectID object, UInt32 num_addresses,
-    const AudioObjectPropertyAddress addresses[], void* context) {
+OSStatus AudioDeviceListenerMac::OnEvent(
+    AudioObjectID object,
+    UInt32 num_addresses,
+    const AudioObjectPropertyAddress addresses[],
+    void* context) {
   if (object != kAudioObjectSystemObject)
     return noErr;
 
+  PropertyListener* listener = static_cast<PropertyListener*>(context);
   for (UInt32 i = 0; i < num_addresses; ++i) {
-    if (addresses[i].mSelector == kDeviceChangePropertyAddress.mSelector &&
-        addresses[i].mScope == kDeviceChangePropertyAddress.mScope &&
-        addresses[i].mElement == kDeviceChangePropertyAddress.mElement &&
-        context) {
-      static_cast<AudioDeviceListenerMac*>(context)->listener_cb_.Run();
+    if (addresses[i].mSelector == listener->property()->mSelector &&
+        addresses[i].mScope == listener->property()->mScope &&
+        addresses[i].mElement == listener->property()->mElement && context) {
+      listener->callback().Run();
       break;
     }
   }
@@ -44,30 +70,62 @@
 }
 
 AudioDeviceListenerMac::AudioDeviceListenerMac(
-    const base::Closure& listener_cb) {
-  OSStatus result = AudioObjectAddPropertyListener(
-      kAudioObjectSystemObject, &kDeviceChangePropertyAddress,
-      &AudioDeviceListenerMac::OnDefaultDeviceChanged, this);
+    const base::RepeatingClosure listener_cb,
+    bool monitor_default_input,
+    bool monitor_addition_removal) {
+  listener_cb_ = std::move(listener_cb);
 
-  if (result != noErr) {
-    OSSTATUS_DLOG(ERROR, result)
-        << "AudioObjectAddPropertyListener() failed!";
-    return;
+  // Changes to the default output device are always monitored.
+  default_output_listener_ = std::make_unique<PropertyListener>(
+      &kDefaultOutputDeviceChangePropertyAddress, this);
+  if (!AddPropertyListener(default_output_listener_.get()))
+    default_output_listener_.reset();
+
+  if (monitor_default_input) {
+    default_input_listener_ = std::make_unique<PropertyListener>(
+        &kDefaultInputDeviceChangePropertyAddress, this);
+    if (!AddPropertyListener(default_input_listener_.get()))
+      default_input_listener_.reset();
   }
 
-  listener_cb_ = listener_cb;
+  if (monitor_addition_removal) {
+    addition_removal_listener_ =
+        std::make_unique<PropertyListener>(&kDevicesPropertyAddress, this);
+    if (!AddPropertyListener(addition_removal_listener_.get()))
+      addition_removal_listener_.reset();
+  }
 }
 
 AudioDeviceListenerMac::~AudioDeviceListenerMac() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (listener_cb_.is_null())
-    return;
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   // Since we're running on the same CFRunLoop, there can be no outstanding
   // callbacks in flight.
+  if (default_output_listener_)
+    RemovePropertyListener(default_output_listener_.get());
+  if (default_input_listener_)
+    RemovePropertyListener(default_input_listener_.get());
+  if (addition_removal_listener_)
+    RemovePropertyListener(addition_removal_listener_.get());
+}
+
+bool AudioDeviceListenerMac::AddPropertyListener(
+    AudioDeviceListenerMac::PropertyListener* property_listener) {
+  OSStatus result = AudioObjectAddPropertyListener(
+      kAudioObjectSystemObject, property_listener->property(),
+      &AudioDeviceListenerMac::OnEvent, property_listener);
+  bool success = result == noErr;
+  if (!success)
+    OSSTATUS_DLOG(ERROR, result) << "AudioObjectAddPropertyListener() failed!";
+
+  return success;
+}
+
+void AudioDeviceListenerMac::RemovePropertyListener(
+    AudioDeviceListenerMac::PropertyListener* property_listener) {
   OSStatus result = AudioObjectRemovePropertyListener(
-      kAudioObjectSystemObject, &kDeviceChangePropertyAddress,
-      &AudioDeviceListenerMac::OnDefaultDeviceChanged, this);
+      kAudioObjectSystemObject, property_listener->property(),
+      &AudioDeviceListenerMac::OnEvent, property_listener);
   OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
       << "AudioObjectRemovePropertyListener() failed!";
 }
diff --git a/media/audio/mac/audio_device_listener_mac.h b/media/audio/mac/audio_device_listener_mac.h
index 1d02d9cb..3d2f5c42 100644
--- a/media/audio/mac/audio_device_listener_mac.h
+++ b/media/audio/mac/audio_device_listener_mac.h
@@ -7,6 +7,8 @@
 
 #include <CoreAudio/AudioHardware.h>
 
+#include <memory>
+
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
@@ -21,22 +23,36 @@
   // |listener_cb| will be called when a device change occurs; it's a permanent
   // callback and must outlive AudioDeviceListenerMac.  Note that |listener_cb|
   // might not be executed on the same thread as construction.
-  explicit AudioDeviceListenerMac(const base::Closure& listener_cb);
+  AudioDeviceListenerMac(base::RepeatingClosure listener_cb,
+                         bool monitor_default_input = false,
+                         bool monitor_addition_removal = false);
   ~AudioDeviceListenerMac();
 
  private:
   friend class AudioDeviceListenerMacTest;
-  static const AudioObjectPropertyAddress kDeviceChangePropertyAddress;
+  class PropertyListener;
+  static const AudioObjectPropertyAddress
+      kDefaultOutputDeviceChangePropertyAddress;
+  static const AudioObjectPropertyAddress
+      kDefaultInputDeviceChangePropertyAddress;
+  static const AudioObjectPropertyAddress kDevicesPropertyAddress;
 
-  static OSStatus OnDefaultDeviceChanged(
-      AudioObjectID object, UInt32 num_addresses,
-      const AudioObjectPropertyAddress addresses[], void* context);
+  static OSStatus OnEvent(AudioObjectID object,
+                          UInt32 num_addresses,
+                          const AudioObjectPropertyAddress addresses[],
+                          void* context);
 
-  base::Closure listener_cb_;
+  bool AddPropertyListener(PropertyListener* property_listener);
+  void RemovePropertyListener(PropertyListener* property_listener);
+
+  base::RepeatingClosure listener_cb_;
+  std::unique_ptr<PropertyListener> default_output_listener_;
+  std::unique_ptr<PropertyListener> default_input_listener_;
+  std::unique_ptr<PropertyListener> addition_removal_listener_;
 
   // AudioDeviceListenerMac must be constructed and destructed on the same
   // thread.
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(AudioDeviceListenerMac);
 };
diff --git a/media/audio/mac/audio_device_listener_mac_unittest.cc b/media/audio/mac/audio_device_listener_mac_unittest.cc
index 3b8384f6..94700767 100644
--- a/media/audio/mac/audio_device_listener_mac_unittest.cc
+++ b/media/audio/mac/audio_device_listener_mac_unittest.cc
@@ -44,49 +44,79 @@
   void CreateDeviceListener() {
     // Force a post task using BindToCurrentLoop() to ensure device listener
     // internals are working correctly.
-    output_device_listener_.reset(new AudioDeviceListenerMac(BindToCurrentLoop(
-        base::Bind(&AudioDeviceListenerMacTest::OnDeviceChange,
-                   base::Unretained(this)))));
+    device_listener_.reset(new AudioDeviceListenerMac(
+        BindToCurrentLoop(
+            base::Bind(&AudioDeviceListenerMacTest::OnDeviceChange,
+                       base::Unretained(this))),
+        true /* monitor_default_input */, true /* monitor_addition_removal */));
   }
 
-  void DestroyDeviceListener() {
-    output_device_listener_.reset();
-  }
+  void DestroyDeviceListener() { device_listener_.reset(); }
 
-  bool ListenerIsValid() {
-    return !output_device_listener_->listener_cb_.is_null();
-  }
+  bool ListenerIsValid() { return !device_listener_->listener_cb_.is_null(); }
 
-  // Simulate a device change where no output devices are available.
-  bool SimulateDefaultOutputDeviceChange() {
+  bool SimulateEvent(const AudioObjectPropertyAddress& address) {
     // Include multiple addresses to ensure only a single device change event
     // occurs.
     const AudioObjectPropertyAddress addresses[] = {
-      AudioDeviceListenerMac::kDeviceChangePropertyAddress,
-      { kAudioHardwarePropertyDevices,
-        kAudioObjectPropertyScopeGlobal,
-        kAudioObjectPropertyElementMaster }
-    };
+        address,
+        {kAudioHardwarePropertySleepingIsAllowed,
+         kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster}};
 
-    return noErr == output_device_listener_->OnDefaultDeviceChanged(
-        kAudioObjectSystemObject, 1, addresses, output_device_listener_.get());
+    OSStatus status = device_listener_->OnEvent(
+        kAudioObjectSystemObject, 2, addresses,
+        device_listener_->default_output_listener_.get());
+    if (status != noErr)
+      return false;
+
+    device_listener_->OnEvent(kAudioObjectSystemObject, 2, addresses,
+                              device_listener_->default_input_listener_.get());
+    if (status != noErr)
+      return false;
+
+    device_listener_->OnEvent(
+        kAudioObjectSystemObject, 2, addresses,
+        device_listener_->addition_removal_listener_.get());
+    return status == noErr;
+  }
+
+  bool SimulateDefaultOutputDeviceChange() {
+    return SimulateEvent(
+        AudioDeviceListenerMac::kDefaultOutputDeviceChangePropertyAddress);
+  }
+
+  bool SimulateDefaultInputDeviceChange() {
+    return SimulateEvent(
+        AudioDeviceListenerMac::kDefaultInputDeviceChangePropertyAddress);
+  }
+
+  bool SimulateDeviceAdditionRemoval() {
+    return SimulateEvent(AudioDeviceListenerMac::kDevicesPropertyAddress);
   }
 
   MOCK_METHOD0(OnDeviceChange, void());
 
  protected:
   base::MessageLoop message_loop_;
-  std::unique_ptr<AudioDeviceListenerMac> output_device_listener_;
+  std::unique_ptr<AudioDeviceListenerMac> device_listener_;
 
   DISALLOW_COPY_AND_ASSIGN(AudioDeviceListenerMacTest);
 };
 
-// Simulate a device change events and ensure we get the right callbacks.
-TEST_F(AudioDeviceListenerMacTest, OutputDeviceChange) {
+// Simulate a device change event and ensure we get the right callback.
+TEST_F(AudioDeviceListenerMacTest, Events) {
   ASSERT_TRUE(ListenerIsValid());
   EXPECT_CALL(*this, OnDeviceChange()).Times(1);
   ASSERT_TRUE(SimulateDefaultOutputDeviceChange());
   base::RunLoop().RunUntilIdle();
+
+  EXPECT_CALL(*this, OnDeviceChange()).Times(1);
+  ASSERT_TRUE(SimulateDefaultInputDeviceChange());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_CALL(*this, OnDeviceChange()).Times(1);
+  ASSERT_TRUE(SimulateDeviceAdditionRemoval());
+  base::RunLoop().RunUntilIdle();
 }
 
 }  // namespace media
diff --git a/media/base/content_decryption_module.h b/media/base/content_decryption_module.h
index 5d294f7..68caa1e 100644
--- a/media/base/content_decryption_module.h
+++ b/media/base/content_decryption_module.h
@@ -54,7 +54,8 @@
   LICENSE_REQUEST,
   LICENSE_RENEWAL,
   LICENSE_RELEASE,
-  MESSAGE_TYPE_MAX = LICENSE_RELEASE
+  INDIVIDUALIZATION_REQUEST,
+  MESSAGE_TYPE_MAX = INDIVIDUALIZATION_REQUEST
 };
 
 enum class HdcpVersion {
diff --git a/media/base/user_input_monitor_linux.cc b/media/base/user_input_monitor_linux.cc
index a1d3433..41fc05c 100644
--- a/media/base/user_input_monitor_linux.cc
+++ b/media/base/user_input_monitor_linux.cc
@@ -7,8 +7,6 @@
 #include <stddef.h>
 #include <sys/select.h>
 #include <unistd.h>
-#define XK_MISCELLANY
-#include <X11/keysymdef.h>
 
 #include "base/bind.h"
 #include "base/callback.h"
@@ -24,14 +22,9 @@
 #include "media/base/keyboard_event_counter.h"
 #include "third_party/skia/include/core/SkPoint.h"
 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
+#include "ui/gfx/x/x11.h"
 #include "ui/gfx/x/x11_types.h"
 
-// These includes need to be later than dictated by the style guide due to
-// Xlib header pollution, specifically the min, max, and Status macros.
-#include <X11/XKBlib.h>
-#include <X11/Xlibint.h>
-#include <X11/extensions/record.h>
-
 namespace media {
 namespace {
 
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.cc b/media/blink/webcontentdecryptionmodulesession_impl.cc
index c8f15ad6..df37559 100644
--- a/media/blink/webcontentdecryptionmodulesession_impl.cc
+++ b/media/blink/webcontentdecryptionmodulesession_impl.cc
@@ -57,6 +57,9 @@
     case CdmMessageType::LICENSE_RELEASE:
       return blink::WebContentDecryptionModuleSession::Client::MessageType::
           kLicenseRelease;
+    case CdmMessageType::INDIVIDUALIZATION_REQUEST:
+      return blink::WebContentDecryptionModuleSession::Client::MessageType::
+          kIndividualizationRequest;
   }
 
   NOTREACHED();
diff --git a/media/cast/test/linux_output_window.h b/media/cast/test/linux_output_window.h
index 3fd2c540..d4de979 100644
--- a/media/cast/test/linux_output_window.h
+++ b/media/cast/test/linux_output_window.h
@@ -5,9 +5,6 @@
 #ifndef MEDIA_CAST_TEST_LINUX_OUTPUT_WINDOW_H_
 #define MEDIA_CAST_TEST_LINUX_OUTPUT_WINDOW_H_
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
 
@@ -15,6 +12,7 @@
 #include <string>
 
 #include "base/memory/ref_counted.h"
+#include "ui/gfx/x/x11.h"
 
 namespace media {
 class VideoFrame;
diff --git a/media/cdm/cdm_adapter.cc b/media/cdm/cdm_adapter.cc
index 4fc87181..ffb76dc5 100644
--- a/media/cdm/cdm_adapter.cc
+++ b/media/cdm/cdm_adapter.cc
@@ -149,6 +149,8 @@
       return CdmMessageType::LICENSE_RENEWAL;
     case cdm::kLicenseRelease:
       return CdmMessageType::LICENSE_RELEASE;
+    case cdm::kIndividualizationRequest:
+      return CdmMessageType::INDIVIDUALIZATION_REQUEST;
   }
 
   NOTREACHED() << "Unexpected cdm::MessageType " << message_type;
@@ -400,15 +402,13 @@
   // If this check fails, update this function and DCHECK or update
   // IsSupportedCdmHostVersion.
 
-  DCHECK(
-      // Future version is not supported.
-      !IsSupportedCdmHostVersion(cdm::Host_9::kVersion + 1) &&
-      // Current version is supported.
-      IsSupportedCdmHostVersion(cdm::Host_9::kVersion) &&
-      // Include all previous supported versions (if any) here.
-      IsSupportedCdmHostVersion(cdm::Host_8::kVersion) &&
-      // One older than the oldest supported version is not supported.
-      !IsSupportedCdmHostVersion(cdm::Host_8::kVersion - 1));
+  // TODO(xhwang): Static assert these at compile time.
+  const int kMinVersion = cdm::ContentDecryptionModule_8::kVersion;
+  const int kMaxVersion = cdm::ContentDecryptionModule_10::kVersion;
+  DCHECK(!IsSupportedCdmInterfaceVersion(kMinVersion - 1));
+  for (int version = kMinVersion; version <= kMaxVersion; ++version)
+    DCHECK(IsSupportedCdmInterfaceVersion(version));
+  DCHECK(!IsSupportedCdmInterfaceVersion(kMaxVersion + 1));
   DCHECK(IsSupportedCdmHostVersion(host_interface_version));
 
   CdmAdapter* cdm_adapter = static_cast<CdmAdapter*>(user_data);
@@ -418,6 +418,8 @@
       return static_cast<cdm::Host_8*>(cdm_adapter);
     case cdm::Host_9::kVersion:
       return static_cast<cdm::Host_9*>(cdm_adapter);
+    case cdm::Host_10::kVersion:
+      return static_cast<cdm::Host_10*>(cdm_adapter);
     default:
       NOTREACHED() << "Unexpected host interface version "
                    << host_interface_version;
@@ -1169,6 +1171,12 @@
                                             weak_factory_.GetWeakPtr()));
 }
 
+cdm::CdmProxy* CdmAdapter::CreateCdmProxy() {
+  // TODO(xhwang): Implement this!
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
 void CdmAdapter::OnStorageIdObtained(uint32_t version,
                                      const std::vector<uint8_t>& storage_id) {
   cdm_->OnStorageId(version, storage_id.data(), storage_id.size());
diff --git a/media/cdm/cdm_adapter.h b/media/cdm/cdm_adapter.h
index 5d06ca04..3371719 100644
--- a/media/cdm/cdm_adapter.h
+++ b/media/cdm/cdm_adapter.h
@@ -40,7 +40,8 @@
                                 public CdmContext,
                                 public Decryptor,
                                 public cdm::Host_8,
-                                public cdm::Host_9 {
+                                public cdm::Host_9,
+                                public cdm::Host_10 {
  public:
   // Creates the CDM and initialize it using |key_system| and |cdm_config|.
   // |allocator| is to be used whenever the CDM needs memory and to create
@@ -142,6 +143,9 @@
   cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) override;
   void RequestStorageId(uint32_t version) override;
 
+  // cdm::Host_10 specific implementation.
+  cdm::CdmProxy* CreateCdmProxy() override;
+
   // cdm::Host_8 specific implementation.
   void OnRejectPromise(uint32_t promise_id,
                        cdm::Error error,
diff --git a/media/cdm/cdm_wrapper.h b/media/cdm/cdm_wrapper.h
index 2fdc73d..ca7822f 100644
--- a/media/cdm/cdm_wrapper.h
+++ b/media/cdm/cdm_wrapper.h
@@ -19,6 +19,7 @@
 #include "ppapi/cpp/logging.h"  // nogncheck
 #define PLATFORM_DCHECK PP_DCHECK
 #else
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "media/base/media_switches.h"  // nogncheck
 #define PLATFORM_DCHECK DCHECK
@@ -26,6 +27,19 @@
 
 namespace media {
 
+namespace {
+
+bool IsExperimentalCdmInterfaceSupported() {
+#if defined(USE_PPAPI_CDM_ADAPTER)
+  // No new CDM interface will be supported using pepper CDM.
+  return false;
+#else
+  return base::FeatureList::IsEnabled(media::kSupportExperimentalCdmInterface);
+#endif
+}
+
+}  // namespace
+
 // Returns a pointer to the requested CDM upon success.
 // Returns NULL if an error occurs or the requested |cdm_interface_version| or
 // |key_system| is not supported or another error occurs.
@@ -296,6 +310,7 @@
                                uint32_t key_system_size,
                                GetCdmHostFunc get_cdm_host_func,
                                void* user_data) {
+  // cdm::ContentDecryptionModule::kVersion is always the latest stable version.
   static_assert(cdm::ContentDecryptionModule::kVersion ==
                     cdm::ContentDecryptionModule_9::kVersion,
                 "update the code below");
@@ -304,23 +319,33 @@
   // Always update this DCHECK when updating this function.
   // If this check fails, update this function and DCHECK or update
   // IsSupportedCdmInterfaceVersion().
-  PLATFORM_DCHECK(!IsSupportedCdmInterfaceVersion(
-                      cdm::ContentDecryptionModule_9::kVersion + 1) &&
-                  IsSupportedCdmInterfaceVersion(
-                      cdm::ContentDecryptionModule_9::kVersion) &&
-                  IsSupportedCdmInterfaceVersion(
-                      cdm::ContentDecryptionModule_8::kVersion) &&
-                  !IsSupportedCdmInterfaceVersion(
-                      cdm::ContentDecryptionModule_8::kVersion - 1));
+  // TODO(xhwang): Static assert these at compile time.
+  const int kMinVersion = cdm::ContentDecryptionModule_8::kVersion;
+  const int kMaxVersion = cdm::ContentDecryptionModule_10::kVersion;
+  PLATFORM_DCHECK(!IsSupportedCdmInterfaceVersion(kMinVersion - 1));
+  for (int version = kMinVersion; version <= kMaxVersion; ++version)
+    PLATFORM_DCHECK(IsSupportedCdmInterfaceVersion(version));
+  PLATFORM_DCHECK(!IsSupportedCdmInterfaceVersion(kMaxVersion + 1));
 
   // Try to create the CDM using the latest CDM interface version.
   // This is only attempted if requested. For pepper plugins, this is done
   // at compile time. For mojo, it is done using a media feature setting.
   CdmWrapper* cdm_wrapper = nullptr;
 
-  cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_9>::Create(
-      create_cdm_func, key_system, key_system_size, get_cdm_host_func,
-      user_data);
+  // TODO(xhwang): Check whether we can use static loops to simplify this code.
+  if (IsExperimentalCdmInterfaceSupported()) {
+    cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_10>::Create(
+        create_cdm_func, key_system, key_system_size, get_cdm_host_func,
+        user_data);
+  }
+
+  // If |cdm_wrapper| is NULL, try to create the CDM using older supported
+  // versions of the CDM interface here.
+  if (!cdm_wrapper) {
+    cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_9>::Create(
+        create_cdm_func, key_system, key_system_size, get_cdm_host_func,
+        user_data);
+  }
 
   // If |cdm_wrapper| is NULL, try to create the CDM using older supported
   // versions of the CDM interface here.
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
index f981279..78ac868 100644
--- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
+++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -204,6 +204,8 @@
       return cdm::kLicenseRenewal;
     case media::CdmMessageType::LICENSE_RELEASE:
       return cdm::kLicenseRelease;
+    case media::CdmMessageType::INDIVIDUALIZATION_REQUEST:
+      return cdm::kIndividualizationRequest;
   }
 
   NOTREACHED();
diff --git a/media/cdm/ppapi/ppapi_cdm_adapter.cc b/media/cdm/ppapi/ppapi_cdm_adapter.cc
index afeb97c..c072060 100644
--- a/media/cdm/ppapi/ppapi_cdm_adapter.cc
+++ b/media/cdm/ppapi/ppapi_cdm_adapter.cc
@@ -334,6 +334,9 @@
       return PP_CDMMESSAGETYPE_LICENSE_RENEWAL;
     case cdm::kLicenseRelease:
       return PP_CDMMESSAGETYPE_LICENSE_RELEASE;
+    case cdm::kIndividualizationRequest:
+      PP_NOTREACHED();
+      return PP_CDMMESSAGETYPE_LICENSE_REQUEST;
   }
 
   PP_NOTREACHED();
@@ -1386,9 +1389,9 @@
 
   PP_DCHECK(
       // Future version is not supported.
-      !IsSupportedCdmHostVersion(cdm::Host_9::kVersion + 1) &&
+      !IsSupportedCdmHostVersion(cdm::Host_10::kVersion + 1) &&
       // Current version is supported.
-      IsSupportedCdmHostVersion(cdm::Host_9::kVersion) &&
+      IsSupportedCdmHostVersion(cdm::Host_10::kVersion) &&
       // Include all previous supported versions (if any) here.
       IsSupportedCdmHostVersion(cdm::Host_8::kVersion) &&
       // One older than the oldest supported version is not supported.
diff --git a/media/cdm/supported_cdm_versions.cc b/media/cdm/supported_cdm_versions.cc
index fe9b161..1fdf5b64 100644
--- a/media/cdm/supported_cdm_versions.cc
+++ b/media/cdm/supported_cdm_versions.cc
@@ -24,6 +24,7 @@
                 "update the code below");
   switch (version) {
     // Supported versions in decreasing order.
+    case cdm::ContentDecryptionModule_10::kVersion:
     case cdm::ContentDecryptionModule_9::kVersion:
     case cdm::ContentDecryptionModule_8::kVersion:
       return true;
@@ -38,6 +39,7 @@
                 "update the code below");
   switch (version) {
     // Supported versions in decreasing order.
+    case cdm::Host_10::kVersion:
     case cdm::Host_9::kVersion:
     case cdm::Host_8::kVersion:
       return true;
diff --git a/media/device_monitors/device_monitor_mac.h b/media/device_monitors/device_monitor_mac.h
index 0fee010..b7c85f9b 100644
--- a/media/device_monitors/device_monitor_mac.h
+++ b/media/device_monitors/device_monitor_mac.h
@@ -18,6 +18,8 @@
 
 namespace media {
 
+class AudioDeviceListenerMac;
+
 // Class to track audio/video devices removal or addition via callback to
 // base::SystemMonitor ProcessDevicesChanged(). A single object of this class
 // is created from the browser main process and lives as long as this one.
@@ -42,6 +44,7 @@
  private:
   scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
   std::unique_ptr<DeviceMonitorMacImpl> device_monitor_impl_;
+  std::unique_ptr<AudioDeviceListenerMac> audio_device_listener_;
 
   // |thread_checker_| is used to check that constructor and StartMonitoring()
   // are called in the correct thread, the UI thread, that also owns the object.
@@ -50,6 +53,6 @@
   DISALLOW_COPY_AND_ASSIGN(DeviceMonitorMac);
 };
 
-}  // namespace content
+}  // namespace media
 
 #endif  // MEDIA_DEVICE_MONITORS_DEVICE_MONITOR_MAC_H_
diff --git a/media/device_monitors/device_monitor_mac.mm b/media/device_monitors/device_monitor_mac.mm
index e8b5c2f..e6971722 100644
--- a/media/device_monitors/device_monitor_mac.mm
+++ b/media/device_monitors/device_monitor_mac.mm
@@ -14,6 +14,7 @@
 #include "base/macros.h"
 #include "base/task_runner_util.h"
 #include "base/threading/thread_checker.h"
+#include "media/audio/mac/audio_device_listener_mac.h"
 
 namespace {
 
@@ -82,9 +83,7 @@
 void DeviceMonitorMacImpl::ConsolidateDevicesListAndNotify(
     const std::vector<DeviceInfo>& snapshot_devices) {
   bool video_device_added = false;
-  bool audio_device_added = false;
   bool video_device_removed = false;
-  bool audio_device_removed = false;
 
   // Compare the current system devices snapshot with the ones cached to detect
   // additions, present in the former but not in the latter. If we find a device
@@ -97,9 +96,7 @@
     if (cached_devices_iterator == cached_devices_.end()) {
       video_device_added |= ((it->type() == DeviceInfo::kVideo) ||
                              (it->type() == DeviceInfo::kMuxed));
-      audio_device_added |= ((it->type() == DeviceInfo::kAudio) ||
-                             (it->type() == DeviceInfo::kMuxed));
-      DVLOG(1) << "Device has been added, id: " << it->unique_id();
+      DVLOG(1) << "Video device has been added, id: " << it->unique_id();
     } else {
       cached_devices_.erase(cached_devices_iterator);
     }
@@ -109,18 +106,13 @@
     video_device_removed |= ((it->type() == DeviceInfo::kVideo) ||
                              (it->type() == DeviceInfo::kMuxed) ||
                              (it->type() == DeviceInfo::kInvalid));
-    audio_device_removed |= ((it->type() == DeviceInfo::kAudio) ||
-                             (it->type() == DeviceInfo::kMuxed) ||
-                             (it->type() == DeviceInfo::kInvalid));
-    DVLOG(1) << "Device has been removed, id: " << it->unique_id();
+    DVLOG(1) << "Video device has been removed, id: " << it->unique_id();
   }
   // Update the cached devices with the current system snapshot.
   cached_devices_ = snapshot_devices;
 
   if (video_device_added || video_device_removed)
     monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
-  if (audio_device_added || audio_device_removed)
-    monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO);
 }
 
 // Forward declaration for use by CrAVFoundationDeviceObserver.
@@ -450,8 +442,16 @@
 void DeviceMonitorMac::StartMonitoring() {
   DCHECK(thread_checker_.CalledOnValidThread());
   DVLOG(1) << "Monitoring via AVFoundation";
-  device_monitor_impl_.reset(
-      new AVFoundationMonitorImpl(this, device_task_runner_));
+  device_monitor_impl_ =
+      std::make_unique<AVFoundationMonitorImpl>(this, device_task_runner_);
+  audio_device_listener_ = std::make_unique<AudioDeviceListenerMac>(
+      base::BindRepeating([] {
+        if (base::SystemMonitor::Get()) {
+          base::SystemMonitor::Get()->ProcessDevicesChanged(
+              base::SystemMonitor::DEVTYPE_AUDIO);
+        }
+      }),
+      true /* monitor_default_input */, true /* monitor_addition_removal */);
 }
 
 void DeviceMonitorMac::NotifyDeviceChanged(
diff --git a/media/formats/mp4/box_reader_unittest.cc b/media/formats/mp4/box_reader_unittest.cc
index 948845f..cc496d9 100644
--- a/media/formats/mp4/box_reader_unittest.cc
+++ b/media/formats/mp4/box_reader_unittest.cc
@@ -100,7 +100,7 @@
 
     EXPECT_EQ(result, ParseResult::kOk);
     EXPECT_TRUE(reader);
-    EXPECT_EQ(fourCC, reader->type());
+    EXPECT_EQ(fourCC, static_cast<uint32_t>(reader->type()));
     EXPECT_EQ(reader->box_size(), data_size);
   }
 
diff --git a/media/remoting/proto_enum_utils.cc b/media/remoting/proto_enum_utils.cc
index 9b2f6f6..2f7401a 100644
--- a/media/remoting/proto_enum_utils.cc
+++ b/media/remoting/proto_enum_utils.cc
@@ -514,6 +514,7 @@
     CASE_RETURN_OTHER(LICENSE_REQUEST);
     CASE_RETURN_OTHER(LICENSE_RENEWAL);
     CASE_RETURN_OTHER(LICENSE_RELEASE);
+    CASE_RETURN_OTHER(INDIVIDUALIZATION_REQUEST);
   }
   return base::nullopt;  // Not a 'default' to ensure compile-time checks.
 }
@@ -525,6 +526,7 @@
     CASE_RETURN_OTHER(LICENSE_REQUEST);
     CASE_RETURN_OTHER(LICENSE_RENEWAL);
     CASE_RETURN_OTHER(LICENSE_RELEASE);
+    CASE_RETURN_OTHER(INDIVIDUALIZATION_REQUEST);
   }
   return base::nullopt;  // Not a 'default' to ensure compile-time checks.
 }
diff --git a/media/remoting/rpc.proto b/media/remoting/rpc.proto
index a29dc16..8747856 100644
--- a/media/remoting/rpc.proto
+++ b/media/remoting/rpc.proto
@@ -297,6 +297,7 @@
   LICENSE_REQUEST = 0;
   LICENSE_RENEWAL = 1;
   LICENSE_RELEASE = 2;
+  INDIVIDUALIZATION_REQUEST = 3;
 }
 
 // Proto version of media::CdmSessionType.
diff --git a/media/renderers/video_renderer_impl_unittest.cc b/media/renderers/video_renderer_impl_unittest.cc
index 582f2b6..8013ead 100644
--- a/media/renderers/video_renderer_impl_unittest.cc
+++ b/media/renderers/video_renderer_impl_unittest.cc
@@ -769,9 +769,9 @@
       .WillRepeatedly(Return(base::TimeDelta::FromSeconds(4)));
 
   StartPlayingFrom(0);
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
 
   renderer_->OnTimeProgressing();
@@ -784,9 +784,9 @@
   event.RunAndWait();
 
   // No buffering should have been triggered due to speed.
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
   Destroy();
 }
@@ -828,9 +828,9 @@
       .WillRepeatedly(Return(base::TimeDelta::FromMilliseconds(100)));
 
   StartPlayingFrom(0);
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
 
   renderer_->OnTimeProgressing();
@@ -843,10 +843,10 @@
   event.RunAndWait();
 
   // No buffering should have been triggered due to memory pressure.
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
 
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
   Destroy();
 }
@@ -872,9 +872,9 @@
       .WillRepeatedly(Return(base::TimeDelta::FromMilliseconds(100)));
 
   StartPlayingFrom(0);
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
 
   renderer_->OnTimeProgressing();
@@ -887,9 +887,9 @@
   event.RunAndWait();
 
   // No buffering should have been triggered due to background rendering.
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
   Destroy();
 }
@@ -913,9 +913,9 @@
   StartPlayingFrom(0);
 
   // Prior to playback start no extended buffering should be triggered.
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
 
   renderer_->OnTimeProgressing();
@@ -928,9 +928,9 @@
     EXPECT_CALL(mock_cb_, FrameReceived(HasTimestampMatcher(1000)))
         .WillOnce(RunClosure(event.GetClosure()));
     event.RunAndWait();
-    EXPECT_EQ(limits::kMaxVideoFrames,
+    EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
               renderer_->min_buffered_frames_for_testing());
-    EXPECT_EQ(limits::kMaxVideoFrames,
+    EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
               renderer_->max_buffered_frames_for_testing());
   }
 
@@ -948,9 +948,9 @@
   Flush();
 
   // Ensure min/max buffered frames is reset.
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->min_buffered_frames_for_testing());
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
   Destroy();
 }
@@ -974,7 +974,7 @@
   StartPlayingFrom(0);
 
   // Prior to playback start no extended buffering should be triggered.
-  EXPECT_EQ(limits::kMaxVideoFrames,
+  EXPECT_EQ(static_cast<size_t>(limits::kMaxVideoFrames),
             renderer_->max_buffered_frames_for_testing());
 
   renderer_->OnTimeProgressing();
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 5524b0d..a807405 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1906,7 +1906,7 @@
     }
 
     if (use_gio) {
-      deps += [ "//build/linux/libgio" ]
+      configs += [ "//build/linux:gio_config" ]
     }
 
     if (!use_nss_certs) {
@@ -2306,9 +2306,7 @@
     "server/web_socket_encoder.cc",
     "server/web_socket_encoder.h",
   ]
-  configs += [
-    "//build/config/compiler:wexit_time_destructors",
-  ]
+  configs += [ "//build/config/compiler:wexit_time_destructors" ]
   deps = [
     ":net",
     "//base",
@@ -2660,9 +2658,7 @@
     "url_request/url_request_test_util.h",
   ]
 
-  configs += [
-    "//build/config:precompiled_headers",
-  ]
+  configs += [ "//build/config:precompiled_headers" ]
 
   public_deps = [
     ":traffic_annotation",
@@ -2769,6 +2765,7 @@
 
     configs += [
       "//build/config/compiler:wexit_time_destructors",
+      "//tools/v8_context_snapshot:use_v8_context_snapshot",
       "//v8:external_startup_data",
     ]
 
@@ -2779,6 +2776,7 @@
     deps = [
       "//base",
       "//gin",
+      "//tools/v8_context_snapshot",
       "//url",
       "//v8",
     ]
@@ -5307,9 +5305,7 @@
   ]
   net_unfiltered_sources = []
 
-  configs += [
-    "//build/config:precompiled_headers",
-  ]
+  configs += [ "//build/config:precompiled_headers" ]
   defines = []
 
   deps = [
diff --git a/net/base/prioritized_dispatcher_unittest.cc b/net/base/prioritized_dispatcher_unittest.cc
index 7d0b90e..3970ff4d 100644
--- a/net/base/prioritized_dispatcher_unittest.cc
+++ b/net/base/prioritized_dispatcher_unittest.cc
@@ -177,7 +177,8 @@
   // Get current limits, make sure the original limits are returned.
   PrioritizedDispatcher::Limits retrieved_limits = dispatcher_->GetLimits();
   ASSERT_EQ(original_limits.total_jobs, retrieved_limits.total_jobs);
-  ASSERT_EQ(NUM_PRIORITIES, retrieved_limits.reserved_slots.size());
+  ASSERT_EQ(static_cast<size_t>(NUM_PRIORITIES),
+            retrieved_limits.reserved_slots.size());
   for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY;
        ++priority) {
     EXPECT_EQ(original_limits.reserved_slots[priority],
@@ -193,7 +194,8 @@
   // Get current limits, make sure the new limits are returned.
   retrieved_limits = dispatcher_->GetLimits();
   ASSERT_EQ(new_limits.total_jobs, retrieved_limits.total_jobs);
-  ASSERT_EQ(NUM_PRIORITIES, retrieved_limits.reserved_slots.size());
+  ASSERT_EQ(static_cast<size_t>(NUM_PRIORITIES),
+            retrieved_limits.reserved_slots.size());
   for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY;
        ++priority) {
     EXPECT_EQ(new_limits.reserved_slots[priority],
diff --git a/net/cert/internal/revocation_checker.cc b/net/cert/internal/revocation_checker.cc
index a8333e2..e33f8e9f 100644
--- a/net/cert/internal/revocation_checker.cc
+++ b/net/cert/internal/revocation_checker.cc
@@ -242,6 +242,12 @@
         crypto::SHA256HashString(cert->tbs().spki_tlv.AsStringPiece());
     CRLSet::Result result = crl_set->CheckSPKI(spki_hash);
 
+    // Check for revocation using the certificate's Subject.
+    if (result != CRLSet::REVOKED) {
+      result = crl_set->CheckSubject(cert->tbs().subject_tlv.AsStringPiece(),
+                                     spki_hash);
+    }
+
     // Check for revocation using the certificate's serial number and issuer's
     // SPKI.
     if (result != CRLSet::REVOKED && !is_root) {
diff --git a/net/nqe/network_qualities_prefs_manager.cc b/net/nqe/network_qualities_prefs_manager.cc
index 7d860f02..f66b8bc 100644
--- a/net/nqe/network_qualities_prefs_manager.cc
+++ b/net/nqe/network_qualities_prefs_manager.cc
@@ -14,6 +14,7 @@
 #include "base/threading/thread_checker.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "net/nqe/network_quality_estimator.h"
+#include "net/nqe/network_quality_estimator_params.h"
 
 namespace net {
 
@@ -27,7 +28,7 @@
 // (ii)  Connection type of the network as reported by network
 //       change notifier (an enum).
 // (iii) Effective connection type of the network (an enum).
-constexpr size_t kMaxCacheSize = 10u;
+constexpr size_t kMaxCacheSize = 20u;
 
 // Parses |value| into a map of NetworkIDs and CachedNetworkQualities,
 // and returns the map.
@@ -133,6 +134,14 @@
   if (network_id_string.find('.') != std::string::npos)
     return;
 
+  if (cached_network_quality.effective_connection_type() ==
+      network_quality_estimator_->params()->GetDefaultECT(network_id.type)) {
+    // No need to cache the network quality since the default network quality
+    // (synthesized using the platform APIs) matches the observed network
+    // quality.
+    return;
+  }
+
   prefs_->SetString(network_id_string,
                     GetNameForEffectiveConnectionType(
                         cached_network_quality.effective_connection_type()));
diff --git a/net/nqe/network_qualities_prefs_manager_unittest.cc b/net/nqe/network_qualities_prefs_manager_unittest.cc
index 8d0657e..ea5b433 100644
--- a/net/nqe/network_qualities_prefs_manager_unittest.cc
+++ b/net/nqe/network_qualities_prefs_manager_unittest.cc
@@ -74,7 +74,12 @@
 };
 
 TEST(NetworkQualitiesPrefManager, Write) {
-  TestNetworkQualityEstimator estimator;
+  // Force set the ECT to Slow 2G so that the ECT does not match the default
+  // ECT for the current connection type. This forces the prefs to be written
+  // for the current connection.
+  std::map<std::string, std::string> variation_params;
+  variation_params["force_effective_connection_type"] = "Slow-2G";
+  TestNetworkQualityEstimator estimator(variation_params);
 
   std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
   TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();
@@ -114,8 +119,14 @@
 }
 
 TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
-  static const size_t kMaxCacheSize = 10u;
-  TestNetworkQualityEstimator estimator;
+  static const size_t kMaxCacheSize = 20u;
+
+  // Force set the ECT to Slow 2G so that the ECT does not match the default
+  // ECT for the current connection type. This forces the prefs to be written
+  // for the current connection.
+  std::map<std::string, std::string> variation_params;
+  variation_params["force_effective_connection_type"] = "Slow-2G";
+  TestNetworkQualityEstimator estimator(variation_params);
 
   std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
 
@@ -185,7 +196,12 @@
 
 // Verifies that the prefs are cleared correctly.
 TEST(NetworkQualitiesPrefManager, ClearPrefs) {
-  TestNetworkQualityEstimator estimator;
+  // Force set the ECT to Slow 2G so that the ECT does not match the default
+  // ECT for the current connection type. This forces the prefs to be written
+  // for the current connection.
+  std::map<std::string, std::string> variation_params;
+  variation_params["force_effective_connection_type"] = "Slow-2G";
+  TestNetworkQualityEstimator estimator(variation_params);
 
   std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
 
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h
index 85ae272..4190904c 100644
--- a/net/nqe/network_quality_estimator.h
+++ b/net/nqe/network_quality_estimator.h
@@ -214,6 +214,8 @@
       const std::map<nqe::internal::NetworkID,
                      nqe::internal::CachedNetworkQuality> read_prefs);
 
+  const NetworkQualityEstimatorParams* params() { return params_.get(); }
+
   typedef nqe::internal::Observation Observation;
   typedef nqe::internal::ObservationBuffer ObservationBuffer;
 
diff --git a/net/nqe/network_quality_estimator_params.cc b/net/nqe/network_quality_estimator_params.cc
index c393f54..8628570 100644
--- a/net/nqe/network_quality_estimator_params.cc
+++ b/net/nqe/network_quality_estimator_params.cc
@@ -164,7 +164,7 @@
                                     74);
 
   default_observations[NetworkChangeNotifier::CONNECTION_3G] =
-      nqe::internal::NetworkQuality(base::TimeDelta::FromMilliseconds(272),
+      nqe::internal::NetworkQuality(base::TimeDelta::FromMilliseconds(273),
                                     base::TimeDelta::FromMilliseconds(209),
                                     749);
 
@@ -304,7 +304,7 @@
   default_effective_connection_type_thresholds[EFFECTIVE_CONNECTION_TYPE_3G] =
       nqe::internal::NetworkQuality(
           // Set to the 50th percentile of 3G RTT observations on Android.
-          base::TimeDelta::FromMilliseconds(273),
+          base::TimeDelta::FromMilliseconds(272),
           base::TimeDelta::FromMilliseconds(204),
           nqe::internal::INVALID_RTT_THROUGHPUT);
 
@@ -562,4 +562,23 @@
   return effective_connection_type_algorithm_;
 }
 
+EffectiveConnectionType NetworkQualityEstimatorParams::GetDefaultECT(
+    NetworkChangeNotifier::ConnectionType connection_type) const {
+  switch (connection_type) {
+    case NetworkChangeNotifier::CONNECTION_UNKNOWN:
+    case NetworkChangeNotifier::CONNECTION_ETHERNET:
+    case NetworkChangeNotifier::CONNECTION_WIFI:
+    case NetworkChangeNotifier::CONNECTION_4G:
+    case NetworkChangeNotifier::CONNECTION_NONE:
+    case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
+      return EFFECTIVE_CONNECTION_TYPE_4G;
+    case NetworkChangeNotifier::CONNECTION_2G:
+      return EFFECTIVE_CONNECTION_TYPE_2G;
+    case NetworkChangeNotifier::CONNECTION_3G:
+      return EFFECTIVE_CONNECTION_TYPE_3G;
+  }
+  NOTREACHED();
+  return EFFECTIVE_CONNECTION_TYPE_4G;
+}
+
 }  // namespace net
diff --git a/net/nqe/network_quality_estimator_params.h b/net/nqe/network_quality_estimator_params.h
index 3a1b079..fab94a4 100644
--- a/net/nqe/network_quality_estimator_params.h
+++ b/net/nqe/network_quality_estimator_params.h
@@ -229,6 +229,10 @@
     return socket_watchers_min_notification_interval_;
   }
 
+  // Returns the default effective connection type for a given connection type.
+  EffectiveConnectionType GetDefaultECT(
+      NetworkChangeNotifier::ConnectionType connection_type) const;
+
  private:
   // Map containing all field trial parameters related to
   // NetworkQualityEstimator field trial.
diff --git a/net/nqe/network_quality_estimator_params_unittest.cc b/net/nqe/network_quality_estimator_params_unittest.cc
index 3626f19..93adb31 100644
--- a/net/nqe/network_quality_estimator_params_unittest.cc
+++ b/net/nqe/network_quality_estimator_params_unittest.cc
@@ -7,6 +7,7 @@
 #include <map>
 #include <string>
 
+#include "net/base/network_change_notifier.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
@@ -139,6 +140,61 @@
   }
 }
 
+// Verify that for a given connection type, the default network quality values
+// lie in the same range of ECT as the value returned by GetDefaultECT().
+TEST(NetworkQualityEstimatorParamsTest, GetDefaultECT) {
+  std::map<std::string, std::string> variation_params;
+  NetworkQualityEstimatorParams params(variation_params);
+
+  for (size_t i = 0; i < NetworkChangeNotifier::ConnectionType::CONNECTION_LAST;
+       ++i) {
+    NetworkChangeNotifier::ConnectionType connection_type =
+        static_cast<NetworkChangeNotifier::ConnectionType>(i);
+    EffectiveConnectionType ect = params.GetDefaultECT(connection_type);
+    EXPECT_LE(EFFECTIVE_CONNECTION_TYPE_2G, ect);
+
+    const nqe::internal::NetworkQuality& default_nq =
+        params.DefaultObservation(connection_type);
+
+    // Now verify that |default_nq| corresponds to |ect|.
+    if (ect == EFFECTIVE_CONNECTION_TYPE_4G) {
+      // If the expected effective connection type is 4G, then RTT values in
+      // |default_nq| should be lower than the threshold for ECT of 3G.
+      const nqe::internal::NetworkQuality& threshold_3g =
+          params.ConnectionThreshold(EFFECTIVE_CONNECTION_TYPE_3G);
+
+      EXPECT_LT(default_nq.http_rtt(), threshold_3g.http_rtt());
+      EXPECT_LT(default_nq.transport_rtt(), threshold_3g.transport_rtt());
+      EXPECT_TRUE(default_nq.downstream_throughput_kbps() >
+                      threshold_3g.downstream_throughput_kbps() ||
+                  threshold_3g.downstream_throughput_kbps() < 0);
+    } else {
+      // If the expected effective connection type is |ect|, then RTT values in
+      // |default_nq| should be (i) higher than the threshold for ECT of |ect|
+      // (ii) Lower than the threshold for |slower_ect|.
+      const nqe::internal::NetworkQuality& threshold_ect =
+          params.ConnectionThreshold(ect);
+      EffectiveConnectionType slower_ect =
+          static_cast<EffectiveConnectionType>(static_cast<int>(ect) - 1);
+      const nqe::internal::NetworkQuality& threshold_slower_ect =
+          params.ConnectionThreshold(slower_ect);
+
+      EXPECT_GT(default_nq.http_rtt(), threshold_ect.http_rtt());
+      EXPECT_GT(default_nq.transport_rtt(), threshold_ect.transport_rtt());
+      EXPECT_TRUE(default_nq.downstream_throughput_kbps() <
+                      threshold_ect.downstream_throughput_kbps() ||
+                  threshold_ect.downstream_throughput_kbps() < 0);
+
+      EXPECT_LT(default_nq.http_rtt(), threshold_slower_ect.http_rtt());
+      EXPECT_LT(default_nq.transport_rtt(),
+                threshold_slower_ect.transport_rtt());
+      EXPECT_TRUE(default_nq.downstream_throughput_kbps() >
+                      threshold_slower_ect.downstream_throughput_kbps() ||
+                  threshold_slower_ect.downstream_throughput_kbps() < 0);
+    }
+  }
+}
+
 }  // namespace
 
 }  // namespace internal
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc
index 1ee6136..72395a2 100644
--- a/net/nqe/network_quality_estimator_unittest.cc
+++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -730,7 +730,7 @@
       NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-3");
   EXPECT_TRUE(estimator.GetRecentHttpRTT(base::TimeTicks(), &rtt));
   // Taken from network_quality_estimator_params.cc.
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(272), rtt);
+  EXPECT_EQ(base::TimeDelta::FromMilliseconds(273), rtt);
   EXPECT_EQ(rtt, estimator.GetHttpRTT().value());
   EXPECT_TRUE(
       estimator.GetRecentTransportRTT(base::TimeTicks(), &rtt, nullptr));
@@ -760,7 +760,7 @@
           "effective_connection_type"));
 
   EXPECT_EQ(4, rtt_throughput_estimates_observer.notifications_received());
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(272),
+  EXPECT_EQ(base::TimeDelta::FromMilliseconds(273),
             rtt_throughput_estimates_observer.http_rtt());
   EXPECT_EQ(base::TimeDelta::FromMilliseconds(209),
             rtt_throughput_estimates_observer.transport_rtt());
@@ -768,7 +768,7 @@
             rtt_throughput_estimates_observer.downstream_throughput_kbps());
 
   EXPECT_EQ(2U, rtt_observer.observations().size());
-  EXPECT_EQ(272, rtt_observer.observations().at(0).rtt_ms);
+  EXPECT_EQ(273, rtt_observer.observations().at(0).rtt_ms);
   EXPECT_EQ(NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM,
             rtt_observer.observations().at(0).source);
   EXPECT_EQ(209, rtt_observer.observations().at(1).rtt_ms);
@@ -857,7 +857,7 @@
   estimator.SimulateNetworkChange(
       NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-3");
   EXPECT_TRUE(estimator.GetRecentHttpRTT(base::TimeTicks(), &rtt));
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(272), rtt);
+  EXPECT_EQ(base::TimeDelta::FromMilliseconds(273), rtt);
   EXPECT_EQ(rtt, estimator.GetHttpRTT().value());
   EXPECT_TRUE(
       estimator.GetRecentTransportRTT(base::TimeTicks(), &rtt, nullptr));
@@ -3053,7 +3053,7 @@
       base::RunLoop().Run();
 
       EXPECT_EQ(effective_connection_type,
-                estimator.GetEffectiveConnectionType());
+                static_cast<size_t>(estimator.GetEffectiveConnectionType()));
     }
   }
 }
diff --git a/net/proxy/proxy_config_service_linux.cc b/net/proxy/proxy_config_service_linux.cc
index 14e24fa..bebb917 100644
--- a/net/proxy/proxy_config_service_linux.cc
+++ b/net/proxy/proxy_config_service_linux.cc
@@ -5,9 +5,6 @@
 #include "net/proxy/proxy_config_service_linux.h"
 
 #include <errno.h>
-#if defined(USE_GCONF)
-#include <gconf/gconf-client.h>
-#endif  // defined(USE_GCONF)
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -42,8 +39,11 @@
 #include "net/proxy/proxy_server.h"
 #include "url/url_canon.h"
 
+#if defined(USE_GCONF)
+#include <gconf/gconf-client.h>
+#endif  // defined(USE_GCONF)
 #if defined(USE_GIO)
-#include "library_loaders/libgio.h"  // nogncheck
+#include <gio/gio.h>
 #endif  // defined(USE_GIO)
 
 namespace net {
@@ -520,7 +520,7 @@
 #endif  // defined(USE_GCONF)
 
 #if defined(USE_GIO)
-const char kProxyGConfSchema[] = "org.gnome.system.proxy";
+const char kProxyGSettingsSchema[] = "org.gnome.system.proxy";
 
 // This setting getter uses gsettings, as used in most GNOME 3 desktops.
 class SettingGetterImplGSettings
@@ -558,18 +558,8 @@
     DCHECK(!client_);
   }
 
-  bool SchemaExists(base::StringPiece schema_name) {
-    const gchar* const* schemas = libgio_loader_.g_settings_list_schemas();
-    while (*schemas) {
-      if (!strcmp(schema_name.data(), static_cast<const char*>(*schemas)))
-        return true;
-      schemas++;
-    }
-    return false;
-  }
-
-  // LoadAndCheckVersion() must be called *before* Init()!
-  bool LoadAndCheckVersion(base::Environment* env);
+  // CheckVersion() must be called *before* Init()!
+  bool CheckVersion(base::Environment* env);
 
   bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner)
       override {
@@ -577,18 +567,19 @@
     DCHECK(!client_);
     DCHECK(!task_runner_.get());
 
-    if (!SchemaExists(kProxyGConfSchema) ||
-        !(client_ = libgio_loader_.g_settings_new(kProxyGConfSchema))) {
+    if (!g_settings_schema_source_lookup(g_settings_schema_source_get_default(),
+                                         kProxyGSettingsSchema, FALSE) ||
+        !(client_ = g_settings_new(kProxyGSettingsSchema))) {
       // It's not clear whether/when this can return NULL.
       LOG(ERROR) << "Unable to create a gsettings client";
       return false;
     }
     task_runner_ = glib_task_runner;
     // We assume these all work if the above call worked.
-    http_client_ = libgio_loader_.g_settings_get_child(client_, "http");
-    https_client_ = libgio_loader_.g_settings_get_child(client_, "https");
-    ftp_client_ = libgio_loader_.g_settings_get_child(client_, "ftp");
-    socks_client_ = libgio_loader_.g_settings_get_child(client_, "socks");
+    http_client_ = g_settings_get_child(client_, "http");
+    https_client_ = g_settings_get_child(client_, "https");
+    ftp_client_ = g_settings_get_child(client_, "ftp");
+    socks_client_ = g_settings_get_child(client_, "socks");
     DCHECK(http_client_ && https_client_ && ftp_client_ && socks_client_);
     return true;
   }
@@ -713,7 +704,7 @@
                        base::StringPiece key,
                        std::string* result) {
     DCHECK(task_runner_->RunsTasksInCurrentSequence());
-    gchar* value = libgio_loader_.g_settings_get_string(client, key.data());
+    gchar* value = g_settings_get_string(client, key.data());
     if (!value)
       return false;
     *result = value;
@@ -722,20 +713,19 @@
   }
   bool GetBoolByPath(GSettings* client, base::StringPiece key, bool* result) {
     DCHECK(task_runner_->RunsTasksInCurrentSequence());
-    *result = static_cast<bool>(
-        libgio_loader_.g_settings_get_boolean(client, key.data()));
+    *result = static_cast<bool>(g_settings_get_boolean(client, key.data()));
     return true;
   }
   bool GetIntByPath(GSettings* client, base::StringPiece key, int* result) {
     DCHECK(task_runner_->RunsTasksInCurrentSequence());
-    *result = libgio_loader_.g_settings_get_int(client, key.data());
+    *result = g_settings_get_int(client, key.data());
     return true;
   }
   bool GetStringListByPath(GSettings* client,
                            base::StringPiece key,
                            std::vector<std::string>* result) {
     DCHECK(task_runner_->RunsTasksInCurrentSequence());
-    gchar** list = libgio_loader_.g_settings_get_strv(client, key.data());
+    gchar** list = g_settings_get_strv(client, key.data());
     if (!list)
       return false;
     for (size_t i = 0; list[i]; ++i) {
@@ -786,51 +776,18 @@
   // thread. Only for assertions.
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
-  LibGioLoader libgio_loader_;
-
   DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings);
 };
 
-bool SettingGetterImplGSettings::LoadAndCheckVersion(
+bool SettingGetterImplGSettings::CheckVersion(
     base::Environment* env) {
-  // LoadAndCheckVersion() must be called *before* Init()!
+  // CheckVersion() must be called *before* Init()!
   DCHECK(!client_);
 
-  // The APIs to query gsettings were introduced after the minimum glib
-  // version we target, so we can't link directly against them. We load them
-  // dynamically at runtime, and if they don't exist, return false here. (We
-  // support linking directly via gyp flags though.) Additionally, even when
-  // they are present, we do two additional checks to make sure we should use
-  // them and not gconf. First, we attempt to load the schema for proxy
-  // settings. Second, we check for the program that was used in older
-  // versions of GNOME to configure proxy settings, and return false if it
-  // exists. Some distributions (e.g. Ubuntu 11.04) have the API and schema
-  // but don't use gsettings for proxy settings, but they do have the old
-  // binary, so we detect these systems that way.
-
-  {
-    // TODO(phajdan.jr): Redesign the code to load library on different thread.
-    base::ThreadRestrictions::ScopedAllowIO allow_io;
-
-    // Try also without .0 at the end; on some systems this may be required.
-    if (!libgio_loader_.Load("libgio-2.0.so.0") &&
-        !libgio_loader_.Load("libgio-2.0.so")) {
-      VLOG(1) << "Cannot load gio library. Will fall back to gconf.";
-      return false;
-    }
-
-    // g_type_init will be deprecated in 2.36. 2.35 is the development
-    // version for 2.36, hence do not call g_type_init starting 2.35.
-    // http://developer.gnome.org/gobject/unstable/gobject-Type-Information.html#g-type-init
-    if (libgio_loader_.glib_check_version(2, 35, 0)) {
-      libgio_loader_.g_type_init();
-    }
-  }
-
   GSettings* client = nullptr;
-  if (SchemaExists(kProxyGConfSchema)) {
-    ANNOTATE_SCOPED_MEMORY_LEAK;  // http://crbug.com/380782
-    client = libgio_loader_.g_settings_new(kProxyGConfSchema);
+  if (g_settings_schema_source_lookup(g_settings_schema_source_get_default(),
+                                      kProxyGSettingsSchema, FALSE)) {
+    client = g_settings_new(kProxyGSettingsSchema);
   }
   if (!client) {
     VLOG(1) << "Cannot create gsettings client. Will fall back to gconf.";
@@ -1545,8 +1502,8 @@
       std::unique_ptr<SettingGetterImplGSettings> gs_getter(
           new SettingGetterImplGSettings());
       // We have to load symbols and check the GNOME version in use to decide
-      // if we should use the gsettings getter. See LoadAndCheckVersion().
-      if (gs_getter->LoadAndCheckVersion(env_var_getter_.get()))
+      // if we should use the gsettings getter. See CheckVersion().
+      if (gs_getter->CheckVersion(env_var_getter_.get()))
         setting_getter_ = std::move(gs_getter);
       }
 #endif
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 265aa69..88c9aa4 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -375,7 +375,10 @@
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
         gin::V8Initializer::LoadV8Snapshot();
         gin::V8Initializer::LoadV8Natives();
-#endif
+#ifdef USE_V8_CONTEXT_SNAPSHOT
+        gin::V8Initializer::LoadV8ContextSnapshot();
+#endif  // USE_V8_CONTEXT_SNAPSHOT
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
 
         // The performance of the proxy resolver is limited by DNS resolution,
         // and not V8, so tune down V8 to use as little memory as possible.
diff --git a/net/quic/core/crypto/crypto_server_test.cc b/net/quic/core/crypto/crypto_server_test.cc
index 346cc2a..00a8978 100644
--- a/net/quic/core/crypto/crypto_server_test.cc
+++ b/net/quic/core/crypto/crypto_server_test.cc
@@ -347,7 +347,8 @@
 
     EXPECT_EQ(expected_count, reject_reasons.size());
     for (size_t i = 0; i < reject_reasons.size(); ++i) {
-      EXPECT_EQ(expected_handshake_failures[i], reject_reasons[i]);
+      EXPECT_EQ(static_cast<QuicTag>(expected_handshake_failures[i]),
+                reject_reasons[i]);
     }
   }
 
diff --git a/net/reporting/reporting_browsing_data_remover_unittest.cc b/net/reporting/reporting_browsing_data_remover_unittest.cc
index 6ce6526..3d8d10d81 100644
--- a/net/reporting/reporting_browsing_data_remover_unittest.cc
+++ b/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -39,6 +39,19 @@
                                                      origin_filter);
   }
 
+  void AddReport(const GURL& url) {
+    cache()->AddReport(url, kGroup_, kType_,
+                       std::make_unique<base::DictionaryValue>(),
+                       tick_clock()->NowTicks(), 0);
+  }
+
+  void SetClient(const url::Origin& origin, const GURL& endpoint) {
+    cache()->SetClient(
+        origin, endpoint, ReportingClient::Subdomains::EXCLUDE, kGroup_,
+        tick_clock()->NowTicks() + base::TimeDelta::FromDays(7),
+        ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight);
+  }
+
   static bool HostIs(std::string host, const GURL& url) {
     return url.host() == host;
   }
@@ -65,18 +78,11 @@
 };
 
 TEST_F(ReportingBrowsingDataRemoverTest, RemoveNothing) {
-  cache()->AddReport(kUrl1_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->AddReport(kUrl2_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin1_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
-  cache()->SetClient(kOrigin2_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  AddReport(kUrl1_);
+  AddReport(kUrl2_);
+
+  SetClient(kOrigin1_, kEndpoint_);
+  SetClient(kOrigin2_, kEndpoint_);
 
   RemoveBrowsingData(/* remove_reports= */ false, /* remove_clients= */ false,
                      /* host= */ "");
@@ -85,18 +91,11 @@
 }
 
 TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllReports) {
-  cache()->AddReport(kUrl1_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->AddReport(kUrl2_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin1_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
-  cache()->SetClient(kOrigin2_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  AddReport(kUrl1_);
+  AddReport(kUrl2_);
+
+  SetClient(kOrigin1_, kEndpoint_);
+  SetClient(kOrigin2_, kEndpoint_);
 
   RemoveBrowsingData(/* remove_reports= */ true, /* remove_clients= */ false,
                      /* host= */ "");
@@ -105,18 +104,11 @@
 }
 
 TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllClients) {
-  cache()->AddReport(kUrl1_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->AddReport(kUrl2_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin1_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
-  cache()->SetClient(kOrigin2_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  AddReport(kUrl1_);
+  AddReport(kUrl2_);
+
+  SetClient(kOrigin1_, kEndpoint_);
+  SetClient(kOrigin2_, kEndpoint_);
 
   RemoveBrowsingData(/* remove_reports= */ false, /* remove_clients= */ true,
                      /* host= */ "");
@@ -125,18 +117,11 @@
 }
 
 TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllReportsAndClients) {
-  cache()->AddReport(kUrl1_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->AddReport(kUrl2_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin1_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
-  cache()->SetClient(kOrigin2_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  AddReport(kUrl1_);
+  AddReport(kUrl2_);
+
+  SetClient(kOrigin1_, kEndpoint_);
+  SetClient(kOrigin2_, kEndpoint_);
 
   RemoveBrowsingData(/* remove_reports= */ true, /* remove_clients= */ true,
                      /* host= */ "");
@@ -145,18 +130,11 @@
 }
 
 TEST_F(ReportingBrowsingDataRemoverTest, RemoveSomeReports) {
-  cache()->AddReport(kUrl1_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->AddReport(kUrl2_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin1_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
-  cache()->SetClient(kOrigin2_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  AddReport(kUrl1_);
+  AddReport(kUrl2_);
+
+  SetClient(kOrigin1_, kEndpoint_);
+  SetClient(kOrigin2_, kEndpoint_);
 
   RemoveBrowsingData(/* remove_reports= */ true, /* remove_clients= */ false,
                      /* host= */ kUrl1_.host());
@@ -169,18 +147,11 @@
 }
 
 TEST_F(ReportingBrowsingDataRemoverTest, RemoveSomeClients) {
-  cache()->AddReport(kUrl1_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->AddReport(kUrl2_, kGroup_, kType_,
-                     std::make_unique<base::DictionaryValue>(),
-                     tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin1_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
-  cache()->SetClient(kOrigin2_, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  AddReport(kUrl1_);
+  AddReport(kUrl2_);
+
+  SetClient(kOrigin1_, kEndpoint_);
+  SetClient(kOrigin2_, kEndpoint_);
 
   RemoveBrowsingData(/* remove_reports= */ false, /* remove_clients= */ true,
                      /* host= */ kUrl1_.host());
diff --git a/net/reporting/reporting_cache.cc b/net/reporting/reporting_cache.cc
index 4c06ede..0ed130b 100644
--- a/net/reporting/reporting_cache.cc
+++ b/net/reporting/reporting_cache.cc
@@ -171,7 +171,9 @@
                  const GURL& endpoint,
                  ReportingClient::Subdomains subdomains,
                  const std::string& group,
-                 base::TimeTicks expires) override {
+                 base::TimeTicks expires,
+                 int priority,
+                 int weight) override {
     DCHECK(endpoint.SchemeIsCryptographic());
 
     base::TimeTicks last_used = tick_clock()->NowTicks();
@@ -183,9 +185,10 @@
       RemoveClient(old_client);
     }
 
-    AddClient(std::make_unique<ReportingClient>(origin, endpoint, subdomains,
-                                                group, expires),
-              last_used);
+    AddClient(
+        std::make_unique<ReportingClient>(origin, endpoint, subdomains, group,
+                                          expires, priority, weight),
+        last_used);
 
     if (client_last_used_.size() > context_->policy().max_client_count) {
       // There should only ever be one extra client, added above.
diff --git a/net/reporting/reporting_cache.h b/net/reporting/reporting_cache.h
index fbe11da..eca3c5c 100644
--- a/net/reporting/reporting_cache.h
+++ b/net/reporting/reporting_cache.h
@@ -87,14 +87,16 @@
   // endpoint.
   //
   // All parameters correspond to the desired values for the fields in
-  // |Client|.
+  // ReportingClient.
   //
   // |endpoint| must use a cryptographic scheme.
   virtual void SetClient(const url::Origin& origin,
                          const GURL& endpoint,
                          ReportingClient::Subdomains subdomains,
                          const std::string& group,
-                         base::TimeTicks expires) = 0;
+                         base::TimeTicks expires,
+                         int priority,
+                         int client) = 0;
 
   virtual void MarkClientUsed(const url::Origin& origin,
                               const GURL& endpoint) = 0;
diff --git a/net/reporting/reporting_cache_unittest.cc b/net/reporting/reporting_cache_unittest.cc
index 9c77e71b..6e447fcf 100644
--- a/net/reporting/reporting_cache_unittest.cc
+++ b/net/reporting/reporting_cache_unittest.cc
@@ -60,6 +60,18 @@
     return clients.size();
   }
 
+  void SetClient(const url::Origin& origin,
+                 const GURL& endpoint,
+                 bool subdomains,
+                 const std::string& group,
+                 base::TimeTicks expires) {
+    cache()->SetClient(origin, endpoint,
+                       subdomains ? ReportingClient::Subdomains::INCLUDE
+                                  : ReportingClient::Subdomains::EXCLUDE,
+                       group, expires, ReportingClient::kDefaultPriority,
+                       ReportingClient::kDefaultWeight);
+  }
+
   const GURL kUrl1_ = GURL("https://origin1/path");
   const url::Origin kOrigin1_ = url::Origin::Create(GURL("https://origin1/"));
   const url::Origin kOrigin2_ = url::Origin::Create(GURL("https://origin2/"));
@@ -195,9 +207,7 @@
 }
 
 TEST_F(ReportingCacheTest, Endpoints) {
-  cache()->SetClient(kOrigin1_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
   EXPECT_EQ(1, observer()->cache_update_count());
 
   const ReportingClient* client =
@@ -209,8 +219,7 @@
   EXPECT_EQ(kGroup1_, client->group);
   EXPECT_EQ(kExpires1_, client->expires);
 
-  cache()->SetClient(kOrigin1_, kEndpoint1_,
-                     ReportingClient::Subdomains::INCLUDE, kGroup2, kExpires2_);
+  SetClient(kOrigin1_, kEndpoint1_, true, kGroup2, kExpires2_);
   EXPECT_EQ(2, observer()->cache_update_count());
 
   client = FindClientInCache(cache(), kOrigin1_, kEndpoint1_);
@@ -229,14 +238,9 @@
 }
 
 TEST_F(ReportingCacheTest, GetClientsForOriginAndGroup) {
-  cache()->SetClient(kOrigin1_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
-  cache()->SetClient(kOrigin1_, kEndpoint2_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup2, kExpires1_);
-  cache()->SetClient(kOrigin2_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+  SetClient(kOrigin1_, kEndpoint2_, false, kGroup2, kExpires1_);
+  SetClient(kOrigin2_, kEndpoint1_, false, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin1_, kGroup1_, &clients);
@@ -248,14 +252,9 @@
 }
 
 TEST_F(ReportingCacheTest, RemoveClientForOriginAndEndpoint) {
-  cache()->SetClient(kOrigin1_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
-  cache()->SetClient(kOrigin1_, kEndpoint2_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup2, kExpires1_);
-  cache()->SetClient(kOrigin2_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+  SetClient(kOrigin1_, kEndpoint2_, false, kGroup2, kExpires1_);
+  SetClient(kOrigin2_, kEndpoint1_, false, kGroup1_, kExpires1_);
   EXPECT_EQ(3, observer()->cache_update_count());
 
   cache()->RemoveClientForOriginAndEndpoint(kOrigin1_, kEndpoint1_);
@@ -273,14 +272,9 @@
 }
 
 TEST_F(ReportingCacheTest, RemoveClientsForEndpoint) {
-  cache()->SetClient(kOrigin1_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
-  cache()->SetClient(kOrigin1_, kEndpoint2_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup2, kExpires1_);
-  cache()->SetClient(kOrigin2_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+  SetClient(kOrigin1_, kEndpoint2_, false, kGroup2, kExpires1_);
+  SetClient(kOrigin2_, kEndpoint1_, false, kGroup1_, kExpires1_);
   EXPECT_EQ(3, observer()->cache_update_count());
 
   cache()->RemoveClientsForEndpoint(kEndpoint1_);
@@ -298,12 +292,8 @@
 }
 
 TEST_F(ReportingCacheTest, RemoveAllClients) {
-  cache()->SetClient(kOrigin1_, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
-  cache()->SetClient(kOrigin2_, kEndpoint2_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+  SetClient(kOrigin2_, kEndpoint2_, false, kGroup1_, kExpires1_);
   EXPECT_EQ(2, observer()->cache_update_count());
 
   cache()->RemoveAllClients();
@@ -319,9 +309,7 @@
   const url::Origin kDifferentPortOrigin =
       url::Origin::Create(GURL("https://example:444/"));
 
-  cache()->SetClient(kDifferentPortOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kDifferentPortOrigin, kEndpoint1_, false, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -333,9 +321,7 @@
   const url::Origin kSuperOrigin =
       url::Origin::Create(GURL("https://example/"));
 
-  cache()->SetClient(kSuperOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kSuperOrigin, kEndpoint1_, false, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -347,9 +333,7 @@
   const url::Origin kDifferentPortOrigin =
       url::Origin::Create(GURL("https://example:444/"));
 
-  cache()->SetClient(kDifferentPortOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::INCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kDifferentPortOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -362,9 +346,7 @@
   const url::Origin kSuperOrigin =
       url::Origin::Create(GURL("https://example/"));
 
-  cache()->SetClient(kSuperOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::INCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -377,11 +359,8 @@
   const url::Origin kDifferentPortOrigin =
       url::Origin::Create(GURL("https://example:444/"));
 
-  cache()->SetClient(kOrigin, kEndpoint1_, ReportingClient::Subdomains::INCLUDE,
-                     kGroup1_, kExpires1_);
-  cache()->SetClient(kDifferentPortOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::INCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
+  SetClient(kDifferentPortOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -394,11 +373,8 @@
   const url::Origin kSuperOrigin =
       url::Origin::Create(GURL("https://example/"));
 
-  cache()->SetClient(kOrigin, kEndpoint1_, ReportingClient::Subdomains::INCLUDE,
-                     kGroup1_, kExpires1_);
-  cache()->SetClient(kSuperOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::INCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
+  SetClient(kSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -414,12 +390,8 @@
   const url::Origin kSuperSuperOrigin =
       url::Origin::Create(GURL("https://example/"));
 
-  cache()->SetClient(kSuperOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::INCLUDE, kGroup1_,
-                     kExpires1_);
-  cache()->SetClient(kSuperSuperOrigin, kEndpoint1_,
-                     ReportingClient::Subdomains::INCLUDE, kGroup1_,
-                     kExpires1_);
+  SetClient(kSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
+  SetClient(kSuperSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
 
   std::vector<const ReportingClient*> clients;
   cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -502,9 +474,7 @@
   ASSERT_GT(std::numeric_limits<size_t>::max(), max_client_count);
 
   for (size_t i = 0; i < max_client_count; ++i) {
-    cache()->SetClient(kOrigin1_, MakeEndpoint(i),
-                       ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                       tomorrow());
+    SetClient(kOrigin1_, MakeEndpoint(i), false, kGroup1_, tomorrow());
   }
   EXPECT_EQ(max_client_count, client_count());
 
@@ -515,9 +485,8 @@
   }
 
   // Add one more client, forcing the cache to evict the LRU.
-  cache()->SetClient(kOrigin1_, MakeEndpoint(max_client_count),
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     tomorrow());
+  SetClient(kOrigin1_, MakeEndpoint(max_client_count), false, kGroup1_,
+            tomorrow());
   EXPECT_EQ(max_client_count, client_count());
   EXPECT_FALSE(FindClientInCache(cache(), kOrigin1_,
                                  MakeEndpoint(max_client_count - 1)));
@@ -532,15 +501,13 @@
   for (size_t i = 0; i < max_client_count; ++i) {
     base::TimeTicks expires =
         (i == max_client_count - 1) ? yesterday() : tomorrow();
-    cache()->SetClient(kOrigin1_, MakeEndpoint(i),
-                       ReportingClient::Subdomains::EXCLUDE, kGroup1_, expires);
+    SetClient(kOrigin1_, MakeEndpoint(i), false, kGroup1_, expires);
   }
   EXPECT_EQ(max_client_count, client_count());
 
   // Add one more client, forcing the cache to evict the expired one.
-  cache()->SetClient(kOrigin1_, MakeEndpoint(max_client_count),
-                     ReportingClient::Subdomains::EXCLUDE, kGroup1_,
-                     tomorrow());
+  SetClient(kOrigin1_, MakeEndpoint(max_client_count), false, kGroup1_,
+            tomorrow());
   EXPECT_EQ(max_client_count, client_count());
   EXPECT_FALSE(FindClientInCache(cache(), kOrigin1_,
                                  MakeEndpoint(max_client_count - 1)));
diff --git a/net/reporting/reporting_client.cc b/net/reporting/reporting_client.cc
index 609441d2..5f01048c 100644
--- a/net/reporting/reporting_client.cc
+++ b/net/reporting/reporting_client.cc
@@ -12,16 +12,26 @@
 
 namespace net {
 
+const char ReportingClient::kDefaultGroup[] = "default";
+const int ReportingClient::kDefaultPriority = 0;
+const int ReportingClient::kDefaultWeight = 1;
+
 ReportingClient::ReportingClient(const url::Origin& origin,
                                  const GURL& endpoint,
                                  Subdomains subdomains,
                                  const std::string& group,
-                                 base::TimeTicks expires)
+                                 base::TimeTicks expires,
+                                 int priority,
+                                 int weight)
     : origin(origin),
       endpoint(endpoint),
       subdomains(subdomains),
       group(group),
-      expires(expires) {}
+      expires(expires),
+      priority(priority),
+      weight(weight) {
+  DCHECK_LT(0, weight);
+}
 
 ReportingClient::~ReportingClient() = default;
 
diff --git a/net/reporting/reporting_client.h b/net/reporting/reporting_client.h
index 0aa11bea..c2b87f4 100644
--- a/net/reporting/reporting_client.h
+++ b/net/reporting/reporting_client.h
@@ -18,13 +18,19 @@
 // The configuration by an origin to use an endpoint for report delivery.
 struct NET_EXPORT ReportingClient {
  public:
+  static const char kDefaultGroup[];
+  static const int kDefaultPriority;
+  static const int kDefaultWeight;
+
   enum class Subdomains { EXCLUDE = 0, INCLUDE = 1 };
 
   ReportingClient(const url::Origin& origin,
                   const GURL& endpoint,
                   Subdomains subdomains,
                   const std::string& group,
-                  base::TimeTicks expires);
+                  base::TimeTicks expires,
+                  int priority,
+                  int weight);
   ~ReportingClient();
 
   // The origin from which reports will be delivered.
@@ -39,11 +45,20 @@
   Subdomains subdomains = Subdomains::EXCLUDE;
 
   // The endpoint group to which this client belongs.
-  std::string group = "default";
+  std::string group = kDefaultGroup;
 
   // When this client's max-age has expired.
   base::TimeTicks expires;
 
+  // Priority when multiple endpoints are configured for an origin; endpoints
+  // with numerically lower priorities are used first.
+  int priority = kDefaultPriority;
+
+  // Weight when multiple endpoints are configured for an origin with the same
+  // priority; among those with the same priority, each endpoint has a chance of
+  // being chosen that is proportional to its weight.
+  int weight = kDefaultWeight;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(ReportingClient);
 };
diff --git a/net/reporting/reporting_context.cc b/net/reporting/reporting_context.cc
index 4514993..8f2a280e 100644
--- a/net/reporting/reporting_context.cc
+++ b/net/reporting/reporting_context.cc
@@ -6,13 +6,16 @@
 
 #include <utility>
 
+#include "base/bind.h"
 #include "base/observer_list.h"
+#include "base/rand_util.h"
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
 #include "net/base/backoff_entry.h"
+#include "net/base/rand_callback.h"
 #include "net/reporting/reporting_cache.h"
 #include "net/reporting/reporting_delegate.h"
 #include "net/reporting/reporting_delivery_agent.h"
@@ -36,6 +39,7 @@
       : ReportingContext(policy,
                          base::DefaultClock::GetInstance(),
                          base::DefaultTickClock::GetInstance(),
+                         base::BindRepeating(&base::RandInt),
                          ReportingUploader::Create(request_context),
                          ReportingDelegate::Create(request_context)) {}
 };
@@ -69,6 +73,7 @@
 ReportingContext::ReportingContext(const ReportingPolicy& policy,
                                    base::Clock* clock,
                                    base::TickClock* tick_clock,
+                                   const RandIntCallback& rand_callback,
                                    std::unique_ptr<ReportingUploader> uploader,
                                    std::unique_ptr<ReportingDelegate> delegate)
     : policy_(policy),
@@ -77,7 +82,7 @@
       uploader_(std::move(uploader)),
       delegate_(std::move(delegate)),
       cache_(ReportingCache::Create(this)),
-      endpoint_manager_(ReportingEndpointManager::Create(this)),
+      endpoint_manager_(ReportingEndpointManager::Create(this, rand_callback)),
       delivery_agent_(ReportingDeliveryAgent::Create(this)),
       garbage_collector_(ReportingGarbageCollector::Create(this)),
       network_change_observer_(ReportingNetworkChangeObserver::Create(this)) {}
diff --git a/net/reporting/reporting_context.h b/net/reporting/reporting_context.h
index b38c176..9b4a6021 100644
--- a/net/reporting/reporting_context.h
+++ b/net/reporting/reporting_context.h
@@ -11,6 +11,7 @@
 #include "base/time/time.h"
 #include "net/base/backoff_entry.h"
 #include "net/base/net_export.h"
+#include "net/base/rand_callback.h"
 #include "net/reporting/reporting_policy.h"
 
 namespace base {
@@ -65,6 +66,7 @@
   ReportingContext(const ReportingPolicy& policy,
                    base::Clock* clock,
                    base::TickClock* tick_clock,
+                   const RandIntCallback& rand_callback,
                    std::unique_ptr<ReportingUploader> uploader,
                    std::unique_ptr<ReportingDelegate> delegate);
 
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc
index 4bc74893..c4e233a9 100644
--- a/net/reporting/reporting_delivery_agent_unittest.cc
+++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -42,6 +42,14 @@
     return tick_clock()->NowTicks() + base::TimeDelta::FromDays(1);
   }
 
+  void SetClient(const url::Origin& origin,
+                 const GURL& endpoint,
+                 const std::string& group) {
+    cache()->SetClient(origin, endpoint, ReportingClient::Subdomains::EXCLUDE,
+                       group, tomorrow(), ReportingClient::kDefaultPriority,
+                       ReportingClient::kDefaultWeight);
+  }
+
   const GURL kUrl_ = GURL("https://origin/path");
   const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
   const GURL kEndpoint_ = GURL("https://endpoint/");
@@ -55,8 +63,7 @@
   base::DictionaryValue body;
   body.SetString("key", "value");
 
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
   cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(),
                      tick_clock()->NowTicks(), 0);
 
@@ -94,8 +101,7 @@
 }
 
 TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
                      tick_clock()->NowTicks(), 0);
@@ -124,10 +130,8 @@
   static const url::Origin kDifferentOrigin =
       url::Origin::Create(GURL("https://origin2/"));
 
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
-  cache()->SetClient(kDifferentOrigin, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
+  SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
   ASSERT_TRUE(FindClientInCache(cache(), kOrigin_, kEndpoint_));
   ASSERT_TRUE(FindClientInCache(cache(), kDifferentOrigin, kEndpoint_));
 
@@ -159,8 +163,7 @@
 }
 
 TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) {
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
                      tick_clock()->NowTicks(), 0);
@@ -200,10 +203,8 @@
   static const url::Origin kDifferentOrigin =
       url::Origin::Create(kDifferentUrl);
 
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
-  cache()->SetClient(kDifferentOrigin, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
+  SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
 
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
@@ -228,10 +229,8 @@
   static const url::Origin kDifferentOrigin =
       url::Origin::Create(kDifferentUrl);
 
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
-  cache()->SetClient(kDifferentOrigin, kEndpoint_,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
+  SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
 
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
@@ -266,10 +265,8 @@
 TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) {
   static const GURL kDifferentEndpoint("https://endpoint2/");
 
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
-  cache()->SetClient(kOrigin_, kDifferentEndpoint,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
+  SetClient(kOrigin_, kDifferentEndpoint, kGroup_);
 
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
@@ -304,11 +301,8 @@
   static const GURL kDifferentEndpoint("https://endpoint2/");
   static const std::string kDifferentGroup("group2");
 
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
-  cache()->SetClient(kOrigin_, kDifferentEndpoint,
-                     ReportingClient::Subdomains::EXCLUDE, kDifferentGroup,
-                     tomorrow());
+  SetClient(kOrigin_, kEndpoint_, kGroup_);
+  SetClient(kOrigin_, kDifferentEndpoint, kDifferentGroup);
 
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
diff --git a/net/reporting/reporting_endpoint_manager.cc b/net/reporting/reporting_endpoint_manager.cc
index 6b7ac814..6a4c6c1 100644
--- a/net/reporting/reporting_endpoint_manager.cc
+++ b/net/reporting/reporting_endpoint_manager.cc
@@ -15,6 +15,7 @@
 #include "base/stl_util.h"
 #include "base/time/tick_clock.h"
 #include "net/base/backoff_entry.h"
+#include "net/base/rand_callback.h"
 #include "net/reporting/reporting_cache.h"
 #include "net/reporting/reporting_client.h"
 #include "net/reporting/reporting_delegate.h"
@@ -28,7 +29,9 @@
 
 class ReportingEndpointManagerImpl : public ReportingEndpointManager {
  public:
-  ReportingEndpointManagerImpl(ReportingContext* context) : context_(context) {}
+  ReportingEndpointManagerImpl(ReportingContext* context,
+                               const RandIntCallback& rand_callback)
+      : context_(context), rand_callback_(rand_callback) {}
 
   ~ReportingEndpointManagerImpl() override = default;
 
@@ -38,8 +41,12 @@
     std::vector<const ReportingClient*> clients;
     cache()->GetClientsForOriginAndGroup(origin, group, &clients);
 
-    // Filter out expired, pending, and backed-off endpoints.
+    // Highest-priority client(s) that are not expired, pending, failing, or
+    // forbidden for use by the ReportingDelegate.
     std::vector<const ReportingClient*> available_clients;
+    // Total weight of clients in available_clients.
+    int total_weight = 0;
+
     base::TimeTicks now = tick_clock()->NowTicks();
     for (const ReportingClient* client : clients) {
       if (client->expires < now)
@@ -52,7 +59,23 @@
       }
       if (!delegate()->CanUseClient(client->origin, client->endpoint))
         continue;
+
+      // If this client is lower priority than the ones we've found, skip it.
+      if (!available_clients.empty() &&
+          client->priority > available_clients[0]->priority) {
+        continue;
+      }
+
+      // If this client is higher priority than the ones we've found (or we
+      // haven't found any), forget about those ones and remember this one.
+      if (available_clients.empty() ||
+          client->priority < available_clients[0]->priority) {
+        available_clients.clear();
+        total_weight = 0;
+      }
+
       available_clients.push_back(client);
+      total_weight += client->weight;
     }
 
     if (available_clients.empty()) {
@@ -60,9 +83,20 @@
       return false;
     }
 
-    int random_index = base::RandInt(0, available_clients.size() - 1);
-    *endpoint_url_out = available_clients[random_index]->endpoint;
-    return true;
+    int random_index = rand_callback_.Run(0, total_weight - 1);
+    int weight_so_far = 0;
+    for (size_t i = 0; i < available_clients.size(); ++i) {
+      const ReportingClient* client = available_clients[i];
+      weight_so_far += client->weight;
+      if (random_index < weight_so_far) {
+        *endpoint_url_out = client->endpoint;
+        return true;
+      }
+    }
+
+    // TODO(juliatuttle): Can we reach this in some weird overflow case?
+    NOTREACHED();
+    return false;
   }
 
   void SetEndpointPending(const GURL& endpoint) override {
@@ -91,6 +125,8 @@
 
   ReportingContext* context_;
 
+  RandIntCallback rand_callback_;
+
   std::set<GURL> pending_endpoints_;
 
   // Note: Currently the ReportingBrowsingDataRemover does not clear this data
@@ -105,8 +141,9 @@
 
 // static
 std::unique_ptr<ReportingEndpointManager> ReportingEndpointManager::Create(
-    ReportingContext* context) {
-  return std::make_unique<ReportingEndpointManagerImpl>(context);
+    ReportingContext* context,
+    const RandIntCallback& rand_callback) {
+  return std::make_unique<ReportingEndpointManagerImpl>(context, rand_callback);
 }
 
 ReportingEndpointManager::~ReportingEndpointManager() = default;
diff --git a/net/reporting/reporting_endpoint_manager.h b/net/reporting/reporting_endpoint_manager.h
index 1f351984..6df5f38 100644
--- a/net/reporting/reporting_endpoint_manager.h
+++ b/net/reporting/reporting_endpoint_manager.h
@@ -10,6 +10,7 @@
 
 #include "base/macros.h"
 #include "net/base/net_export.h"
+#include "net/base/rand_callback.h"
 #include "net/reporting/reporting_context.h"
 
 class GURL;
@@ -27,7 +28,8 @@
  public:
   // |context| must outlive the ReportingEndpointManager.
   static std::unique_ptr<ReportingEndpointManager> Create(
-      ReportingContext* context);
+      ReportingContext* context,
+      const RandIntCallback& rand_callback);
 
   virtual ~ReportingEndpointManager();
 
diff --git a/net/reporting/reporting_endpoint_manager_unittest.cc b/net/reporting/reporting_endpoint_manager_unittest.cc
index 28915e0..de26c00 100644
--- a/net/reporting/reporting_endpoint_manager_unittest.cc
+++ b/net/reporting/reporting_endpoint_manager_unittest.cc
@@ -22,6 +22,11 @@
 
 class ReportingEndpointManagerTest : public ReportingTestBase {
  protected:
+  void SetClient(const GURL& endpoint, int priority, int weight) {
+    cache()->SetClient(kOrigin_, endpoint, ReportingClient::Subdomains::EXCLUDE,
+                       kGroup_, tomorrow(), priority, weight);
+  }
+
   const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
   const GURL kEndpoint_ = GURL("https://endpoint/");
   const std::string kGroup_ = "group";
@@ -35,8 +40,8 @@
 }
 
 TEST_F(ReportingEndpointManagerTest, Endpoint) {
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
+  SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+            ReportingClient::kDefaultWeight);
 
   GURL endpoint_url;
   bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
@@ -46,8 +51,11 @@
 }
 
 TEST_F(ReportingEndpointManagerTest, ExpiredEndpoint) {
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, yesterday());
+  SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+            ReportingClient::kDefaultWeight);
+
+  // Default expiration is "tomorrow", so make sure we're past that.
+  tick_clock()->Advance(base::TimeDelta::FromDays(2));
 
   GURL endpoint_url;
   bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
@@ -56,8 +64,8 @@
 }
 
 TEST_F(ReportingEndpointManagerTest, PendingEndpoint) {
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
+  SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+            ReportingClient::kDefaultWeight);
 
   endpoint_manager()->SetEndpointPending(kEndpoint_);
 
@@ -80,8 +88,8 @@
   base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(
       policy().endpoint_backoff_policy.initial_delay_ms);
 
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_, tomorrow());
+  SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+            ReportingClient::kDefaultWeight);
 
   endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false);
 
@@ -142,28 +150,28 @@
 // Make sure that multiple endpoints will all be returned at some point, to
 // avoid accidentally or intentionally implementing any priority ordering.
 TEST_F(ReportingEndpointManagerTest, RandomEndpoint) {
-  static const GURL kEndpoint_1("https://endpoint1/");
-  static const GURL kEndpoint_2("https://endpoint2/");
+  static const GURL kEndpoint1("https://endpoint1/");
+  static const GURL kEndpoint2("https://endpoint2/");
   static const int kMaxAttempts = 20;
 
-  cache()->SetClient(kOrigin_, kEndpoint_1,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
-  cache()->SetClient(kOrigin_, kEndpoint_2,
-                     ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+  SetClient(kEndpoint1, ReportingClient::kDefaultPriority,
+            ReportingClient::kDefaultWeight);
+  SetClient(kEndpoint2, ReportingClient::kDefaultPriority,
+            ReportingClient::kDefaultWeight);
 
   bool endpoint1_seen = false;
   bool endpoint2_seen = false;
 
-  for (int i = 0; i < kMaxAttempts; i++) {
+  for (int i = 0; i < kMaxAttempts; ++i) {
     GURL endpoint_url;
     bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
         kOrigin_, kGroup_, &endpoint_url);
     ASSERT_TRUE(found_endpoint);
-    ASSERT_TRUE(endpoint_url == kEndpoint_1 || endpoint_url == kEndpoint_2);
+    ASSERT_TRUE(endpoint_url == kEndpoint1 || endpoint_url == kEndpoint2);
 
-    if (endpoint_url == kEndpoint_1)
+    if (endpoint_url == kEndpoint1)
       endpoint1_seen = true;
-    else if (endpoint_url == kEndpoint_2)
+    else if (endpoint_url == kEndpoint2)
       endpoint2_seen = true;
 
     if (endpoint1_seen && endpoint2_seen)
@@ -174,5 +182,68 @@
   EXPECT_TRUE(endpoint2_seen);
 }
 
+TEST_F(ReportingEndpointManagerTest, Priority) {
+  static const GURL kPrimaryEndpoint("https://endpoint1/");
+  static const GURL kBackupEndpoint("https://endpoint2/");
+
+  SetClient(kPrimaryEndpoint, 10, ReportingClient::kDefaultWeight);
+  SetClient(kBackupEndpoint, 20, ReportingClient::kDefaultWeight);
+
+  GURL endpoint_url;
+
+  bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+      kOrigin_, kGroup_, &endpoint_url);
+  ASSERT_TRUE(found_endpoint);
+  EXPECT_EQ(kPrimaryEndpoint, endpoint_url);
+
+  endpoint_manager()->SetEndpointPending(kPrimaryEndpoint);
+
+  found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+      kOrigin_, kGroup_, &endpoint_url);
+  ASSERT_TRUE(found_endpoint);
+  EXPECT_EQ(kBackupEndpoint, endpoint_url);
+
+  endpoint_manager()->ClearEndpointPending(kPrimaryEndpoint);
+
+  found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+      kOrigin_, kGroup_, &endpoint_url);
+  ASSERT_TRUE(found_endpoint);
+  EXPECT_EQ(kPrimaryEndpoint, endpoint_url);
+}
+
+// Note: This test depends on the deterministic mock RandIntCallback set up in
+// TestReportingContext, which returns consecutive integers starting at 0
+// (modulo the requested range, plus the requested minimum).
+TEST_F(ReportingEndpointManagerTest, Weight) {
+  static const GURL kEndpoint1("https://endpoint1/");
+  static const GURL kEndpoint2("https://endpoint2/");
+
+  static const int kEndpoint1Weight = 5;
+  static const int kEndpoint2Weight = 2;
+  static const int kTotalEndpointWeight = kEndpoint1Weight + kEndpoint2Weight;
+
+  SetClient(kEndpoint1, ReportingClient::kDefaultPriority, kEndpoint1Weight);
+  SetClient(kEndpoint2, ReportingClient::kDefaultPriority, kEndpoint2Weight);
+
+  int endpoint1_count = 0;
+  int endpoint2_count = 0;
+
+  for (int i = 0; i < kTotalEndpointWeight; ++i) {
+    GURL endpoint_url;
+    bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+        kOrigin_, kGroup_, &endpoint_url);
+    ASSERT_TRUE(found_endpoint);
+    ASSERT_TRUE(endpoint_url == kEndpoint1 || endpoint_url == kEndpoint2);
+
+    if (endpoint_url == kEndpoint1)
+      ++endpoint1_count;
+    else if (endpoint_url == kEndpoint2)
+      ++endpoint2_count;
+  }
+
+  EXPECT_EQ(kEndpoint1Weight, endpoint1_count);
+  EXPECT_EQ(kEndpoint2Weight, endpoint2_count);
+}
+
 }  // namespace
 }  // namespace net
diff --git a/net/reporting/reporting_header_parser.cc b/net/reporting/reporting_header_parser.cc
index 9e1b7533..5512a5b 100644
--- a/net/reporting/reporting_header_parser.cc
+++ b/net/reporting/reporting_header_parser.cc
@@ -13,6 +13,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "net/reporting/reporting_cache.h"
+#include "net/reporting/reporting_client.h"
 #include "net/reporting/reporting_context.h"
 #include "net/reporting/reporting_delegate.h"
 
@@ -49,6 +50,10 @@
   SET_REJECTED_BY_DELEGATE = 10,
   SET = 11,
 
+  DISCARDED_PRIORITY_NOT_INTEGER = 12,
+  DISCARDED_WEIGHT_NOT_INTEGER = 13,
+  DISCARDED_WEIGHT_NOT_POSITIVE = 14,
+
   MAX
 };
 
@@ -68,6 +73,8 @@
 const char kGroupKey[] = "group";
 const char kGroupDefaultValue[] = "default";
 const char kMaxAgeKey[] = "max-age";
+const char kPriorityKey[] = "priority";
+const char kWeightKey[] = "weight";
 
 // Processes a single endpoint tuple received in a Report-To header.
 //
@@ -121,6 +128,16 @@
     subdomains = ReportingClient::Subdomains::INCLUDE;
   }
 
+  int priority = ReportingClient::kDefaultPriority;
+  if (dict->HasKey(kPriorityKey) && !dict->GetInteger(kPriorityKey, &priority))
+    return HeaderEndpointOutcome::DISCARDED_PRIORITY_NOT_INTEGER;
+
+  int weight = ReportingClient::kDefaultWeight;
+  if (dict->HasKey(kWeightKey) && !dict->GetInteger(kWeightKey, &weight))
+    return HeaderEndpointOutcome::DISCARDED_WEIGHT_NOT_INTEGER;
+  if (weight <= 0)
+    return HeaderEndpointOutcome::DISCARDED_WEIGHT_NOT_POSITIVE;
+
   *endpoint_url_out = endpoint_url;
 
   if (ttl_sec == 0) {
@@ -132,7 +149,8 @@
     return HeaderEndpointOutcome::SET_REJECTED_BY_DELEGATE;
 
   cache->SetClient(origin, endpoint_url, subdomains, group,
-                   now + base::TimeDelta::FromSeconds(ttl_sec));
+                   now + base::TimeDelta::FromSeconds(ttl_sec), priority,
+                   weight);
   return HeaderEndpointOutcome::SET;
 }
 
diff --git a/net/reporting/reporting_header_parser_unittest.cc b/net/reporting/reporting_header_parser_unittest.cc
index 8fe3f4f..151675e 100644
--- a/net/reporting/reporting_header_parser_unittest.cc
+++ b/net/reporting/reporting_header_parser_unittest.cc
@@ -49,6 +49,16 @@
       // Note that a non-boolean includeSubdomains field is *not* invalid, per
       // the spec.
 
+      {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"priority\":\"\"}",
+       "non-integer priority"},
+
+      {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"weight\":\"\"}",
+       "non-integer weight"},
+      {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"weight\":-1}",
+       "negative weight"},
+      {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"weight\":0}",
+       "zero weight"},
+
       {"[{\"url\":\"https://a/\",\"max-age\":1},"
        "{\"url\":\"https://b/\",\"max-age\":1}]",
        "wrapped in list"}};
@@ -78,6 +88,21 @@
   EXPECT_EQ(kEndpoint_, client->endpoint);
   EXPECT_EQ(ReportingClient::Subdomains::EXCLUDE, client->subdomains);
   EXPECT_EQ(86400, (client->expires - tick_clock()->NowTicks()).InSeconds());
+  EXPECT_EQ(ReportingClient::kDefaultPriority, client->priority);
+  EXPECT_EQ(ReportingClient::kDefaultWeight, client->weight);
+}
+
+TEST_F(ReportingHeaderParserTest, ZeroMaxAge) {
+  cache()->SetClient(
+      kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, kGroup_,
+      tick_clock()->NowTicks() + base::TimeDelta::FromDays(1),
+      ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight);
+
+  ReportingHeaderParser::ParseHeader(
+      context(), kUrl_,
+      "{\"url\":\"" + kEndpoint_.spec() + "\",\"max-age\":0}");
+
+  EXPECT_EQ(nullptr, FindClientInCache(cache(), kOrigin_, kEndpoint_));
 }
 
 TEST_F(ReportingHeaderParserTest, Subdomains) {
@@ -92,16 +117,40 @@
   EXPECT_EQ(ReportingClient::Subdomains::INCLUDE, client->subdomains);
 }
 
-TEST_F(ReportingHeaderParserTest, ZeroMaxAge) {
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(1));
+TEST_F(ReportingHeaderParserTest, PriorityPositive) {
+  ReportingHeaderParser::ParseHeader(context(), kUrl_,
+                                     "{\"url\":\"" + kEndpoint_.spec() +
+                                         "\",\"max-age\":86400,"
+                                         "\"priority\":2}");
 
-  ReportingHeaderParser::ParseHeader(
-      context(), kUrl_,
-      "{\"url\":\"" + kEndpoint_.spec() + "\",\"max-age\":0}");
+  const ReportingClient* client =
+      FindClientInCache(cache(), kOrigin_, kEndpoint_);
+  ASSERT_TRUE(client);
+  EXPECT_EQ(2, client->priority);
+}
 
-  EXPECT_EQ(nullptr, FindClientInCache(cache(), kOrigin_, kEndpoint_));
+TEST_F(ReportingHeaderParserTest, PriorityNegative) {
+  ReportingHeaderParser::ParseHeader(context(), kUrl_,
+                                     "{\"url\":\"" + kEndpoint_.spec() +
+                                         "\",\"max-age\":86400,"
+                                         "\"priority\":-2}");
+
+  const ReportingClient* client =
+      FindClientInCache(cache(), kOrigin_, kEndpoint_);
+  ASSERT_TRUE(client);
+  EXPECT_EQ(-2, client->priority);
+}
+
+TEST_F(ReportingHeaderParserTest, Weight) {
+  ReportingHeaderParser::ParseHeader(context(), kUrl_,
+                                     "{\"url\":\"" + kEndpoint_.spec() +
+                                         "\",\"max-age\":86400,"
+                                         "\"weight\":3}");
+
+  const ReportingClient* client =
+      FindClientInCache(cache(), kOrigin_, kEndpoint_);
+  ASSERT_TRUE(client);
+  EXPECT_EQ(3, client->weight);
 }
 
 TEST_F(ReportingHeaderParserTest, RemoveOld) {
diff --git a/net/reporting/reporting_network_change_observer_unittest.cc b/net/reporting/reporting_network_change_observer_unittest.cc
index 8350e8d..ce114d1 100644
--- a/net/reporting/reporting_network_change_observer_unittest.cc
+++ b/net/reporting/reporting_network_change_observer_unittest.cc
@@ -32,6 +32,13 @@
     base::RunLoop().RunUntilIdle();
   }
 
+  void SetClient() {
+    cache()->SetClient(
+        kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, kGroup_,
+        tick_clock()->NowTicks() + base::TimeDelta::FromDays(7),
+        ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight);
+  }
+
   size_t report_count() {
     std::vector<const ReportingReport*> reports;
     cache()->GetReports(&reports);
@@ -60,9 +67,7 @@
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
                      tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  SetClient();
   ASSERT_EQ(1u, report_count());
   ASSERT_EQ(1u, client_count());
 
@@ -81,9 +86,7 @@
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
                      tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  SetClient();
   ASSERT_EQ(1u, report_count());
   ASSERT_EQ(1u, client_count());
 
@@ -102,9 +105,7 @@
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
                      tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  SetClient();
   ASSERT_EQ(1u, report_count());
   ASSERT_EQ(1u, client_count());
 
@@ -123,9 +124,7 @@
   cache()->AddReport(kUrl_, kGroup_, kType_,
                      std::make_unique<base::DictionaryValue>(),
                      tick_clock()->NowTicks(), 0);
-  cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
-                     kGroup_,
-                     tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+  SetClient();
   ASSERT_EQ(1u, report_count());
   ASSERT_EQ(1u, client_count());
 
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc
index 9fe8335..1425069 100644
--- a/net/reporting/reporting_test_util.cc
+++ b/net/reporting/reporting_test_util.cc
@@ -10,10 +10,12 @@
 
 #include "base/bind.h"
 #include "base/json/json_reader.h"
+#include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/test/simple_test_clock.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/timer/mock_timer.h"
+#include "net/base/rand_callback.h"
 #include "net/reporting/reporting_cache.h"
 #include "net/reporting/reporting_client.h"
 #include "net/reporting/reporting_context.h"
@@ -128,11 +130,15 @@
 TestReportingContext::TestReportingContext(base::Clock* clock,
                                            base::TickClock* tick_clock,
                                            const ReportingPolicy& policy)
-    : ReportingContext(policy,
-                       clock,
-                       tick_clock,
-                       std::make_unique<TestReportingUploader>(),
-                       std::make_unique<TestReportingDelegate>()),
+    : ReportingContext(
+          policy,
+          clock,
+          tick_clock,
+          base::BindRepeating(&TestReportingContext::RandIntCallback,
+                              base::Unretained(this)),
+          std::make_unique<TestReportingUploader>(),
+          std::make_unique<TestReportingDelegate>()),
+      rand_counter_(0),
       delivery_timer_(new base::MockTimer(/* retain_user_task= */ false,
                                           /* is_repeating= */ false)),
       garbage_collection_timer_(
@@ -148,6 +154,11 @@
   garbage_collection_timer_ = nullptr;
 }
 
+int TestReportingContext::RandIntCallback(int min, int max) {
+  DCHECK_LE(min, max);
+  return min + (rand_counter_++ % (max - min + 1));
+}
+
 ReportingTestBase::ReportingTestBase() {
   // For tests, disable jitter.
   ReportingPolicy policy;
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h
index f7b83113..35216c0 100644
--- a/net/reporting/reporting_test_util.h
+++ b/net/reporting/reporting_test_util.h
@@ -121,6 +121,10 @@
   }
 
  private:
+  int RandIntCallback(int min, int max);
+
+  int rand_counter_;
+
   // Owned by the DeliveryAgent and GarbageCollector, respectively, but
   // referenced here to preserve type:
 
diff --git a/net/server/http_server_unittest.cc b/net/server/http_server_unittest.cc
index 9463387..b6a8402 100644
--- a/net/server/http_server_unittest.cc
+++ b/net/server/http_server_unittest.cc
@@ -123,9 +123,9 @@
  private:
   void Write() {
     int result = socket_->Write(
-        write_buffer_.get(),
-        write_buffer_->BytesRemaining(),
-        base::Bind(&TestHttpClient::OnWrite, base::Unretained(this)));
+        write_buffer_.get(), write_buffer_->BytesRemaining(),
+        base::Bind(&TestHttpClient::OnWrite, base::Unretained(this)),
+        TRAFFIC_ANNOTATION_FOR_TESTS);
     if (result != ERR_IO_PENDING)
       OnWrite(result);
   }
@@ -601,12 +601,10 @@
     return read_len;
   }
 
-  // TODO(crbug.com/656607): Remove default value.
   int Write(IOBuffer* buf,
             int buf_len,
             const CompletionCallback& callback,
-            const NetworkTrafficAnnotationTag& traffic_annotation =
-                NO_TRAFFIC_ANNOTATION_BUG_656607) override {
+            const NetworkTrafficAnnotationTag& traffic_annotation) override {
     return ERR_NOT_IMPLEMENTED;
   }
   int SetReceiveBufferSize(int32_t size) override {
diff --git a/net/socket/socket_posix.h b/net/socket/socket_posix.h
index 3e62f27..cdccc8c 100644
--- a/net/socket/socket_posix.h
+++ b/net/socket/socket_posix.h
@@ -76,12 +76,10 @@
   int ReadIfReady(IOBuffer* buf,
                   int buf_len,
                   const CompletionCallback& callback);
-  // TODO(crbug.com/656607): Remove default value.
   int Write(IOBuffer* buf,
             int buf_len,
             const CompletionCallback& callback,
-            const NetworkTrafficAnnotationTag& traffic_annotation =
-                NO_TRAFFIC_ANNOTATION_BUG_656607);
+            const NetworkTrafficAnnotationTag& traffic_annotation);
 
   // Waits for next write event. This is called by TCPSocketPosix for TCP
   // fastopen after sending first data. Returns ERR_IO_PENDING if it starts
diff --git a/net/socket/tcp_client_socket.h b/net/socket/tcp_client_socket.h
index 06327af2..acf20a6d 100644
--- a/net/socket/tcp_client_socket.h
+++ b/net/socket/tcp_client_socket.h
@@ -72,12 +72,10 @@
   int ReadIfReady(IOBuffer* buf,
                   int buf_len,
                   const CompletionCallback& callback) override;
-  // TODO(crbug.com/656607): Remove default value.
   int Write(IOBuffer* buf,
             int buf_len,
             const CompletionCallback& callback,
-            const NetworkTrafficAnnotationTag& traffic_annotation =
-                NO_TRAFFIC_ANNOTATION_BUG_656607) override;
+            const NetworkTrafficAnnotationTag& traffic_annotation) override;
   int SetReceiveBufferSize(int32_t size) override;
   int SetSendBufferSize(int32_t size) override;
 
diff --git a/net/socket/tcp_socket_posix.h b/net/socket/tcp_socket_posix.h
index df1edebf..d5e9885 100644
--- a/net/socket/tcp_socket_posix.h
+++ b/net/socket/tcp_socket_posix.h
@@ -92,12 +92,10 @@
 
   // Writes to the socket.
   // Returns a net error code.
-  // TODO(crbug.com/656607): Remove default value.
   int Write(IOBuffer* buf,
             int buf_len,
             const CompletionCallback& callback,
-            const NetworkTrafficAnnotationTag& traffic_annotation =
-                NO_TRAFFIC_ANNOTATION_BUG_656607);
+            const NetworkTrafficAnnotationTag& traffic_annotation);
 
   // Copies the local tcp address into |address| and returns a net error code.
   int GetLocalAddress(IPEndPoint* address) const;
diff --git a/net/socket/tcp_socket_unittest.cc b/net/socket/tcp_socket_unittest.cc
index e170f3b..80ac0a2e 100644
--- a/net/socket/tcp_socket_unittest.cc
+++ b/net/socket/tcp_socket_unittest.cc
@@ -23,6 +23,7 @@
 #include "net/socket/socket_performance_watcher.h"
 #include "net/socket/tcp_client_socket.h"
 #include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
@@ -168,7 +169,8 @@
 
       TestCompletionCallback write_callback;
       int write_result = accepted_socket->Write(
-          write_buffer.get(), write_buffer->size(), write_callback.callback());
+          write_buffer.get(), write_buffer->size(), write_callback.callback(),
+          TRAFFIC_ANNOTATION_FOR_TESTS);
 
       scoped_refptr<IOBufferWithSize> read_buffer(
           new IOBufferWithSize(message.size()));
@@ -388,7 +390,8 @@
 
     TestCompletionCallback write_callback;
     int write_result = accepted_socket->Write(
-        write_buffer.get(), write_buffer->size(), write_callback.callback());
+        write_buffer.get(), write_buffer->size(), write_callback.callback(),
+        TRAFFIC_ANNOTATION_FOR_TESTS);
     write_result = write_callback.GetResult(write_result);
     ASSERT_TRUE(write_result >= 0);
     bytes_written += write_result;
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc
index 6ee6e5b..50597c7 100644
--- a/net/test/spawned_test_server/base_test_server.cc
+++ b/net/test/spawned_test_server/base_test_server.cc
@@ -269,8 +269,7 @@
 }
 
 const base::DictionaryValue& BaseTestServer::server_data() const {
-  DCHECK(started_);
-  DCHECK(server_data_.get());
+  DCHECK(server_data_);
   return *server_data_;
 }
 
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h
index 377e24f8d..a3592ac4 100644
--- a/net/test/spawned_test_server/base_test_server.h
+++ b/net/test/spawned_test_server/base_test_server.h
@@ -380,6 +380,7 @@
  protected:
   virtual ~BaseTestServer();
   Type type() const { return type_; }
+  const SSLOptions& ssl_options() const { return ssl_options_; }
 
   bool started() const { return started_; }
 
diff --git a/net/test/spawned_test_server/remote_test_server.cc b/net/test/spawned_test_server/remote_test_server.cc
index 6a26cde..8cfe03b2 100644
--- a/net/test/spawned_test_server/remote_test_server.cc
+++ b/net/test/spawned_test_server/remote_test_server.cc
@@ -88,6 +88,20 @@
   // pass right server type to Python test server.
   arguments_dict.SetString("server-type", GetServerTypeString(type()));
 
+  // If the server is not on localhost and it's expected to start OCSP server
+  // then pass OCSP proxy port number, so the server can generate certificates
+  // for the OCSP server valid for the proxied port.
+  bool ocsp_server_enabled =
+      type() == TYPE_HTTPS && (ssl_options().server_certificate ==
+                                   SSLOptions::CERT_AUTO_AIA_INTERMEDIATE ||
+                               !ssl_options().GetOCSPArgument().empty());
+  if (config_.address() != IPAddress::IPv4Localhost() && ocsp_server_enabled) {
+    ocsp_proxy_ =
+        std::make_unique<RemoteTestServerProxy>(io_thread_.task_runner());
+    arguments_dict.SetKey("ocsp-proxy-port-number",
+                          base::Value(ocsp_proxy_->local_port()));
+  }
+
   // Generate JSON-formatted argument string.
   std::string arguments_string;
   base::JSONWriter::Write(arguments_dict, &arguments_string);
@@ -104,24 +118,36 @@
 bool RemoteTestServer::BlockUntilStarted() {
   DCHECK(start_request_);
 
-  std::string server_data;
-  bool request_result = start_request_->WaitForCompletion(&server_data);
+  std::string server_data_json;
+  bool request_result = start_request_->WaitForCompletion(&server_data_json);
   start_request_.reset();
   if (!request_result)
     return false;
 
-  // Parse server_data.
-  if (server_data.empty() ||
-      !SetAndParseServerData(server_data, &remote_port_)) {
-    LOG(ERROR) << "Could not parse server_data: " << server_data;
+  // Parse server_data_json.
+  if (server_data_json.empty() ||
+      !SetAndParseServerData(server_data_json, &remote_port_)) {
+    LOG(ERROR) << "Could not parse server_data: " << server_data_json;
     return false;
   }
 
   // If the server is not on localhost then start a proxy on localhost to
   // forward connections to the server.
   if (config_.address() != IPAddress::IPv4Localhost()) {
-    test_server_proxy_ = std::make_unique<RemoteTestServerProxy>(
-        IPEndPoint(config_.address(), remote_port_), io_thread_.task_runner());
+    test_server_proxy_ =
+        std::make_unique<RemoteTestServerProxy>(io_thread_.task_runner());
+    test_server_proxy_->Start(IPEndPoint(config_.address(), remote_port_));
+
+    if (ocsp_proxy_) {
+      const base::Value* ocsp_port_value = server_data().FindKey("ocsp_port");
+      if (ocsp_port_value && ocsp_port_value->is_int()) {
+        ocsp_proxy_->Start(
+            IPEndPoint(config_.address(), ocsp_port_value->GetInt()));
+      } else {
+        LOG(WARNING) << "testserver.py didn't return ocsp_port.";
+      }
+    }
+
     SetPort(test_server_proxy_->local_port());
   } else {
     SetPort(remote_port_);
diff --git a/net/test/spawned_test_server/remote_test_server.h b/net/test/spawned_test_server/remote_test_server.h
index af75d2f..8a7e430d 100644
--- a/net/test/spawned_test_server/remote_test_server.h
+++ b/net/test/spawned_test_server/remote_test_server.h
@@ -93,6 +93,7 @@
   int remote_port_ = 0;
 
   std::unique_ptr<RemoteTestServerProxy> test_server_proxy_;
+  std::unique_ptr<RemoteTestServerProxy> ocsp_proxy_;
 
   DISALLOW_COPY_AND_ASSIGN(RemoteTestServer);
 };
diff --git a/net/test/spawned_test_server/remote_test_server_proxy.cc b/net/test/spawned_test_server/remote_test_server_proxy.cc
index 70330cb..86278709a 100644
--- a/net/test/spawned_test_server/remote_test_server_proxy.cc
+++ b/net/test/spawned_test_server/remote_test_server_proxy.cc
@@ -197,10 +197,16 @@
 // RemoteTestServerProxy implementation that runs on a background IO thread.
 class RemoteTestServerProxy::Core {
  public:
-  explicit Core(const IPEndPoint& remote_address);
+  Core();
   ~Core();
 
-  void Start(base::WaitableEvent* started_event);
+  // Creates local socket for accepting incoming connections and binds it to a
+  // port. local_port() comes valid after this call is complete.
+  void Initialize(base::WaitableEvent* initialized_event);
+
+  // Starts accepting incoming connections and redirecting them to
+  // remote_address. Must be called only after Initialize().
+  void Start(const IPEndPoint& remote_address);
 
   uint16_t local_port() const { return local_port_; }
 
@@ -222,10 +228,12 @@
   DISALLOW_COPY_AND_ASSIGN(Core);
 };
 
-RemoteTestServerProxy::Core::Core(const IPEndPoint& remote_address)
-    : remote_address_(remote_address) {}
+RemoteTestServerProxy::Core::Core() {}
 
-void RemoteTestServerProxy::Core::Start(base::WaitableEvent* started_event) {
+void RemoteTestServerProxy::Core::Initialize(
+    base::WaitableEvent* initialized_event) {
+  CHECK(!socket_);
+
   socket_ = std::make_unique<TCPServerSocket>(nullptr, net::NetLogSource());
   int result = socket_->Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0), 5);
   CHECK_EQ(result, OK);
@@ -236,9 +244,14 @@
   CHECK_EQ(result, OK);
   local_port_ = address.port();
 
-  DoAcceptLoop();
+  initialized_event->Signal();
+}
 
-  started_event->Signal();
+void RemoteTestServerProxy::Core::Start(const IPEndPoint& remote_address) {
+  CHECK(socket_);
+
+  remote_address_ = remote_address;
+  DoAcceptLoop();
 }
 
 RemoteTestServerProxy::Core::~Core() {}
@@ -294,17 +307,16 @@
 }
 
 RemoteTestServerProxy::RemoteTestServerProxy(
-    const IPEndPoint& remote_address,
     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
-    : io_task_runner_(io_task_runner),
-      core_(std::make_unique<Core>(remote_address)) {
-  base::WaitableEvent started_event(
+    : io_task_runner_(io_task_runner), core_(std::make_unique<Core>()) {
+  base::WaitableEvent intialized_event(
       base::WaitableEvent::ResetPolicy::MANUAL,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
   io_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Core::Start, base::Unretained(core_.get()), &started_event));
-  started_event.Wait();
+      base::BindOnce(&Core::Initialize, base::Unretained(core_.get()),
+                     &intialized_event));
+  intialized_event.Wait();
 
   local_port_ = core_->local_port();
 }
@@ -314,4 +326,10 @@
   io_task_runner_->DeleteSoon(FROM_HERE, core_.release());
 }
 
+void RemoteTestServerProxy::Start(const IPEndPoint& remote_address) {
+  io_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get()),
+                                remote_address));
+}
+
 }  // namespace net
diff --git a/net/test/spawned_test_server/remote_test_server_proxy.h b/net/test/spawned_test_server/remote_test_server_proxy.h
index 538fcea..366e254 100644
--- a/net/test/spawned_test_server/remote_test_server_proxy.h
+++ b/net/test/spawned_test_server/remote_test_server_proxy.h
@@ -24,13 +24,16 @@
 // address.
 class RemoteTestServerProxy {
  public:
-  RemoteTestServerProxy(
-      const IPEndPoint& remote_address,
+  explicit RemoteTestServerProxy(
       scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
   ~RemoteTestServerProxy();
 
   uint16_t local_port() const { return local_port_; }
 
+  // Starts the proxy for the specified |remote_address|. Must be called before
+  // any incoming connection on local_port() are initiated.
+  void Start(const IPEndPoint& remote_address);
+
  private:
   class Core;
 
diff --git a/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc b/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc
index ddb623c..7b3b6b5 100644
--- a/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc
+++ b/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc
@@ -35,10 +35,10 @@
     result = listen_socket_->GetLocalAddress(&address);
     EXPECT_THAT(result, IsOk());
 
-    proxy_ = std::make_unique<RemoteTestServerProxy>(address,
-                                                     io_thread_.task_runner());
+    proxy_ = std::make_unique<RemoteTestServerProxy>(io_thread_.task_runner());
     proxy_address_ =
         IPEndPoint(IPAddress::IPv4Localhost(), proxy_->local_port());
+    proxy_->Start(address);
   }
 
   void MakeConnection(std::unique_ptr<StreamSocket>* client_socket,
diff --git a/net/tools/quic/quic_simple_server.cc b/net/tools/quic/quic_simple_server.cc
index 4ecbf753..8eed295 100644
--- a/net/tools/quic/quic_simple_server.cc
+++ b/net/tools/quic/quic_simple_server.cc
@@ -146,6 +146,9 @@
   // notify clients that they're closing.
   dispatcher_->Shutdown();
 
+  if (!socket_) {
+    return;
+  }
   socket_->Close();
   socket_.reset();
 }
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py
index 23a3f08..634b41e 100755
--- a/net/tools/testserver/testserver.py
+++ b/net/tools/testserver/testserver.py
@@ -1918,11 +1918,16 @@
           print ('AIA server started on %s:%d...' %
               (host, self.__ocsp_server.server_port))
 
+          ocsp_server_port = self.__ocsp_server.server_port
+          if self.options.ocsp_proxy_port_number != 0:
+            ocsp_server_port = self.options.ocsp_proxy_port_number
+            server_data['ocsp_port'] = self.__ocsp_server.server_port
+
           (pem_cert_and_key, intermediate_cert_der) = \
               minica.GenerateCertKeyAndIntermediate(
                   subject = self.options.cert_common_name,
-                  ca_issuers_url = ("http://%s:%d/ca_issuers" %
-                                    (host, self.__ocsp_server.server_port)),
+                  ca_issuers_url =
+                      ("http://%s:%d/ca_issuers" % (host, ocsp_server_port)),
                   serial = self.options.cert_serial)
 
           self.__ocsp_server.ocsp_response = None
@@ -1991,10 +1996,14 @@
             raise testserver_base.OptionError('unknown OCSP produced: ' +
                 self.options.ocsp_produced)
 
+          ocsp_server_port = self.__ocsp_server.server_port
+          if self.options.ocsp_proxy_port_number != 0:
+            ocsp_server_port = self.options.ocsp_proxy_port_number
+            server_data['ocsp_port'] = self.__ocsp_server.server_port
+
           (pem_cert_and_key, ocsp_der) = minica.GenerateCertKeyAndOCSP(
               subject = self.options.cert_common_name,
-              ocsp_url = ("http://%s:%d/ocsp" %
-                  (host, self.__ocsp_server.server_port)),
+              ocsp_url = ("http://%s:%d/ocsp" % (host, ocsp_server_port)),
               ocsp_states = ocsp_states,
               ocsp_dates = ocsp_dates,
               ocsp_produced = ocsp_produced,
@@ -2295,6 +2304,10 @@
                                   help='If set, the OCSP server will return '
                                   'a tryLater status rather than the actual '
                                   'OCSP response.')
+    self.option_parser.add_option('--ocsp-proxy-port-number', default=0,
+                                  type='int', dest='ocsp_proxy_port_number',
+                                  help='Port allocated for OCSP proxy '
+                                  'when connection is proxied.')
     self.option_parser.add_option('--alert-after-handshake',
                                   dest='alert_after_handshake',
                                   default=False, action='store_true',
diff --git a/net/url_request/url_request_quic_unittest.cc b/net/url_request/url_request_quic_unittest.cc
index d2fbf34b..a7456ac 100644
--- a/net/url_request/url_request_quic_unittest.cc
+++ b/net/url_request/url_request_quic_unittest.cc
@@ -37,7 +37,6 @@
 
 // This must match the certificate used (quic_test.example.com.crt and
 // quic_test.example.com.key.pkcs8).
-const int kTestServerPort = 6121;
 const char kTestServerHost[] = "test.example.com";
 // Used as a simple response from the server.
 const char kHelloPath[] = "/hello.txt";
@@ -160,8 +159,8 @@
         test::crypto_test_utils::ProofSourceForTesting(), config,
         net::QuicCryptoServerConfig::ConfigOptions(),
         AllSupportedTransportVersions(), &response_cache_));
-    int rv = server_->Listen(
-        net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kTestServerPort));
+    int rv =
+        server_->Listen(net::IPEndPoint(net::IPAddress::IPv4AllZeros(), 0));
     EXPECT_GE(rv, 0) << "Quic server fails to start";
 
     std::unique_ptr<MockHostResolver> resolver(new MockHostResolver());
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index daf0d40..764451c 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -10489,9 +10489,8 @@
 }
 
 static bool SystemSupportsOCSP() {
-#if defined(OS_ANDROID) || defined(OS_FUCHSIA)
+#if defined(OS_ANDROID)
   // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
-  // TODO(crbug.com/776575): OCSP tests currently fail on Fuchsia.
   return false;
 #else
   return true;
diff --git a/printing/BUILD.gn b/printing/BUILD.gn
index 277f5025..71ea5f6 100644
--- a/printing/BUILD.gn
+++ b/printing/BUILD.gn
@@ -71,8 +71,6 @@
     "printed_document.h",
     "printed_document_mac.cc",
     "printed_document_win.cc",
-    "printed_page.cc",
-    "printed_page.h",
     "printing_context.cc",
     "printing_context.h",
     "printing_export.h",
@@ -132,6 +130,8 @@
       "backend/print_backend_win.cc",
       "backend/win_helper.cc",
       "backend/win_helper.h",
+      "printed_page_win.cc",
+      "printed_page_win.h",
       "printing_context_system_dialog_win.cc",
       "printing_context_system_dialog_win.h",
       "printing_context_win.cc",
@@ -269,7 +269,6 @@
     "page_range_unittest.cc",
     "page_setup_unittest.cc",
     "pdf_metafile_cg_mac_unittest.cc",
-    "printed_page_unittest.cc",
     "printing_context_win_unittest.cc",
     "printing_test.h",
     "printing_utils_unittest.cc",
@@ -291,6 +290,14 @@
     sources += [ "pdf_transform_unittest.cc" ]
   }
 
+  if (is_win || is_mac) {
+    sources += [ "printed_document_unittest.cc" ]
+  }
+
+  if (is_win) {
+    sources += [ "printed_page_win_unittest.cc" ]
+  }
+
   if (use_cups) {
     configs += [ ":cups" ]
 
diff --git a/printing/printed_document.cc b/printing/printed_document.cc
index b4f6f9d..ad6c48b0 100644
--- a/printing/printed_document.cc
+++ b/printing/printed_document.cc
@@ -27,13 +27,17 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "printing/metafile.h"
 #include "printing/page_number.h"
 #include "printing/print_settings_conversion.h"
-#include "printing/printed_page.h"
 #include "printing/units.h"
 #include "ui/gfx/font.h"
 #include "ui/gfx/text_elider.h"
 
+#if defined(OS_WIN)
+#include "printing/printed_page_win.h"
+#endif
+
 namespace printing {
 
 namespace {
@@ -41,19 +45,15 @@
 base::LazyInstance<base::FilePath>::Leaky g_debug_dump_info =
     LAZY_INSTANCE_INITIALIZER;
 
+#if defined(OS_WIN)
 void DebugDumpPageTask(const base::string16& doc_name,
                        const PrintedPage* page) {
   base::AssertBlockingAllowed();
 
-  if (g_debug_dump_info.Get().empty())
-    return;
+  DCHECK(!g_debug_dump_info.Get().empty());
 
   static constexpr base::FilePath::CharType kExtension[] =
-#if defined(OS_WIN)
       FILE_PATH_LITERAL(".emf");
-#else
-      FILE_PATH_LITERAL(".pdf");
-#endif
 
   base::string16 name = doc_name;
   name += base::ASCIIToUTF16(base::StringPrintf("_%04d", page->page_number()));
@@ -62,6 +62,23 @@
                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
   page->metafile()->SaveTo(&file);
 }
+#else
+void DebugDumpTask(const base::string16& doc_name,
+                   const MetafilePlayer* metafile) {
+  base::AssertBlockingAllowed();
+
+  DCHECK(!g_debug_dump_info.Get().empty());
+
+  static constexpr base::FilePath::CharType kExtension[] =
+      FILE_PATH_LITERAL(".pdf");
+
+  base::string16 name = doc_name;
+  base::FilePath path = PrintedDocument::CreateDebugDumpPath(name, kExtension);
+  base::File file(path,
+                  base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+  metafile->SaveTo(&file);
+}
+#endif
 
 void DebugDumpDataTask(const base::string16& doc_name,
                        const base::FilePath::StringType& extension,
@@ -113,27 +130,20 @@
 
 PrintedDocument::~PrintedDocument() = default;
 
+#if defined(OS_WIN)
 void PrintedDocument::SetPage(int page_number,
                               std::unique_ptr<MetafilePlayer> metafile,
-#if defined(OS_WIN)
                               float shrink,
-#endif
-                              const gfx::Size& paper_size,
-                              const gfx::Rect& page_rect) {
+                              const gfx::Size& page_size,
+                              const gfx::Rect& page_content_rect) {
   // Notice the page_number + 1, the reason is that this is the value that will
   // be shown. Users dislike 0-based counting.
   auto page = base::MakeRefCounted<PrintedPage>(
-      page_number + 1, std::move(metafile), paper_size, page_rect);
-#if defined(OS_WIN)
+      page_number + 1, std::move(metafile), page_size, page_content_rect);
   page->set_shrink_factor(shrink);
-#endif
   {
     base::AutoLock lock(lock_);
     mutable_.pages_[page_number] = page;
-
-#if defined(OS_POSIX)
-    mutable_.first_page = std::min(mutable_.first_page, page_number);
-#endif
   }
 
   if (!g_debug_dump_info.Get().empty()) {
@@ -154,27 +164,52 @@
   return page;
 }
 
+#else
+void PrintedDocument::SetDocument(std::unique_ptr<MetafilePlayer> metafile,
+                                  const gfx::Size& page_size,
+                                  const gfx::Rect& page_content_rect) {
+  {
+    base::AutoLock lock(lock_);
+    mutable_.metafile_ = std::move(metafile);
+#if defined(OS_MACOSX)
+    mutable_.page_size_ = page_size;
+    mutable_.page_content_rect_ = page_content_rect;
+#endif
+  }
+
+  if (!g_debug_dump_info.Get().empty()) {
+    base::PostTaskWithTraits(
+        FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()},
+        base::BindOnce(&DebugDumpTask, name(), mutable_.metafile_.get()));
+  }
+}
+
+const MetafilePlayer* PrintedDocument::GetMetafile() {
+  return mutable_.metafile_.get();
+}
+
+#endif
+
 bool PrintedDocument::IsComplete() const {
   base::AutoLock lock(lock_);
   if (!mutable_.page_count_)
     return false;
+#if defined(OS_WIN)
   PageNumber page(immutable_.settings_, mutable_.page_count_);
   if (page == PageNumber::npos())
     return false;
 
   for (; page != PageNumber::npos(); ++page) {
-#if defined(OS_WIN)
-    const bool metafile_must_be_valid = true;
-#elif defined(OS_POSIX)
-    const bool metafile_must_be_valid = (page.ToInt() == mutable_.first_page);
-#endif
     PrintedPages::const_iterator it = mutable_.pages_.find(page.ToInt());
-    if (it == mutable_.pages_.end() || !it->second.get())
+    if (it == mutable_.pages_.end() || !it->second.get() ||
+        !it->second->metafile()) {
       return false;
-    if (metafile_must_be_valid && !it->second->metafile())
-      return false;
+    }
   }
   return true;
+#else
+  return !!mutable_.metafile_;
+#endif
 }
 
 void PrintedDocument::set_page_count(int max_page) {
@@ -208,8 +243,8 @@
 base::FilePath PrintedDocument::CreateDebugDumpPath(
     const base::string16& document_name,
     const base::FilePath::StringType& extension) {
-  if (g_debug_dump_info.Get().empty())
-    return base::FilePath();
+  DCHECK(!g_debug_dump_info.Get().empty());
+
   // Create a filename.
   base::string16 filename;
   base::Time now(base::Time::Now());
@@ -238,6 +273,24 @@
                                           base::RetainedRef(data)));
 }
 
+#if defined(OS_WIN) || defined(OS_MACOSX)
+gfx::Rect PrintedDocument::GetCenteredPageContentRect(
+    const gfx::Size& paper_size,
+    const gfx::Size& page_size,
+    const gfx::Rect& page_content_rect) const {
+  gfx::Rect content_rect = page_content_rect;
+  if (paper_size.width() > page_size.width()) {
+    int diff = paper_size.width() - page_size.width();
+    content_rect.set_x(content_rect.x() + diff / 2);
+  }
+  if (paper_size.height() > page_size.height()) {
+    int diff = paper_size.height() - page_size.height();
+    content_rect.set_y(content_rect.y() + diff / 2);
+  }
+  return content_rect;
+}
+#endif
+
 PrintedDocument::Mutable::Mutable() = default;
 
 PrintedDocument::Mutable::~Mutable() = default;
@@ -251,9 +304,9 @@
 
 #if defined(OS_ANDROID)
 // This function is not used on android.
-void PrintedDocument::RenderPrintedPage(const PrintedPage& page,
-                                        PrintingContext* context) const {
+bool PrintedDocument::RenderPrintedDocument(PrintingContext* context) {
   NOTREACHED();
+  return false;
 }
 #endif
 
diff --git a/printing/printed_document.h b/printing/printed_document.h
index 3ccfb064..e9ccdee 100644
--- a/printing/printed_document.h
+++ b/printing/printed_document.h
@@ -42,29 +42,38 @@
                   const base::string16& name,
                   int cookie);
 
-  // Sets a page's data. 0-based. Takes metafile ownership.
-  // Note: locks for a short amount of time.
+#if defined(OS_WIN)
+  // Sets a page's data. 0-based. Note: locks for a short amount of time.
   void SetPage(int page_number,
                std::unique_ptr<MetafilePlayer> metafile,
-#if defined(OS_WIN)
                float shrink,
-#endif
-               const gfx::Size& paper_size,
-               const gfx::Rect& page_rect);
+               const gfx::Size& page_size,
+               const gfx::Rect& page_content_rect);
 
   // Retrieves a page. If the page is not available right now, it
   // requests to have this page be rendered and returns NULL.
   // Note: locks for a short amount of time.
   scoped_refptr<PrintedPage> GetPage(int page_number);
+#else
+  // Sets the document data. Note: locks for a short amount of time.
+  void SetDocument(std::unique_ptr<MetafilePlayer> metafile,
+                   const gfx::Size& page_size,
+                   const gfx::Rect& page_content_rect);
 
-  // Draws the page in the context.
-  // Note: locks for a short amount of time in debug only.
-#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(USE_AURA))
+  // Retrieves the metafile with the data to print. Lock must be held when
+  // calling this function
+  const MetafilePlayer* GetMetafile();
+#endif
+
+// Draws the page in the context.
+// Note: locks for a short amount of time in debug only.
+#if defined(OS_WIN)
   void RenderPrintedPage(const PrintedPage& page,
                          printing::NativeDrawingContext context) const;
 #elif defined(OS_POSIX)
-  void RenderPrintedPage(const PrintedPage& page,
-                         PrintingContext* context) const;
+  // Draws the document in the context. Returns true on success and false on
+  // failure. Fails if context->NewPage() or context->PageDone() fails.
+  bool RenderPrintedDocument(PrintingContext* context);
 #endif
 
   // Returns true if all the necessary pages for the settings are already
@@ -107,6 +116,14 @@
   void DebugDumpData(const base::RefCountedMemory* data,
                      const base::FilePath::StringType& extension);
 
+#if defined(OS_WIN) || defined(OS_MACOSX)
+  // Get page content rect adjusted based on
+  // http://dev.w3.org/csswg/css3-page/#positioning-page-box
+  gfx::Rect GetCenteredPageContentRect(const gfx::Size& paper_size,
+                                       const gfx::Size& page_size,
+                                       const gfx::Rect& content_rect) const;
+#endif
+
  private:
   friend class base::RefCountedThreadSafe<PrintedDocument>;
 
@@ -121,10 +138,6 @@
     Mutable();
     ~Mutable();
 
-    // Contains the pages' representation. This is a collection of PrintedPage.
-    // Warning: Lock must be held when accessing this member.
-    PrintedPages pages_;
-
     // Number of expected pages to be rendered.
     // Warning: Lock must be held when accessing this member.
     int expected_page_count_ = 0;
@@ -132,9 +145,16 @@
     // The total number of pages in the document.
     int page_count_ = 0;
 
-#if defined(OS_POSIX)
-    // Page number of the first page.
-    int first_page = INT_MAX;
+#if defined(OS_WIN)
+    // Contains the pages' representation. This is a collection of PrintedPage.
+    // Warning: Lock must be held when accessing this member.
+    PrintedPages pages_;
+#else
+    std::unique_ptr<MetafilePlayer> metafile_;
+#endif
+#if defined(OS_MACOSX)
+    gfx::Size page_size_;
+    gfx::Rect page_content_rect_;
 #endif
   };
 
diff --git a/printing/printed_document_chromeos.cc b/printing/printed_document_chromeos.cc
index aac115f..224acd89 100644
--- a/printing/printed_document_chromeos.cc
+++ b/printing/printed_document_chromeos.cc
@@ -5,42 +5,35 @@
 #include "printing/printed_document.h"
 
 #include "base/logging.h"
-#include "printing/page_number.h"
-#include "printing/printed_page.h"
 
 #if defined(USE_CUPS)
+#include "printing/metafile.h"
 #include "printing/printing_context_chromeos.h"
 #endif
 
 namespace printing {
 
-void PrintedDocument::RenderPrintedPage(const PrintedPage& page,
-                                        PrintingContext* context) const {
+bool PrintedDocument::RenderPrintedDocument(PrintingContext* context) {
 #if defined(USE_CUPS)
-#if defined(NDEBUG)
-  {
-    // Make sure the page is from our list.
-    base::AutoLock lock(lock_);
-    DCHECK(&page == mutable_.pages_.find(page.page_number() - 1)->second.get());
-  }
-#endif  // defined(NDEBUG)
-
   DCHECK(context);
 
+  if (context->NewPage() != PrintingContext::OK)
+    return false;
   {
     base::AutoLock lock(lock_);
-    if (page.page_number() - 1 == mutable_.first_page) {
-      std::vector<char> buffer;
-
-      if (page.metafile()->GetDataAsVector(&buffer)) {
-        static_cast<PrintingContextChromeos*>(context)->StreamData(buffer);
-      } else {
-        LOG(WARNING) << "Failed to read data from metafile";
-      }
+    std::vector<char> buffer;
+    const MetafilePlayer* metafile = GetMetafile();
+    DCHECK(metafile);
+    if (metafile->GetDataAsVector(&buffer)) {
+      static_cast<PrintingContextChromeos*>(context)->StreamData(buffer);
+    } else {
+      LOG(WARNING) << "Failed to read data from metafile";
     }
   }
+  return context->PageDone() == PrintingContext::OK;
 #else
   NOTREACHED();
+  return false;
 #endif  // defined(USE_CUPS)
 }
 
diff --git a/printing/printed_document_linux.cc b/printing/printed_document_linux.cc
index 2beec84b9..87bc30e7 100644
--- a/printing/printed_document_linux.cc
+++ b/printing/printed_document_linux.cc
@@ -6,8 +6,6 @@
 
 #include "base/logging.h"
 #include "build/build_config.h"
-#include "printing/page_number.h"
-#include "printing/printed_page.h"
 #include "printing/printing_context_linux.h"
 
 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
@@ -16,25 +14,18 @@
 
 namespace printing {
 
-void PrintedDocument::RenderPrintedPage(
-    const PrintedPage& page, PrintingContext* context) const {
-#ifndef NDEBUG
-  {
-    // Make sure the page is from our list.
-    base::AutoLock lock(lock_);
-    DCHECK(&page == mutable_.pages_.find(page.page_number() - 1)->second.get());
-  }
-#endif
-
+bool PrintedDocument::RenderPrintedDocument(PrintingContext* context) {
   DCHECK(context);
 
+  if (context->NewPage() != PrintingContext::OK)
+    return false;
   {
     base::AutoLock lock(lock_);
-    if (page.page_number() - 1 == mutable_.first_page) {
-      static_cast<PrintingContextLinux*>(context)
-          ->PrintDocument(*page.metafile());
-    }
+    const MetafilePlayer* metafile = GetMetafile();
+    DCHECK(metafile);
+    static_cast<PrintingContextLinux*>(context)->PrintDocument(*metafile);
   }
+  return context->PageDone() == PrintingContext::OK;
 }
 
 }  // namespace printing
diff --git a/printing/printed_document_mac.cc b/printing/printed_document_mac.cc
index 3224d12..1cfa1ee 100644
--- a/printing/printed_document_mac.cc
+++ b/printing/printed_document_mac.cc
@@ -8,55 +8,42 @@
 #import <CoreFoundation/CoreFoundation.h>
 
 #include "base/logging.h"
-#include "printing/page_number.h"
-#include "printing/printed_page.h"
+#include "printing/metafile.h"
+#include "printing/printing_context.h"
 
 namespace printing {
 
-void PrintedDocument::RenderPrintedPage(
-    const PrintedPage& page,
-    printing::NativeDrawingContext context) const {
+bool PrintedDocument::RenderPrintedDocument(PrintingContext* context) {
   DCHECK(context);
 
-  // |mutable_.pages_| is 0-based, whereas the page number is 1-based.
-  const int page_index = page.page_number() - 1;
-
   const MetafilePlayer* metafile;
-  size_t metafile_page_number;
+  gfx::Size page_size;
+  gfx::Rect page_content_rect;
   {
     base::AutoLock lock(lock_);
-
-    // Make sure |page| is from our list.
-    DCHECK(&page == mutable_.pages_.find(page_index)->second.get());
-
-    // Make sure the first page exists in the list too.
-    DCHECK_GE(mutable_.first_page, 0);
-    DCHECK_NE(mutable_.first_page, INT_MAX);
-    DCHECK(mutable_.pages_.find(mutable_.first_page)->second.get());
-
-    // Always use the metafile from the first page.
-    metafile = mutable_.pages_.find(mutable_.first_page)->second->metafile();
-
-    // Figure out the mapping from |page| to the page inside |metafile|.
-    // e.g. If |metafile| contains 3 pages that corresponds to pages 1, 5, 7,
-    // then page 5 has index 1, which is page number 2.
-    // Use 1-based page number here because that is what RenderPage() takes.
-    metafile_page_number = 1;
-    for (const auto& it : mutable_.pages_) {
-      if (it.first == page_index)
-        break;
-      ++metafile_page_number;
-    }
+    metafile = GetMetafile();
+    page_size = mutable_.page_size_;
+    page_content_rect = mutable_.page_content_rect_;
   }
 
+  DCHECK(metafile);
   const PageSetup& page_setup = immutable_.settings_.page_setup_device_units();
-  gfx::Rect content_area =
-      page.GetCenteredPageContentRect(page_setup.physical_size());
+  gfx::Rect content_area = GetCenteredPageContentRect(
+      page_setup.physical_size(), page_size, page_content_rect);
 
   struct Metafile::MacRenderPageParams params;
   params.autorotate = true;
-  metafile->RenderPage(metafile_page_number, context, content_area.ToCGRect(),
-                       params);
+  size_t num_pages = expected_page_count();
+  for (size_t metafile_page_number = 1; metafile_page_number <= num_pages;
+       metafile_page_number++) {
+    if (context->NewPage() != PrintingContext::OK)
+      return false;
+    metafile->RenderPage(metafile_page_number, context->context(),
+                         content_area.ToCGRect(), params);
+    if (context->PageDone() != PrintingContext::OK)
+      return false;
+  }
+  return true;
 }
 
 }  // namespace printing
diff --git a/printing/printed_document_unittest.cc b/printing/printed_document_unittest.cc
new file mode 100644
index 0000000..efb2aa8
--- /dev/null
+++ b/printing/printed_document_unittest.cc
@@ -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.
+
+#include "printing/printed_document.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace printing {
+
+TEST(PrintedDocumentTest, GetCenteredPageContentRect) {
+  scoped_refptr<PrintedDocument> document;
+  PrintSettings settings;
+  gfx::Rect page_content;
+  const base::string16 name(base::ASCIIToUTF16("name"));
+
+  // No centering.
+  document = base::MakeRefCounted<PrintedDocument>(settings, name, 1);
+  gfx::Size page_size = gfx::Size(1200, 1200);
+  gfx::Rect page_content_rect = gfx::Rect(0, 0, 400, 1100);
+  page_content = document->GetCenteredPageContentRect(
+      gfx::Size(1000, 1000), page_size, page_content_rect);
+  EXPECT_EQ(0, page_content.x());
+  EXPECT_EQ(0, page_content.y());
+  EXPECT_EQ(400, page_content.width());
+  EXPECT_EQ(1100, page_content.height());
+
+  // X centered.
+  document = base::MakeRefCounted<PrintedDocument>(settings, name, 1);
+  page_size = gfx::Size(500, 1200);
+  page_content = document->GetCenteredPageContentRect(
+      gfx::Size(1000, 1000), page_size, page_content_rect);
+  EXPECT_EQ(250, page_content.x());
+  EXPECT_EQ(0, page_content.y());
+  EXPECT_EQ(400, page_content.width());
+  EXPECT_EQ(1100, page_content.height());
+
+  // Y centered.
+  document = base::MakeRefCounted<PrintedDocument>(settings, name, 1);
+  page_size = gfx::Size(1200, 500);
+  page_content = document->GetCenteredPageContentRect(
+      gfx::Size(1000, 1000), page_size, page_content_rect);
+  EXPECT_EQ(0, page_content.x());
+  EXPECT_EQ(250, page_content.y());
+  EXPECT_EQ(400, page_content.width());
+  EXPECT_EQ(1100, page_content.height());
+
+  // Both X and Y centered.
+  document = base::MakeRefCounted<PrintedDocument>(settings, name, 1);
+  page_size = gfx::Size(500, 500),
+  page_content = document->GetCenteredPageContentRect(
+      gfx::Size(1000, 1000), page_size, page_content_rect);
+  EXPECT_EQ(250, page_content.x());
+  EXPECT_EQ(250, page_content.y());
+  EXPECT_EQ(400, page_content.width());
+  EXPECT_EQ(1100, page_content.height());
+}
+
+}  // namespace printing
diff --git a/printing/printed_document_win.cc b/printing/printed_document_win.cc
index 3913a380..19bfb45 100644
--- a/printing/printed_document_win.cc
+++ b/printing/printed_document_win.cc
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #include "printing/page_number.h"
-#include "printing/printed_page.h"
+#include "printing/printed_page_win.h"
 #include "printing/units.h"
 #include "skia/ext/skia_utils_win.h"
 
@@ -42,8 +42,8 @@
   DCHECK(context);
 
   const PageSetup& page_setup = immutable_.settings_.page_setup_device_units();
-  gfx::Rect content_area =
-      page.GetCenteredPageContentRect(page_setup.physical_size());
+  gfx::Rect content_area = GetCenteredPageContentRect(
+      page_setup.physical_size(), page.page_size(), page.page_content_rect());
 
   // Save the state to make sure the context this function call does not modify
   // the device context.
diff --git a/printing/printed_page.cc b/printing/printed_page.cc
deleted file mode 100644
index c2d2c1d86..0000000
--- a/printing/printed_page.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2011 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 "printing/printed_page.h"
-
-#include <utility>
-
-namespace printing {
-
-PrintedPage::PrintedPage(int page_number,
-                         std::unique_ptr<MetafilePlayer> metafile,
-                         const gfx::Size& page_size,
-                         const gfx::Rect& page_content_rect)
-    : page_number_(page_number),
-      metafile_(std::move(metafile)),
-#if defined(OS_WIN)
-      shrink_factor_(0.0f),
-#endif  // OS_WIN
-      page_size_(page_size),
-      page_content_rect_(page_content_rect) {
-}
-
-PrintedPage::~PrintedPage() = default;
-
-const MetafilePlayer* PrintedPage::metafile() const {
-  return metafile_.get();
-}
-
-gfx::Rect PrintedPage::GetCenteredPageContentRect(
-    const gfx::Size& paper_size) const {
-  gfx::Rect content_rect = page_content_rect();
-  if (paper_size.width() > page_size().width()) {
-    int diff = paper_size.width() - page_size().width();
-    content_rect.set_x(content_rect.x() + diff / 2);
-  }
-  if (paper_size.height() > page_size().height()) {
-    int diff = paper_size.height() - page_size().height();
-    content_rect.set_y(content_rect.y() + diff / 2);
-  }
-  return content_rect;
-}
-
-}  // namespace printing
diff --git a/printing/printed_page_unittest.cc b/printing/printed_page_unittest.cc
deleted file mode 100644
index 62b7f00..0000000
--- a/printing/printed_page_unittest.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2011 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 "printing/printed_page.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace printing {
-
-TEST(PrintedPageTest, GetCenteredPageContentRect) {
-  scoped_refptr<PrintedPage> page;
-  gfx::Rect page_content;
-
-  // No centering.
-  page = base::MakeRefCounted<PrintedPage>(1, std::unique_ptr<MetafilePlayer>(),
-                                           gfx::Size(1200, 1200),
-                                           gfx::Rect(0, 0, 400, 1100));
-  page_content = page->GetCenteredPageContentRect(gfx::Size(1000, 1000));
-  EXPECT_EQ(0, page_content.x());
-  EXPECT_EQ(0, page_content.y());
-  EXPECT_EQ(400, page_content.width());
-  EXPECT_EQ(1100, page_content.height());
-
-  // X centered.
-  page = base::MakeRefCounted<PrintedPage>(1, std::unique_ptr<MetafilePlayer>(),
-                                           gfx::Size(500, 1200),
-                                           gfx::Rect(0, 0, 400, 1100));
-  page_content = page->GetCenteredPageContentRect(gfx::Size(1000, 1000));
-  EXPECT_EQ(250, page_content.x());
-  EXPECT_EQ(0, page_content.y());
-  EXPECT_EQ(400, page_content.width());
-  EXPECT_EQ(1100, page_content.height());
-
-  // Y centered.
-  page = base::MakeRefCounted<PrintedPage>(1, std::unique_ptr<MetafilePlayer>(),
-                                           gfx::Size(1200, 500),
-                                           gfx::Rect(0, 0, 400, 1100));
-  page_content = page->GetCenteredPageContentRect(gfx::Size(1000, 1000));
-  EXPECT_EQ(0, page_content.x());
-  EXPECT_EQ(250, page_content.y());
-  EXPECT_EQ(400, page_content.width());
-  EXPECT_EQ(1100, page_content.height());
-
-  // Both X and Y centered.
-  page = base::MakeRefCounted<PrintedPage>(1, std::unique_ptr<MetafilePlayer>(),
-                                           gfx::Size(500, 500),
-                                           gfx::Rect(0, 0, 400, 1100));
-  page_content = page->GetCenteredPageContentRect(gfx::Size(1000, 1000));
-  EXPECT_EQ(250, page_content.x());
-  EXPECT_EQ(250, page_content.y());
-  EXPECT_EQ(400, page_content.width());
-  EXPECT_EQ(1100, page_content.height());
-}
-
-#if defined(OS_WIN)
-TEST(PrintedPageTest, Shrink) {
-  scoped_refptr<PrintedPage> page = base::MakeRefCounted<PrintedPage>(
-      1, std::unique_ptr<MetafilePlayer>(), gfx::Size(1200, 1200),
-      gfx::Rect(0, 0, 400, 1100));
-  EXPECT_EQ(0.0f, page->shrink_factor());
-  page->set_shrink_factor(0.2f);
-  EXPECT_EQ(0.2f, page->shrink_factor());
-  page->set_shrink_factor(0.7f);
-  EXPECT_EQ(0.7f, page->shrink_factor());
-}
-#endif
-
-}  // namespace printing
diff --git a/printing/printed_page_win.cc b/printing/printed_page_win.cc
new file mode 100644
index 0000000..b9df411
--- /dev/null
+++ b/printing/printed_page_win.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2011 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 "printing/printed_page_win.h"
+
+#include <utility>
+
+namespace printing {
+
+PrintedPage::PrintedPage(int page_number,
+                         std::unique_ptr<MetafilePlayer> metafile,
+                         const gfx::Size& page_size,
+                         const gfx::Rect& page_content_rect)
+    : page_number_(page_number),
+      metafile_(std::move(metafile)),
+      shrink_factor_(0.0f),
+      page_size_(page_size),
+      page_content_rect_(page_content_rect) {}
+
+PrintedPage::~PrintedPage() = default;
+
+const MetafilePlayer* PrintedPage::metafile() const {
+  return metafile_.get();
+}
+}  // namespace printing
diff --git a/printing/printed_page.h b/printing/printed_page_win.h
similarity index 84%
rename from printing/printed_page.h
rename to printing/printed_page_win.h
index 3aa6753..6a69de2cc 100644
--- a/printing/printed_page.h
+++ b/printing/printed_page_win.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef PRINTING_PRINTED_PAGE_H_
-#define PRINTING_PRINTED_PAGE_H_
+#ifndef PRINTING_PRINTED_PAGE_WIN_H_
+#define PRINTING_PRINTED_PAGE_WIN_H_
 
 #include <memory>
 
@@ -34,16 +34,10 @@
   const MetafilePlayer* metafile() const;
   const gfx::Size& page_size() const { return page_size_; }
   const gfx::Rect& page_content_rect() const { return page_content_rect_; }
-#if defined(OS_WIN)
   void set_shrink_factor(float shrink_factor) {
     shrink_factor_ = shrink_factor;
   }
   float shrink_factor() const { return shrink_factor_; }
-#endif  // OS_WIN
-
-  // Get page content rect adjusted based on
-  // http://dev.w3.org/csswg/css3-page/#positioning-page-box
-  gfx::Rect GetCenteredPageContentRect(const gfx::Size& paper_size) const;
 
  private:
   friend class base::RefCountedThreadSafe<PrintedPage>;
@@ -56,10 +50,8 @@
   // Actual paint data.
   const std::unique_ptr<MetafilePlayer> metafile_;
 
-#if defined(OS_WIN)
   // Shrink done in comparison to desired_dpi.
   float shrink_factor_;
-#endif  // OS_WIN
 
   // The physical page size. To support multiple page formats inside on print
   // job.
@@ -73,4 +65,4 @@
 
 }  // namespace printing
 
-#endif  // PRINTING_PRINTED_PAGE_H_
+#endif  // PRINTING_PRINTED_PAGE_WIN_H_
diff --git a/printing/printed_page_win_unittest.cc b/printing/printed_page_win_unittest.cc
new file mode 100644
index 0000000..18b7e5a7
--- /dev/null
+++ b/printing/printed_page_win_unittest.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2011 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 "printing/printed_page_win.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace printing {
+
+TEST(PrintedPageTest, Shrink) {
+  scoped_refptr<PrintedPage> page = base::MakeRefCounted<PrintedPage>(
+      1, std::unique_ptr<MetafilePlayer>(), gfx::Size(1200, 1200),
+      gfx::Rect(0, 0, 400, 1100));
+  EXPECT_EQ(0.0f, page->shrink_factor());
+  page->set_shrink_factor(0.2f);
+  EXPECT_EQ(0.2f, page->shrink_factor());
+  page->set_shrink_factor(0.7f);
+  EXPECT_EQ(0.7f, page->shrink_factor());
+}
+
+}  // namespace printing
diff --git a/remoting/OWNERS b/remoting/OWNERS
index f4fb014..7046356 100644
--- a/remoting/OWNERS
+++ b/remoting/OWNERS
@@ -1,7 +1,6 @@
 garykac@chromium.org
 jamiewalch@chromium.org
 joedow@chromium.org
-kelvinp@chromium.org
 lambroslambrou@chromium.org
 nicholss@chromium.org
 sergeyu@chromium.org
diff --git a/remoting/android/OWNERS b/remoting/android/OWNERS
index 11324d06..20fe279 100644
--- a/remoting/android/OWNERS
+++ b/remoting/android/OWNERS
@@ -1,7 +1,6 @@
 # If you modify this, please also update
 # remoting/client/jni/OWNERS
 joedow@chromium.org
-kelvinp@chromium.org
 lambroslambrou@chromium.org
 sergeyu@chromium.org
 yuweih@chromium.org
diff --git a/remoting/client/jni/OWNERS b/remoting/client/jni/OWNERS
index 3871f4b5..994f4fbd 100644
--- a/remoting/client/jni/OWNERS
+++ b/remoting/client/jni/OWNERS
@@ -1,7 +1,6 @@
 # If you modify this, please also update
 # remoting/android/OWNERS
 joedow@chromium.org
-kelvinp@chromium.org
 lambroslambrou@chromium.org
 sergeyu@chromium.org
 yuweih@chromium.org
diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn
index 7b04a1f3..9d4726f 100644
--- a/sandbox/linux/BUILD.gn
+++ b/sandbox/linux/BUILD.gn
@@ -364,8 +364,8 @@
     "syscall_broker/broker_file_permission.h",
     "syscall_broker/broker_host.cc",
     "syscall_broker/broker_host.h",
-    "syscall_broker/broker_policy.cc",
-    "syscall_broker/broker_policy.h",
+    "syscall_broker/broker_permission_list.cc",
+    "syscall_broker/broker_permission_list.h",
     "syscall_broker/broker_process.cc",
     "syscall_broker/broker_process.h",
   ]
@@ -413,8 +413,8 @@
       "syscall_broker/broker_file_permission.h",
       "syscall_broker/broker_host.cc",
       "syscall_broker/broker_host.h",
-      "syscall_broker/broker_policy.cc",
-      "syscall_broker/broker_policy.h",
+      "syscall_broker/broker_permission_list.cc",
+      "syscall_broker/broker_permission_list.h",
       "syscall_broker/broker_process.cc",
       "syscall_broker/broker_process.h",
     ]
diff --git a/sandbox/linux/syscall_broker/broker_client.cc b/sandbox/linux/syscall_broker/broker_client.cc
index 39848caa..5110f2ae 100644
--- a/sandbox/linux/syscall_broker/broker_client.cc
+++ b/sandbox/linux/syscall_broker/broker_client.cc
@@ -18,7 +18,7 @@
 #include "build/build_config.h"
 #include "sandbox/linux/syscall_broker/broker_channel.h"
 #include "sandbox/linux/syscall_broker/broker_command.h"
-#include "sandbox/linux/syscall_broker/broker_policy.h"
+#include "sandbox/linux/syscall_broker/broker_permission_list.h"
 
 #if defined(OS_ANDROID) && !defined(MSG_CMSG_CLOEXEC)
 #define MSG_CMSG_CLOEXEC 0x40000000
@@ -27,12 +27,12 @@
 namespace sandbox {
 namespace syscall_broker {
 
-BrokerClient::BrokerClient(const BrokerPolicy& broker_policy,
+BrokerClient::BrokerClient(const BrokerPermissionList& broker_permission_list,
                            BrokerChannel::EndPoint ipc_channel,
                            const BrokerCommandSet& allowed_command_set,
                            bool fast_check_in_client,
                            bool quiet_failures_for_tests)
-    : broker_policy_(broker_policy),
+    : broker_permission_list_(broker_permission_list),
       ipc_channel_(std::move(ipc_channel)),
       allowed_command_set_(allowed_command_set),
       fast_check_in_client_(fast_check_in_client),
@@ -58,9 +58,9 @@
 
 int BrokerClient::Rename(const char* oldpath, const char* newpath) {
   if (fast_check_in_client_ &&
-      !CommandRenameIsSafe(allowed_command_set_, broker_policy_, oldpath,
-                           newpath, nullptr, nullptr)) {
-    return -broker_policy_.denied_errno();
+      !CommandRenameIsSafe(allowed_command_set_, broker_permission_list_,
+                           oldpath, newpath, nullptr, nullptr)) {
+    return -broker_permission_list_.denied_errno();
   }
 
   base::Pickle write_pickle;
@@ -92,9 +92,9 @@
 
 int BrokerClient::Readlink(const char* path, char* buf, size_t bufsize) {
   if (fast_check_in_client_ &&
-      !CommandReadlinkIsSafe(allowed_command_set_, broker_policy_, path,
-                             nullptr)) {
-    return -broker_policy_.denied_errno();
+      !CommandReadlinkIsSafe(allowed_command_set_, broker_permission_list_,
+                             path, nullptr)) {
+    return -broker_permission_list_.denied_errno();
   }
 
   base::Pickle write_pickle;
@@ -161,15 +161,15 @@
   // IPC.
   if (fast_check_in_client_) {
     if (syscall_type == COMMAND_OPEN &&
-        !CommandOpenIsSafe(allowed_command_set_, broker_policy_, pathname,
-                           flags, NULL /* file_to_open */,
+        !CommandOpenIsSafe(allowed_command_set_, broker_permission_list_,
+                           pathname, flags, NULL /* file_to_open */,
                            NULL /* unlink_after_open */)) {
-      return -broker_policy_.denied_errno();
+      return -broker_permission_list_.denied_errno();
     }
     if (syscall_type == COMMAND_ACCESS &&
-        !CommandAccessIsSafe(allowed_command_set_, broker_policy_, pathname,
-                             flags, NULL)) {
-      return -broker_policy_.denied_errno();
+        !CommandAccessIsSafe(allowed_command_set_, broker_permission_list_,
+                             pathname, flags, NULL)) {
+      return -broker_permission_list_.denied_errno();
     }
   }
 
@@ -231,9 +231,9 @@
                                     void* result_ptr,
                                     size_t expected_result_size) const {
   if (fast_check_in_client_ &&
-      !CommandStatIsSafe(allowed_command_set_, broker_policy_, pathname,
-                         nullptr)) {
-    return -broker_policy_.denied_errno();
+      !CommandStatIsSafe(allowed_command_set_, broker_permission_list_,
+                         pathname, nullptr)) {
+    return -broker_permission_list_.denied_errno();
   }
 
   base::Pickle write_pickle;
diff --git a/sandbox/linux/syscall_broker/broker_client.h b/sandbox/linux/syscall_broker/broker_client.h
index c97fc3b..4ca29653 100644
--- a/sandbox/linux/syscall_broker/broker_client.h
+++ b/sandbox/linux/syscall_broker/broker_client.h
@@ -17,7 +17,7 @@
 
 namespace syscall_broker {
 
-class BrokerPolicy;
+class BrokerPermissionList;
 
 // This class can be embedded in a sandboxed process and can be
 // used to perform certain system calls in another, presumably
@@ -34,7 +34,7 @@
   // |ipc_channel| needs to be a suitable SOCK_SEQPACKET unix socket.
   // |fast_check_in_client| should be set to true and
   // |quiet_failures_for_tests| to false unless you are writing tests.
-  BrokerClient(const BrokerPolicy& policy,
+  BrokerClient(const BrokerPermissionList& policy,
                BrokerChannel::EndPoint ipc_channel,
                const BrokerCommandSet& allowed_command_set,
                bool fast_check_in_client,
@@ -78,7 +78,7 @@
                         void* result_ptr,
                         size_t expected_result_size) const;
 
-  const BrokerPolicy& broker_policy_;
+  const BrokerPermissionList& broker_permission_list_;
   const BrokerChannel::EndPoint ipc_channel_;
   const BrokerCommandSet allowed_command_set_;
   const bool fast_check_in_client_;  // Whether to forward a request that we
diff --git a/sandbox/linux/syscall_broker/broker_command.cc b/sandbox/linux/syscall_broker/broker_command.cc
index 5d0e4374..ef6c819 100644
--- a/sandbox/linux/syscall_broker/broker_command.cc
+++ b/sandbox/linux/syscall_broker/broker_command.cc
@@ -3,13 +3,13 @@
 // found in the LICENSE file.
 
 #include "sandbox/linux/syscall_broker/broker_command.h"
-#include "sandbox/linux/syscall_broker/broker_policy.h"
+#include "sandbox/linux/syscall_broker/broker_permission_list.h"
 
 namespace sandbox {
 namespace syscall_broker {
 
 bool CommandAccessIsSafe(const BrokerCommandSet& command_set,
-                         const BrokerPolicy& policy,
+                         const BrokerPermissionList& policy,
                          const char* requested_filename,
                          int requested_mode,
                          const char** filename_to_use) {
@@ -19,7 +19,7 @@
 }
 
 bool CommandOpenIsSafe(const BrokerCommandSet& command_set,
-                       const BrokerPolicy& policy,
+                       const BrokerPermissionList& policy,
                        const char* requested_filename,
                        int requested_flags,
                        const char** filename_to_use,
@@ -30,7 +30,7 @@
 }
 
 bool CommandReadlinkIsSafe(const BrokerCommandSet& command_set,
-                           const BrokerPolicy& policy,
+                           const BrokerPermissionList& policy,
                            const char* requested_filename,
                            const char** filename_to_use) {
   return command_set.test(COMMAND_READLINK) &&
@@ -39,7 +39,7 @@
 }
 
 bool CommandRenameIsSafe(const BrokerCommandSet& command_set,
-                         const BrokerPolicy& policy,
+                         const BrokerPermissionList& policy,
                          const char* old_filename,
                          const char* new_filename,
                          const char** old_filename_to_use,
@@ -52,7 +52,7 @@
 }
 
 bool CommandStatIsSafe(const BrokerCommandSet& command_set,
-                       const BrokerPolicy& policy,
+                       const BrokerPermissionList& policy,
                        const char* requested_filename,
                        const char** filename_to_use) {
   return command_set.test(COMMAND_STAT) &&
diff --git a/sandbox/linux/syscall_broker/broker_command.h b/sandbox/linux/syscall_broker/broker_command.h
index 6257657..6594dbb5 100644
--- a/sandbox/linux/syscall_broker/broker_command.h
+++ b/sandbox/linux/syscall_broker/broker_command.h
@@ -14,7 +14,7 @@
 namespace sandbox {
 namespace syscall_broker {
 
-class BrokerPolicy;
+class BrokerPermissionList;
 
 constexpr size_t kMaxMessageLength = 4096;
 
@@ -51,32 +51,32 @@
 // (client or broker process) of a broker IPC command. The implementations
 // must be safe when called from an async signal handler.
 bool CommandAccessIsSafe(const BrokerCommandSet& command_set,
-                         const BrokerPolicy& policy,
+                         const BrokerPermissionList& policy,
                          const char* requested_filename,
                          int requested_mode,  // e.g. F_OK, R_OK, W_OK.
                          const char** filename_to_use);
 
 bool CommandOpenIsSafe(const BrokerCommandSet& command_set,
-                       const BrokerPolicy& policy,
+                       const BrokerPermissionList& policy,
                        const char* requested_filename,
                        int requested_flags,  // e.g. O_RDONLY, O_RDWR.
                        const char** filename_to_use,
                        bool* unlink_after_open);
 
 bool CommandReadlinkIsSafe(const BrokerCommandSet& command_set,
-                           const BrokerPolicy& policy,
+                           const BrokerPermissionList& policy,
                            const char* requested_filename,
                            const char** filename_to_use);
 
 bool CommandRenameIsSafe(const BrokerCommandSet& command_set,
-                         const BrokerPolicy& policy,
+                         const BrokerPermissionList& policy,
                          const char* old_filename,
                          const char* new_filename,
                          const char** old_filename_to_use,
                          const char** new_filename_to_use);
 
 bool CommandStatIsSafe(const BrokerCommandSet& command_set,
-                       const BrokerPolicy& policy,
+                       const BrokerPermissionList& policy,
                        const char* requested_filename,
                        const char** filename_to_use);
 
diff --git a/sandbox/linux/syscall_broker/broker_host.cc b/sandbox/linux/syscall_broker/broker_host.cc
index f558191..29926ca 100644
--- a/sandbox/linux/syscall_broker/broker_host.cc
+++ b/sandbox/linux/syscall_broker/broker_host.cc
@@ -24,7 +24,7 @@
 #include "base/posix/eintr_wrapper.h"
 #include "base/posix/unix_domain_socket.h"
 #include "sandbox/linux/syscall_broker/broker_command.h"
-#include "sandbox/linux/syscall_broker/broker_policy.h"
+#include "sandbox/linux/syscall_broker/broker_permission_list.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 
 namespace sandbox {
@@ -46,7 +46,7 @@
 // Write the syscall return value (-errno) to |write_pickle| and append
 // a file descriptor to |opened_files| if relevant.
 void OpenFileForIPC(const BrokerCommandSet& allowed_command_set,
-                    const BrokerPolicy& policy,
+                    const BrokerPermissionList& policy,
                     const std::string& requested_filename,
                     int flags,
                     base::Pickle* write_pickle,
@@ -77,7 +77,7 @@
 // Perform access(2) on |requested_filename| with mode |mode| if allowed by our
 // policy. Write the syscall return value (-errno) to |write_pickle|.
 void AccessFileForIPC(const BrokerCommandSet& allowed_command_set,
-                      const BrokerPolicy& policy,
+                      const BrokerPermissionList& policy,
                       const std::string& requested_filename,
                       int mode,
                       base::Pickle* write_pickle) {
@@ -100,7 +100,7 @@
 // Perform stat(2) on |requested_filename| and marshal the result to
 // |write_pickle|.
 void StatFileForIPC(const BrokerCommandSet& allowed_command_set,
-                    const BrokerPolicy& policy,
+                    const BrokerPermissionList& policy,
                     BrokerCommand command_type,
                     const std::string& requested_filename,
                     base::Pickle* write_pickle) {
@@ -134,7 +134,7 @@
 // Perform rename(2) on |old_filename| to |new_filename| and marshal the
 // result to |write_pickle|.
 void RenameFileForIPC(const BrokerCommandSet& allowed_command_set,
-                      const BrokerPolicy& policy,
+                      const BrokerPermissionList& policy,
                       const std::string& old_filename,
                       const std::string& new_filename,
                       base::Pickle* write_pickle) {
@@ -155,7 +155,7 @@
 
 // Perform readlink(2) on |filename| using a buffer of MAX_PATH bytes.
 void ReadlinkFileForIPC(const BrokerCommandSet& allowed_command_set,
-                        const BrokerPolicy& policy,
+                        const BrokerPermissionList& policy,
                         const std::string& filename,
                         base::Pickle* write_pickle) {
   const char* file_to_access = nullptr;
@@ -177,7 +177,7 @@
 // Handle a |command_type| request contained in |iter| and write the reply
 // to |write_pickle|, adding any files opened to |opened_files|.
 bool HandleRemoteCommand(const BrokerCommandSet& allowed_command_set,
-                         const BrokerPolicy& policy,
+                         const BrokerPermissionList& policy,
                          base::PickleIterator iter,
                          base::Pickle* write_pickle,
                          std::vector<int>* opened_files) {
@@ -239,10 +239,10 @@
 
 }  // namespace
 
-BrokerHost::BrokerHost(const BrokerPolicy& broker_policy,
+BrokerHost::BrokerHost(const BrokerPermissionList& broker_permission_list,
                        const BrokerCommandSet& allowed_command_set,
                        BrokerChannel::EndPoint ipc_channel)
-    : broker_policy_(broker_policy),
+    : broker_permission_list_(broker_permission_list),
       allowed_command_set_(allowed_command_set),
       ipc_channel_(std::move(ipc_channel)) {}
 
@@ -277,8 +277,9 @@
   base::PickleIterator iter(pickle);
   base::Pickle write_pickle;
   std::vector<int> opened_files;
-  bool result = HandleRemoteCommand(allowed_command_set_, broker_policy_, iter,
-                                    &write_pickle, &opened_files);
+  bool result =
+      HandleRemoteCommand(allowed_command_set_, broker_permission_list_, iter,
+                          &write_pickle, &opened_files);
 
   if (result) {
     CHECK_LE(write_pickle.size(), kMaxMessageLength);
diff --git a/sandbox/linux/syscall_broker/broker_host.h b/sandbox/linux/syscall_broker/broker_host.h
index 2051fc48..b54e32d3 100644
--- a/sandbox/linux/syscall_broker/broker_host.h
+++ b/sandbox/linux/syscall_broker/broker_host.h
@@ -13,16 +13,16 @@
 
 namespace syscall_broker {
 
-class BrokerPolicy;
+class BrokerPermissionList;
 
 // The BrokerHost class should be embedded in a (presumably not sandboxed)
 // process. It will honor IPC requests from a BrokerClient sent over
-// |ipc_channel| according to |broker_policy|.
+// |ipc_channel| according to |broker_permission_list|.
 class BrokerHost {
  public:
   enum class RequestStatus { LOST_CLIENT = 0, SUCCESS, FAILURE };
 
-  BrokerHost(const BrokerPolicy& broker_policy,
+  BrokerHost(const BrokerPermissionList& broker_permission_list,
              const BrokerCommandSet& allowed_command_set,
              BrokerChannel::EndPoint ipc_channel);
   ~BrokerHost();
@@ -30,7 +30,7 @@
   RequestStatus HandleRequest() const;
 
  private:
-  const BrokerPolicy& broker_policy_;
+  const BrokerPermissionList& broker_permission_list_;
   const BrokerCommandSet allowed_command_set_;
   const BrokerChannel::EndPoint ipc_channel_;
 
diff --git a/sandbox/linux/syscall_broker/broker_policy.cc b/sandbox/linux/syscall_broker/broker_permission_list.cc
similarity index 85%
rename from sandbox/linux/syscall_broker/broker_policy.cc
rename to sandbox/linux/syscall_broker/broker_permission_list.cc
index b3807aef..10040b0 100644
--- a/sandbox/linux/syscall_broker/broker_policy.cc
+++ b/sandbox/linux/syscall_broker/broker_permission_list.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "sandbox/linux/syscall_broker/broker_policy.h"
+#include "sandbox/linux/syscall_broker/broker_permission_list.h"
 
 #include <fcntl.h>
 #include <stddef.h>
@@ -18,8 +18,9 @@
 namespace sandbox {
 namespace syscall_broker {
 
-BrokerPolicy::BrokerPolicy(int denied_errno,
-                           const std::vector<BrokerFilePermission>& permissions)
+BrokerPermissionList::BrokerPermissionList(
+    int denied_errno,
+    const std::vector<BrokerFilePermission>& permissions)
     : denied_errno_(denied_errno),
       permissions_(permissions),
       num_of_permissions_(permissions.size()) {
@@ -33,8 +34,7 @@
   }
 }
 
-BrokerPolicy::~BrokerPolicy() {
-}
+BrokerPermissionList::~BrokerPermissionList() {}
 
 // Check if calling access() should be allowed on |requested_filename| with
 // mode |requested_mode|.
@@ -47,7 +47,7 @@
 // return true if calling access() on this file should be allowed, false
 // otherwise.
 // Async signal safe if and only if |file_to_access| is NULL.
-bool BrokerPolicy::GetFileNameIfAllowedToAccess(
+bool BrokerPermissionList::GetFileNameIfAllowedToAccess(
     const char* requested_filename,
     int requested_mode,
     const char** file_to_access) const {
@@ -75,10 +75,11 @@
 // string comparison mechanism.
 // Return true if opening should be allowed, false otherwise.
 // Async signal safe if and only if |file_to_open| is NULL.
-bool BrokerPolicy::GetFileNameIfAllowedToOpen(const char* requested_filename,
-                                              int requested_flags,
-                                              const char** file_to_open,
-                                              bool* unlink_after_open) const {
+bool BrokerPermissionList::GetFileNameIfAllowedToOpen(
+    const char* requested_filename,
+    int requested_flags,
+    const char** file_to_open,
+    bool* unlink_after_open) const {
   if (file_to_open && *file_to_open) {
     // Make sure that callers never pass a non-empty string. In case callers
     // wrongly forget to check the return value and look at the string
diff --git a/sandbox/linux/syscall_broker/broker_policy.h b/sandbox/linux/syscall_broker/broker_permission_list.h
similarity index 82%
rename from sandbox/linux/syscall_broker/broker_policy.h
rename to sandbox/linux/syscall_broker/broker_permission_list.h
index 58bc29a..b953d3b 100644
--- a/sandbox/linux/syscall_broker/broker_policy.h
+++ b/sandbox/linux/syscall_broker/broker_permission_list.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SANDBOX_LINUX_SYSCALL_BROKER_BROKER_POLICY_H_
-#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_POLICY_H_
+#ifndef SANDBOX_LINUX_SYSCALL_BROKER_BROKER_PERMISSION_LIST_H_
+#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_PERMISSION_LIST_H_
 
 #include <stddef.h>
 
@@ -17,22 +17,21 @@
 namespace sandbox {
 namespace syscall_broker {
 
-// BrokerPolicy allows to define the security policy enforced by a
-// BrokerHost. The BrokerHost will evaluate requests sent over its
-// IPC channel according to the BrokerPolicy.
-// Some of the methods of this class can be used in an async-signal safe
-// way.
-class BrokerPolicy {
+// BrokerPermissionList defines the file access control list enforced by
+// a BrokerHost. The BrokerHost will evaluate requests to manipulate files
+// sent over its IPC channel according to the BrokerPermissionList.
+// The methods of this class must be usable in an async-signal safe manner.
+class BrokerPermissionList {
  public:
   // |denied_errno| is the error code returned when IPC requests for system
   // calls such as open() or access() are denied because a file is not in the
   // whitelist. EACCESS would be a typical value.
   // |permissions| is a list of BrokerPermission objects that define
   // what the broker will allow.
-  BrokerPolicy(int denied_errno,
-               const std::vector<BrokerFilePermission>& permissions);
+  BrokerPermissionList(int denied_errno,
+                       const std::vector<BrokerFilePermission>& permissions);
 
-  ~BrokerPolicy();
+  ~BrokerPermissionList();
 
   // Check if calling access() should be allowed on |requested_filename| with
   // mode |requested_mode|.
@@ -66,6 +65,7 @@
                                   int requested_flags,
                                   const char** file_to_open,
                                   bool* unlink_after_open) const;
+
   int denied_errno() const { return denied_errno_; }
 
  private:
@@ -79,11 +79,11 @@
   const BrokerFilePermission* permissions_array_;
   const size_t num_of_permissions_;
 
-  DISALLOW_COPY_AND_ASSIGN(BrokerPolicy);
+  DISALLOW_COPY_AND_ASSIGN(BrokerPermissionList);
 };
 
 }  // namespace syscall_broker
 
 }  // namespace sandbox
 
-#endif  // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_POLICY_H_
+#endif  // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_PERMISSION_LIST_H_
diff --git a/sandbox/linux/syscall_broker/broker_process.cc b/sandbox/linux/syscall_broker/broker_process.cc
index 936bf13..cdd7e07 100644
--- a/sandbox/linux/syscall_broker/broker_process.cc
+++ b/sandbox/linux/syscall_broker/broker_process.cc
@@ -41,7 +41,7 @@
       fast_check_in_client_(fast_check_in_client),
       quiet_failures_for_tests_(quiet_failures_for_tests),
       allowed_command_set_(allowed_command_set),
-      broker_policy_(denied_errno, permissions) {}
+      broker_permission_list_(denied_errno, permissions) {}
 
 BrokerProcess::~BrokerProcess() {
   if (initialized_) {
@@ -77,7 +77,7 @@
     ipc_reader.reset();
     broker_pid_ = child_pid;
     broker_client_ = std::make_unique<BrokerClient>(
-        broker_policy_, std::move(ipc_writer), allowed_command_set_,
+        broker_permission_list_, std::move(ipc_writer), allowed_command_set_,
         fast_check_in_client_, quiet_failures_for_tests_);
     initialized_ = true;
     return true;
@@ -87,7 +87,7 @@
   // we get notified if the client disappears.
   ipc_writer.reset();
   CHECK(broker_process_init_callback.Run());
-  BrokerHost broker_host(broker_policy_, allowed_command_set_,
+  BrokerHost broker_host(broker_permission_list_, allowed_command_set_,
                          std::move(ipc_reader));
   for (;;) {
     switch (broker_host.HandleRequest()) {
diff --git a/sandbox/linux/syscall_broker/broker_process.h b/sandbox/linux/syscall_broker/broker_process.h
index 39e92a5..8e13cac 100644
--- a/sandbox/linux/syscall_broker/broker_process.h
+++ b/sandbox/linux/syscall_broker/broker_process.h
@@ -15,7 +15,7 @@
 #include "base/process/process.h"
 #include "sandbox/linux/bpf_dsl/trap_registry.h"
 #include "sandbox/linux/syscall_broker/broker_command.h"
-#include "sandbox/linux/syscall_broker/broker_policy.h"
+#include "sandbox/linux/syscall_broker/broker_permission_list.h"
 #include "sandbox/sandbox_export.h"
 
 namespace sandbox {
@@ -111,7 +111,8 @@
   const bool fast_check_in_client_;
   const bool quiet_failures_for_tests_;
   syscall_broker::BrokerCommandSet allowed_command_set_;
-  syscall_broker::BrokerPolicy broker_policy_;  // File access whitelist.
+  syscall_broker::BrokerPermissionList
+      broker_permission_list_;  // File access whitelist.
   std::unique_ptr<syscall_broker::BrokerClient> broker_client_;
 
   DISALLOW_COPY_AND_ASSIGN(BrokerProcess);
diff --git a/services/data_decoder/BUILD.gn b/services/data_decoder/BUILD.gn
index 3d9da8c..b0f7201 100644
--- a/services/data_decoder/BUILD.gn
+++ b/services/data_decoder/BUILD.gn
@@ -55,10 +55,14 @@
     "//skia",
     "//testing/gtest",
     "//third_party/WebKit/public:blink",
+    "//tools/v8_context_snapshot",
     "//ui/gfx",
   ]
 
-  configs += [ "//v8:external_startup_data" ]
+  configs += [
+    "//tools/v8_context_snapshot:use_v8_context_snapshot",
+    "//v8:external_startup_data",
+  ]
 }
 
 service_manifest("manifest") {
diff --git a/services/data_decoder/image_decoder_impl_unittest.cc b/services/data_decoder/image_decoder_impl_unittest.cc
index f15910ba..3a59c88f 100644
--- a/services/data_decoder/image_decoder_impl_unittest.cc
+++ b/services/data_decoder/image_decoder_impl_unittest.cc
@@ -74,7 +74,10 @@
 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
     gin::V8Initializer::LoadV8Snapshot();
     gin::V8Initializer::LoadV8Natives();
-#endif
+#if defined(USE_V8_CONTEXT_SNAPSHOT)
+    gin::V8Initializer::LoadV8ContextSnapshot();
+#endif  // USE_V8_CONTEXT_SNAPSHOT
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
 
     service_manager::BinderRegistry empty_registry;
     blink::Initialize(this, &empty_registry);
diff --git a/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc b/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc
index 8e79d121..e0c5d01 100644
--- a/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc
+++ b/services/device/generic_sensor/platform_sensor_and_provider_unittest_win.cc
@@ -599,9 +599,9 @@
   base::RunLoop().RunUntilIdle();
   SensorReadingSharedBuffer* buffer =
       static_cast<SensorReadingSharedBuffer*>(mapping.get());
-  EXPECT_THAT(buffer->reading.gyro.x, gfx::DegToRad(-x_ang_accel));
-  EXPECT_THAT(buffer->reading.gyro.y, gfx::DegToRad(-y_ang_accel));
-  EXPECT_THAT(buffer->reading.gyro.z, gfx::DegToRad(-z_ang_accel));
+  EXPECT_THAT(buffer->reading.gyro.x, gfx::DegToRad(x_ang_accel));
+  EXPECT_THAT(buffer->reading.gyro.y, gfx::DegToRad(y_ang_accel));
+  EXPECT_THAT(buffer->reading.gyro.z, gfx::DegToRad(z_ang_accel));
   EXPECT_TRUE(sensor->StopListening(client.get(), configuration));
 }
 
@@ -639,9 +639,9 @@
   base::RunLoop().RunUntilIdle();
   SensorReadingSharedBuffer* buffer =
       static_cast<SensorReadingSharedBuffer*>(mapping.get());
-  EXPECT_THAT(buffer->reading.magn.x, -x_magn_field * kMicroteslaInMilligauss);
-  EXPECT_THAT(buffer->reading.magn.y, -y_magn_field * kMicroteslaInMilligauss);
-  EXPECT_THAT(buffer->reading.magn.z, -z_magn_field * kMicroteslaInMilligauss);
+  EXPECT_THAT(buffer->reading.magn.x, x_magn_field * kMicroteslaInMilligauss);
+  EXPECT_THAT(buffer->reading.magn.y, y_magn_field * kMicroteslaInMilligauss);
+  EXPECT_THAT(buffer->reading.magn.z, z_magn_field * kMicroteslaInMilligauss);
   EXPECT_TRUE(sensor->StopListening(client.get(), configuration));
 }
 
@@ -730,9 +730,9 @@
   SensorReadingSharedBuffer* buffer =
       static_cast<SensorReadingSharedBuffer*>(mapping.get());
 
-  EXPECT_THAT(buffer->reading.orientation_quat.x, -x);
-  EXPECT_THAT(buffer->reading.orientation_quat.y, -y);
-  EXPECT_THAT(buffer->reading.orientation_quat.z, -z);
+  EXPECT_THAT(buffer->reading.orientation_quat.x, x);
+  EXPECT_THAT(buffer->reading.orientation_quat.y, y);
+  EXPECT_THAT(buffer->reading.orientation_quat.z, z);
   EXPECT_THAT(buffer->reading.orientation_quat.w, w);
   EXPECT_TRUE(sensor->StopListening(client.get(), configuration));
 }
diff --git a/services/device/generic_sensor/platform_sensor_reader_win.cc b/services/device/generic_sensor/platform_sensor_reader_win.cc
index 2f6b3a0..a9cfefc2 100644
--- a/services/device/generic_sensor/platform_sensor_reader_win.cc
+++ b/services/device/generic_sensor/platform_sensor_reader_win.cc
@@ -88,9 +88,15 @@
       return E_FAIL;
     }
 
-    // Windows uses coordinate system where Z axis points down from device
-    // screen, therefore, using right hand notation, we have to reverse
-    // sign for each axis. Values are converted from G/s^2 to m/s^2.
+    // Windows HW sensor integration requirements specify accelerometer
+    // measurements conventions such as, the accelerometer sensor must expose
+    // values that are proportional and in the same direction as the force of
+    // gravity. Therefore, sensor hosted by the device at rest on a leveled
+    // surface while the screen is facing towards the sky, must report -1G along
+    // the Z axis.
+    // https://msdn.microsoft.com/en-us/library/windows/hardware/dn642102(v=vs.85).aspx
+    // Change sign of values, to report 'reaction force', and convert values
+    // from G/s^2 to m/s^2 units.
     reading->accel.x = -x * kMeanGravity;
     reading->accel.y = -y * kMeanGravity;
     reading->accel.z = -z * kMeanGravity;
@@ -119,12 +125,10 @@
       return E_FAIL;
     }
 
-    // Windows uses coordinate system where Z axis points down from device
-    // screen, therefore, using right hand notation, we have to reverse
-    // sign for each axis. Values are converted from deg to rad.
-    reading->gyro.x = gfx::DegToRad(-x);
-    reading->gyro.y = gfx::DegToRad(-y);
-    reading->gyro.z = gfx::DegToRad(-z);
+    // Values are converted from degrees to radians.
+    reading->gyro.x = gfx::DegToRad(x);
+    reading->gyro.y = gfx::DegToRad(y);
+    reading->gyro.z = gfx::DegToRad(z);
     return S_OK;
   };
   return params;
@@ -150,13 +154,10 @@
       return E_FAIL;
     }
 
-    // Windows uses coordinate system where Z axis points down from device
-    // screen, therefore, using right hand notation, we have to reverse
-    // sign for each axis. Values are converted from Milligaus to
-    // Microtesla.
-    reading->magn.x = -x * kMicroteslaInMilligauss;
-    reading->magn.y = -y * kMicroteslaInMilligauss;
-    reading->magn.z = -z * kMicroteslaInMilligauss;
+    // Values are converted from Milligaus to Microtesla.
+    reading->magn.x = x * kMicroteslaInMilligauss;
+    reading->magn.y = y * kMicroteslaInMilligauss;
+    reading->magn.z = z * kMicroteslaInMilligauss;
     return S_OK;
   };
   return params;
@@ -204,13 +205,10 @@
 
     float* quat = reinterpret_cast<float*>(quat_variant.get().caub.pElems);
 
-    // Windows uses coordinate system where Z axis points down from device
-    // screen, therefore, using right hand notation, we have to reverse
-    // sign for each quaternion component.
-    reading->orientation_quat.x = -quat[0];  // x*sin(Theta/2)
-    reading->orientation_quat.y = -quat[1];  // y*sin(Theta/2)
-    reading->orientation_quat.z = -quat[2];  // z*sin(Theta/2)
-    reading->orientation_quat.w = quat[3];   // cos(Theta/2)
+    reading->orientation_quat.x = quat[0];  // x*sin(Theta/2)
+    reading->orientation_quat.y = quat[1];  // y*sin(Theta/2)
+    reading->orientation_quat.z = quat[2];  // z*sin(Theta/2)
+    reading->orientation_quat.w = quat[3];  // cos(Theta/2)
     return S_OK;
   };
   return params;
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
index 86396d7..868cbca 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
@@ -590,10 +590,9 @@
   // and friends makes it too easy to accidentally odr-use this variable
   // causing all sorts of compiler-toolchain divergent fun when trying
   // to decide of the lambda capture is necessary.
-  enum {
-    kBrowserPid = 1,
-    kRendererPid = 2,
-  };
+  static constexpr base::ProcessId kBrowserPid = 1;
+  static constexpr base::ProcessId kRendererPid = 2;
+
   MockClientProcess browser_client(this, kBrowserPid,
                                    mojom::ProcessType::BROWSER);
   MockClientProcess renderer_client(this, kRendererPid,
diff --git a/services/ui/public/cpp/gpu/gpu.cc b/services/ui/public/cpp/gpu/gpu.cc
index 35e067f..452e7d3 100644
--- a/services/ui/public/cpp/gpu/gpu.cc
+++ b/services/ui/public/cpp/gpu/gpu.cc
@@ -235,12 +235,9 @@
   SendEstablishGpuChannelRequest();
 }
 
-scoped_refptr<gpu::GpuChannelHost> Gpu::EstablishGpuChannelSync(
-    bool* connection_error) {
+scoped_refptr<gpu::GpuChannelHost> Gpu::EstablishGpuChannelSync() {
   TRACE_EVENT0("mus", "Gpu::EstablishGpuChannelSync");
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-  if (connection_error)
-    *connection_error = false;
 
   scoped_refptr<gpu::GpuChannelHost> channel = GetGpuChannel();
   if (channel)
diff --git a/services/ui/public/cpp/gpu/gpu.h b/services/ui/public/cpp/gpu/gpu.h
index 933d0dc6..bda7c44f 100644
--- a/services/ui/public/cpp/gpu/gpu.h
+++ b/services/ui/public/cpp/gpu/gpu.h
@@ -48,8 +48,7 @@
   // gpu::GpuChannelEstablishFactory:
   void EstablishGpuChannel(
       const gpu::GpuChannelEstablishedCallback& callback) override;
-  scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync(
-      bool* connection_error) override;
+  scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override;
   gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
 
   void LoseChannel();
diff --git a/services/ui/public/cpp/tests/gpu_unittest.cc b/services/ui/public/cpp/tests/gpu_unittest.cc
index dd2775f4..b8259291 100644
--- a/services/ui/public/cpp/tests/gpu_unittest.cc
+++ b/services/ui/public/cpp/tests/gpu_unittest.cc
@@ -246,10 +246,7 @@
       },
       base::Unretained(&counter)));
 
-  bool connection_error = false;
-  scoped_refptr<gpu::GpuChannelHost> host =
-      gpu()->EstablishGpuChannelSync(&connection_error);
-  EXPECT_FALSE(connection_error);
+  scoped_refptr<gpu::GpuChannelHost> host = gpu()->EstablishGpuChannelSync();
   EXPECT_EQ(1, counter);
   EXPECT_TRUE(host);
 }
@@ -276,10 +273,7 @@
   // Run EstablishGpuChannelSync() before the posted task can run. The response
   // to the async request should be used immediately, the pending callback
   // should fire and then EstablishGpuChannelSync() should return.
-  bool connection_error = false;
-  scoped_refptr<gpu::GpuChannelHost> host =
-      gpu()->EstablishGpuChannelSync(&connection_error);
-  EXPECT_FALSE(connection_error);
+  scoped_refptr<gpu::GpuChannelHost> host = gpu()->EstablishGpuChannelSync();
   EXPECT_EQ(1, counter);
   EXPECT_TRUE(host);
 
diff --git a/services/ui/ws/display.h b/services/ui/ws/display.h
index 0978068..e4d7c68 100644
--- a/services/ui/ws/display.h
+++ b/services/ui/ws/display.h
@@ -14,7 +14,7 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "services/ui/common/types.h"
 #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
 #include "services/ui/public/interfaces/window_tree_host.mojom.h"
@@ -220,7 +220,7 @@
   // external window mode this will be invalid.
   display::Display display_;
 
-  viz::LocalSurfaceIdAllocator allocator_;
+  viz::ParentLocalSurfaceIdAllocator allocator_;
 
   WindowManagerDisplayRootMap window_manager_display_root_map_;
 
diff --git a/services/ui/ws/frame_generator.h b/services/ui/ws/frame_generator.h
index 2985c172..589ac19 100644
--- a/services/ui/ws/frame_generator.h
+++ b/services/ui/ws/frame_generator.h
@@ -9,7 +9,7 @@
 
 #include "base/macros.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/common/surfaces/surface_id.h"
 #include "components/viz/common/surfaces/surface_info.h"
 #include "services/ui/ws/compositor_frame_sink_client_binding.h"
@@ -77,7 +77,7 @@
   bool high_contrast_mode_enabled_ = false;
   gfx::Size last_submitted_frame_size_;
   viz::LocalSurfaceId local_surface_id_;
-  viz::LocalSurfaceIdAllocator id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator id_allocator_;
   float last_device_scale_factor_ = 0.0f;
 
   viz::SurfaceInfo window_manager_surface_info_;
diff --git a/services/ui/ws/window_manager_display_root.h b/services/ui/ws/window_manager_display_root.h
index a43ec75..c6962e42 100644
--- a/services/ui/ws/window_manager_display_root.h
+++ b/services/ui/ws/window_manager_display_root.h
@@ -10,7 +10,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 
 namespace ui {
 namespace ws {
@@ -64,7 +64,7 @@
   // the root ServerWindow of the Display.
   std::unique_ptr<ServerWindow> root_;
   WindowManagerState* window_manager_state_ = nullptr;
-  viz::LocalSurfaceIdAllocator allocator_;
+  viz::ParentLocalSurfaceIdAllocator allocator_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowManagerDisplayRoot);
 };
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc
index a2326c28..c15cd120 100644
--- a/services/ui/ws/window_tree_client_unittest.cc
+++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
@@ -1428,7 +1428,7 @@
 
   wt_client2_->set_track_root_bounds_changes(true);
 
-  viz::LocalSurfaceIdAllocator allocator;
+  viz::ParentLocalSurfaceIdAllocator allocator;
   viz::LocalSurfaceId local_surface_id = allocator.GenerateId();
   wt1()->SetWindowBounds(10, window_1_1, gfx::Rect(0, 0, 100, 100),
                          local_surface_id);
diff --git a/services/viz/public/cpp/compositing/filter_operation_struct_traits.h b/services/viz/public/cpp/compositing/filter_operation_struct_traits.h
index 928cee6..fa7fee1 100644
--- a/services/viz/public/cpp/compositing/filter_operation_struct_traits.h
+++ b/services/viz/public/cpp/compositing/filter_operation_struct_traits.h
@@ -129,6 +129,8 @@
       const cc::FilterOperation& operation) {
     if (operation.type() != cc::FilterOperation::REFERENCE)
       return nullptr;
+    if (!operation.image_filter())
+      return nullptr;
     return operation.image_filter()->cached_sk_filter_;
   }
 
diff --git a/services/viz/public/cpp/compositing/local_surface_id_struct_traits.h b/services/viz/public/cpp/compositing/local_surface_id_struct_traits.h
index 1793959..cc0c1478 100644
--- a/services/viz/public/cpp/compositing/local_surface_id_struct_traits.h
+++ b/services/viz/public/cpp/compositing/local_surface_id_struct_traits.h
@@ -17,6 +17,11 @@
     return local_surface_id.parent_id();
   }
 
+  static uint32_t child_sequence_number(
+      const viz::LocalSurfaceId& local_surface_id) {
+    return local_surface_id.child_sequence_number();
+  }
+
   static const base::UnguessableToken& nonce(
       const viz::LocalSurfaceId& local_surface_id) {
     return local_surface_id.nonce();
@@ -25,6 +30,7 @@
   static bool Read(viz::mojom::LocalSurfaceIdDataView data,
                    viz::LocalSurfaceId* out) {
     out->parent_id_ = data.parent_id();
+    out->child_sequence_number_ = data.child_sequence_number();
     return data.ReadNonce(&out->nonce_);
   }
 };
diff --git a/services/viz/public/interfaces/compositing/local_surface_id.mojom b/services/viz/public/interfaces/compositing/local_surface_id.mojom
index c610e206..8a1b6dd 100644
--- a/services/viz/public/interfaces/compositing/local_surface_id.mojom
+++ b/services/viz/public/interfaces/compositing/local_surface_id.mojom
@@ -12,6 +12,10 @@
   // With surface synchronization enabled, this is allocated by the parent.
   uint32 parent_id;
 
+  // An identifier allocated by the client for when the client wants to allocate
+  // its own surface.
+  uint32 child_sequence_number;
+
   mojo.common.mojom.UnguessableToken nonce;
 };
 
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 00bdd27..46a8cfcf 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -3674,28 +3674,6 @@
         "test": "viz_unittests"
       }
     ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "--browser=android-chromium",
-          "--device=android"
-        ],
-        "isolate_name": "telemetry_perf_unittests",
-        "name": "telemetry_perf_unittests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead",
-              "temp_band": "<30"
-            }
-          ],
-          "hard_timeout": 1500,
-          "shards": 15
-        }
-      }
-    ],
     "junit_tests": [
       {
         "test": "base_junit_tests"
diff --git a/testing/buildbot/chromium.chrome.json b/testing/buildbot/chromium.chrome.json
index 0967ef4..8aff5afe 100644
--- a/testing/buildbot/chromium.chrome.json
+++ b/testing/buildbot/chromium.chrome.json
@@ -1 +1,4 @@
-{}
+{
+  "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
+  "AAAAA2 See generate_buildbot_json.py to make changes": {}
+}
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 303a995..0a72917 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1,4 +1,6 @@
 {
+  "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
+  "AAAAA2 See generate_buildbot_json.py to make changes": {},
   "Linux ChromiumOS Builder": {
     "additional_compile_targets": [
       "All"
@@ -796,6 +798,12 @@
         "test": "ash_content_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "ash_unittests"
+      },
+      {
         "args": [
           "--mash",
           "--test-launcher-filter-file=../../testing/buildbot/filters/ash_unittests_mash.filter"
@@ -823,12 +831,6 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
-        "test": "ash_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
         "test": "aura_unittests"
       },
       {
@@ -921,13 +923,6 @@
         "test": "compositor_unittests"
       },
       {
-        "args": [
-          "--enable-viz",
-          "--ozone-platform=headless",
-          "--override-use-software-gl-for-tests",
-          "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_browsertests.filter"
-        ],
-        "name": "viz_content_browsertests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "shards": 2
@@ -948,6 +943,13 @@
         "test": "content_browsertests"
       },
       {
+        "args": [
+          "--enable-viz",
+          "--ozone-platform=headless",
+          "--override-use-software-gl-for-tests",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_browsertests.filter"
+        ],
+        "name": "viz_content_browsertests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "shards": 2
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 4bdfc09..6bf69b42 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -7069,12 +7069,6 @@
           "can_use_on_swarming_builders": true
         },
         "test": "vr_common_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "vr_pixeltests"
       }
     ]
   },
@@ -7082,7 +7076,9 @@
     "isolated_scripts": [
       {
         "args": [
-          "--additional-driver-flag=--enable-blink-features=LayoutNG"
+          "--additional-driver-flag=--enable-blink-features=LayoutNG",
+          "--additional-driver-flag=--enable-blink-features=LayoutNGPaintFragments",
+          "--additional-driver-flag=--enable-slimming-paint-v175"
         ],
         "isolate_name": "webkit_layout_tests_exparchive",
         "merge": {
diff --git a/testing/buildbot/chromium.lkgr.json b/testing/buildbot/chromium.lkgr.json
index 6f7d81d8..5b733b1 100644
--- a/testing/buildbot/chromium.lkgr.json
+++ b/testing/buildbot/chromium.lkgr.json
@@ -1,4 +1,6 @@
 {
+  "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
+  "AAAAA2 See generate_buildbot_json.py to make changes": {},
   "ASAN Release": {
     "additional_compile_targets": [
       "chromium_builder_asan"
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index ea3ddd1..0ebfb2a 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -391,11 +391,14 @@
         }
       },
       {
+        "args": [
+          "--jobs=1"
+        ],
         "isolate_name": "telemetry_unittests",
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       },
       {
@@ -794,11 +797,14 @@
         }
       },
       {
+        "args": [
+          "--jobs=1"
+        ],
         "isolate_name": "telemetry_unittests",
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       },
       {
@@ -1204,7 +1210,7 @@
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       },
       {
@@ -1643,11 +1649,14 @@
         }
       },
       {
+        "args": [
+          "--jobs=1"
+        ],
         "isolate_name": "telemetry_unittests",
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       },
       {
@@ -2039,11 +2048,14 @@
         }
       },
       {
+        "args": [
+          "--jobs=1"
+        ],
         "isolate_name": "telemetry_unittests",
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       }
     ]
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index ba3cc17..0e9c576 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -514,11 +514,14 @@
         }
       },
       {
+        "args": [
+          "--jobs=1"
+        ],
         "isolate_name": "telemetry_unittests",
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       }
     ]
@@ -1610,11 +1613,14 @@
         }
       },
       {
+        "args": [
+          "--jobs=1"
+        ],
         "isolate_name": "telemetry_unittests",
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       },
       {
@@ -2089,11 +2095,14 @@
         }
       },
       {
+        "args": [
+          "--jobs=1"
+        ],
         "isolate_name": "telemetry_unittests",
         "name": "telemetry_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
-          "shards": 2
+          "shards": 4
         }
       },
       {
diff --git a/testing/buildbot/filters/ash_unittests_mash.filter b/testing/buildbot/filters/ash_unittests_mash.filter
index ef501303..d0815d5 100644
--- a/testing/buildbot/filters/ash_unittests_mash.filter
+++ b/testing/buildbot/filters/ash_unittests_mash.filter
@@ -144,6 +144,12 @@
 -ShelfLayoutManagerTest.AutoHideShelfOnScreenBoundary
 -ShelfLayoutManagerTest.GestureDrag
 
+# TODO: http://crbug.com/695562
+-ShelfWindowWatcherTest.CreateAndRemoveShelfItemProperties
+
+# TODO: Probably event filter problem. http://crbug.com/695758
+-ShellTest.TestPreTargetHandlerOrder
+
 # TODO: Needs virtual keyboard. http://crbug.com/698892
 -SystemModalContainerLayoutManagerTest.SystemModalDialogGetPushedButNotCroppedFromKeyboard
 -SystemModalContainerLayoutManagerTest.SystemModalDialogGetPushedButNotCroppedFromKeyboardIfNotCentered
@@ -155,6 +161,9 @@
 -TabletModeWindowManagerTest.ExitFullScreenWithEdgeTouchAtBottom
 -TabletModeWindowManagerTest.ExitFullScreenWithEdgeTouchAtTop
 
+# TODO: Needs CursorManager. http://crbug.com/631103
+-TooltipControllerTest.HideTooltipWhenCursorHidden
+
 # TODO: Touch HUD. http://crbug.com/698032
 -TouchHudDebugTest.DualDisplays
 -TouchHudDebugTest.Headless
@@ -182,10 +191,23 @@
 -VirtualKeyboardControllerAutoTest.SuppressedIfExternalKeyboardPresent
 -VirtualKeyboardControllerAutoTest.SuppressedInMaximizedMode
 
+# TODO: Needs virtual keyboard, but different issue. http://crbug.com/695640
+-VirtualKeyboardRootWindowControllerTest.EnsureCaretInWorkAreaWithMultipleDisplays
+-VirtualKeyboardRootWindowControllerTest.FollowInputFocus
+-VirtualKeyboardRootWindowControllerTest.VirtualKeyboardOnTouchableDisplayOnly
+-VirtualKeyboardRootWindowControllerTest.VirtualKeyboardShowOnSpecifiedDisplay
+
 # TODO: http://crbug.com/698894
 -WindowCycleControllerTest.MouseEventsCaptured
 -WindowCycleControllerTest.TabKeyNotLeaked
 
+# TODO: Needs CursorManager. http://crbug.com/631103
+-WindowManagerTest.MouseEventCursors
+-WindowManagerTest.UpdateCursorVisibility
+-WindowManagerTest.UpdateCursorVisibilityOnKeyEvent
+-WindowManagerTest.UpdateCursorVisibilityAccelerator
+-WindowManagerTest.TestCursorClientObserver
+
 # TODO: Crashes in bounds_animator.cc. http://crbug.com/730759
 -WindowSelectorTest.MultipleDisplays
 -WindowSelectorTest.RemoveDisplay
@@ -198,12 +220,21 @@
 # TODO: Panel focus is broken. http://crbug.com/780936
 -WorkspaceControllerTest.WindowEdgeMouseHitTestPanel
 
+# TODO: Possible event filter problem. http://crbug.com/699175
+-WorkspaceEventHandlerTest.DoubleClickCaptionTogglesMaximize
+-WorkspaceEventHandlerTest.DoubleClickSingleAxisResizeEdge
+-WorkspaceEventHandlerTest.DoubleClickSingleAxisWhenSideSnapped
+-WorkspaceEventHandlerTest.DoubleTapCaptionTogglesMaximize
+
 # TODO: Needs virtual keyboard. http://crbug.com/616909
 -WorkspaceLayoutManagerKeyboardTest.AdjustWindowForA11yKeyboard
 -WorkspaceLayoutManagerKeyboardTest.ChildWindowFocused
 -WorkspaceLayoutManagerKeyboardTest.IgnoreKeyboardBoundsChange
 -WorkspaceLayoutManagerKeyboardTest.IgnoreWorkAreaChangeinNonStickyMode
 
+# TODO: Possible display config issue. http://crbug.com/793101
+-WorkspaceLayoutManagerTest.KeepMinimumVisibilityInDisplays
+
 # TODO: Needs CursorManager. http://crbug.com/631103
 -WorkspaceWindowResizerTest.MouseMoveWithTouchDrag
 
diff --git a/testing/buildbot/filters/fuchsia.net_unittests.filter b/testing/buildbot/filters/fuchsia.net_unittests.filter
index 9f37d9c..74794b81 100644
--- a/testing/buildbot/filters/fuchsia.net_unittests.filter
+++ b/testing/buildbot/filters/fuchsia.net_unittests.filter
@@ -17,6 +17,3 @@
 
 # Flaky, https://crbug.com/784448.
 -DiskCacheBackendTest.InvalidEntry5
-
-# New test, which fails under Fuchsia. http://crbug.com/792300
--HTTPSCRLSetTest.CRLSetRevokedBySubject
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
index 2cbbdb5..50b382d 100644
--- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -14,7 +14,6 @@
 # note: this passes locally but fails on bot.
 -BrowserTest.CancelBeforeUnloadResetsURL
 -BrowserTest.ClearPendingOnFailUnlessNTP
--BrowserTest.GetSizeForNewRenderView
 -BrowserTest.InterstitialCancelsGuestViewDialogs
 -BrowsingDataRemoverBrowserTest.Cache
 -BrowsingDataRemoverBrowserTest.CookieDeletion
@@ -24,8 +23,6 @@
 -ChromeSecurityExploitBrowserTest.CreateFilesystemURLInExtensionOrigin
 -ChromeSitePerProcessTest.LaunchExternalProtocolFromSubframe
 -ContentFaviconDriverTest.ReloadBypassingCache
--ContentScriptApiTests/ContentScriptApiTest.CannotScriptTheNewTabPage/0
--ContentScriptApiTests/ContentScriptApiTest.CannotScriptTheNewTabPage/1
 -ContentVerifierTest.DotSlashPaths
 -ContentVerifierTest.FailOnDone
 -ContentVerifierTest.FailOnRead
@@ -74,7 +71,6 @@
 -ExpectCTBrowserTest.TestDynamicExpectCTHeaderProcessing
 -ExpectCTBrowserTest.TestDynamicExpectCTReporting
 -ExperimentalAppWindowApiTest.SetIcon
--ExtensionApiTabTest.OnUpdatedDiscardedState
 -ExtensionApiTabTest.TabsOnUpdated
 -ExtensionApiTest.ContentSecurityPolicy
 -ExtensionApiTest.Cookies
@@ -99,8 +95,6 @@
 -FeedbackTest.ShowLoginFeedback
 -FileProxyScriptBrowserTest.Verify
 -FtpProxyScriptBrowserTest.Verify
--HttpProxyScriptBrowserTest.Verify
--InlineLoginUISafeIframeBrowserTest.LoadSuccessContinueURL
 -InProcessBrowserTest.ExternalConnectionFail
 -InstantThemeTest.ThemeBackgroundAccess
 -IsolatedAppTest.CookieIsolation
@@ -123,9 +117,7 @@
 -MediaStreamDevicesControllerTest.ExtensionRequestMicCam
 -NaClBrowserTestGLibcVcacheExtension.ValidationCacheOfMainNexe
 -NaClBrowserTestNewlibVcacheExtension.ValidationCacheOfMainNexe
--NetInternalsTest.netInternalsPrerenderViewFail
 -NetInternalsTest.netInternalsSessionBandwidthSucceed
--NewTabUIProcessPerTabTest.NavBeforeNTPCommits
 -NewlibPackagedAppTest.MulticastPermissions
 -NewlibPackagedAppTest.NoSocketPermissions
 -NewlibPackagedAppTest.SocketPermissions
@@ -147,12 +139,9 @@
 -PlatformAppBrowserTest.Isolation
 -PlatformAppDevToolsBrowserTest.ReOpenedWithID
 -PlatformAppDevToolsBrowserTest.ReOpenedWithURL
--PolicyTest.BookmarkBarEnabled
 -PolicyTest.DefaultCookiesSetting
--PolicyTest.HomepageLocation
 -PrefetchBrowserTestPredictionDisabled.ExperimentDisabled
 -PreviewsOptimizationGuideBrowserTest.NoScriptPreviewsEnabledByWhitelist
--ProcessManagementTest.ProcessOverflow
 -ProcessManagerBrowserTest.ExtensionProcessReuse
 -ProcessManagerBrowserTest.NestedURLNavigationsToExtensionAllowed
 -ProfileWindowBrowserTest.GuestClearsCookies
@@ -191,15 +180,10 @@
 -SSLUITest.TestBadHTTPSDownload
 -SSLUITest.TestHTTPSOCSPOk
 -SSLUITest.TestHTTPSOCSPRevoked
--SSLUITestIgnoreLocalhostCertErrors.TestNoInterstitialOnLocalhost
--SSLUITestCommitted.ProceedLinkOverridable/0
--SSLUITestTransientAndCommitted.MarkBlobAsNonSecure/0
--SSLUITestTransientAndCommitted.MarkBlobAsNonSecure/1
 -SSLUITestTransientAndCommitted.TestHTTPSOCSPOk/0
 -SSLUITestTransientAndCommitted.TestHTTPSOCSPOk/1
 -SSLUITestTransientAndCommitted.TestHTTPSOCSPRevoked/1
 -SSLUITestTransientAndCommitted.TestHTTPSOCSPRevoked/0
--SSLUIWorkerFetchTest.TestUnsafeContentsInWorkerWithUserException/0
 -SubresourceFilterBrowserTest.FailedProvisionalLoadInMainframe
 -SuperfishSSLUITest.NoSuperfishRecorded
 -SuperfishSSLUITest.SuperfishInterstitial
@@ -215,26 +199,7 @@
 -TaskManagerUtilityProcessBrowserTest.UtilityJSHeapMemory
 -TtsApiTest.NetworkSpeechEngine
 -V4SafeBrowsingServiceTest.Prefetch
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsEmitsGatheringStateChange
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsGetStatsCallback
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsGetStatsPromise
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerEcdsa
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerRsa
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerEcdsa
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerRsa
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsWithClonedCertificateEcdsa
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsWithClonedCertificateRsa
--WebRtcDisableEncryptionFlagBrowserTest.VerifyEncryption
--WebRtcFromWebAccessibleResourceTest.GetUserMediaInWebAccessibleResourceFail
 -WebRtcFromWebAccessibleResourceTest.GetUserMediaInWebAccessibleResourceSuccess
--WebRtcRtpBrowserTest.AddAndRemoveTracksWithIndividualStreams
--WebRtcRtpBrowserTest.AddAndRemoveTracksWithoutStream
--WebRtcRtpBrowserTest.AddAndRemoveTracksWithSharedStream
--WebRtcRtpBrowserTest.GetReceivers
--WebRtcRtpBrowserTest.GetReceiversSetRemoteDescription
--WebRtcRtpBrowserTest.GetSenders
--WebRtcRtpBrowserTest.SwitchRemoteStreamAndBackAgain
--WebRtcRtpBrowserTest.SwitchRemoteStreamWithoutWaitingForPromisesToResolve
 # This test is flaky.
 -WebRtcRtpBrowserTest.TrackAddedToSecondStream
 -WebRtcRtpBrowserTest.TrackSwitchingStream
@@ -262,8 +227,6 @@
 -WebViewTests/WebViewTest.DownloadPermission/1
 -WebViewTests/WebViewTest.OpenURLFromTab_CurrentTab_Succeed/0
 -WebViewTests/WebViewTest.OpenURLFromTab_CurrentTab_Succeed/1
--WebViewTests/WebViewTest.Shim_TestLoadStartLoadRedirect/0
--WebViewTests/WebViewTest.Shim_TestLoadStartLoadRedirect/1
 -WebViewTests/WebViewTest.Shim_TestNavigationToExternalProtocol/0
 -WebViewTests/WebViewTest.Shim_TestNavigationToExternalProtocol/1
 -WebViewTests/WebViewTest.StoragePersistence/0
@@ -384,10 +347,10 @@
 # Added in r519342.
 -PreviewsNoScriptBrowserTest.NoScriptPreviewsEnabledHttpRedirectToHttps
 
-# crbug.com/751738 Service worker subresource loader doesn't yet support request bodies.
-# crbug.com/778821 Null response body is given to NavigationURLLoaderDelegate::OnResponseStarted() as parameter.
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsVP8
--WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsVP9
+# crbug.com/756642 Need to add support for URL blacklist.
+-PolicyTest.FileURLBlacklist
+-PolicyTest.URLBlacklist
+-PolicyTest.URLBlacklistSubresources
 
 # crbug.com/778814 Null NavigationData is given to NavigationURLLoaderDelegate::OnResponseStarted() as parameter.
 -ChromeResourceDispatcherHostDelegateBrowserTest.NavigationDataProcessed
@@ -672,9 +635,6 @@
 -ErrorPageTest.SniffSmallHttpErrorResponseAsDownload
 -ErrorPageTest.StaleCacheStatus
 
-# Likely started to fail after around r519412.
--ErrorPageNavigationCorrectionsFailTest.FetchCorrectionsFails
-
 # Switch test from using a net::URLRequestFileJob that adds load timing to
 # to using a test URLLoaderFactory via SetNetworkFactoryForTesting.
 -LoadTimingBrowserTest.Basic
@@ -734,16 +694,11 @@
 -PrerenderBrowserTest.FirstContentfulPaintTimingNoCommit
 -PrerenderBrowserTest.FirstContentfulPaintTimingReuse
 -PrerenderBrowserTest.PrerenderBeforeUnload
--PrerenderBrowserTest.PrerenderCancelMainFrameRedirectUnsupportedScheme
 -PrerenderBrowserTest.PrerenderCancelSubresourceRedirectUnsupportedScheme
 -PrerenderBrowserTest.PrerenderCancelSubresourceUnsupportedScheme
--PrerenderBrowserTest.PrerenderCrx
 -PrerenderBrowserTest.PrerenderDeferredImage
 -PrerenderBrowserTest.PrerenderDeferredImageAfterRedirect
 -PrerenderBrowserTest.PrerenderDeferredSynchronousXHR
--PrerenderBrowserTest.PrerenderDownloadClientRedirect
--PrerenderBrowserTest.PrerenderDownloadIframe
--PrerenderBrowserTest.PrerenderDownloadLocation
 -PrerenderBrowserTest.PrerenderLocationReplaceGWSHistograms
 -PrerenderBrowserTest.PrerenderNoCommitNoSwap
 -PrerenderBrowserTest.PrerenderNoCommitNoSwap2
diff --git a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
index d49ee817..c8f403d 100644
--- a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
@@ -16,6 +16,7 @@
 -ServiceWorkerVersionBrowserV8CacheTest.Restart
 
 # http://crbug.com/721398
+-ClearSiteDataThrottleBrowserTest.CacheIntegrationTest
 -ClearSiteDataThrottleBrowserTest.CookiesIntegrationTest
 -ClearSiteDataThrottleBrowserTest.Credentials
 -ClearSiteDataThrottleBrowserTest.CredentialsOnRedirect
@@ -132,3 +133,7 @@
 -CrossSiteDocumentBlockingTest.BlockDocuments
 -CrossSiteDocumentBlockingIsolatedOriginTest.BlockDocumentsFromIsolatedOrigin
 -CrossSiteDocumentBlockingTest.RangeRequest
+
+# https://crbug.com/790933
+-ServiceWorkerNavigationPreloadTest.RespondWithNavigationPreload
+-ServiceWorkerNavigationPreloadTest.RedirectAndRespondWithNavigationPreload
diff --git a/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter
index de04ede..e16d43fb 100644
--- a/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter
+++ b/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter
@@ -85,3 +85,9 @@
 
 # TODO: investigate flaky failure http://crbug.com/790683
 -SitePerProcessBrowserTest.CrossSiteIframeBlockedByXFrameOptionsOrCSP
+
+# TODO: investigate flaky failure http://crbug.com/792739
+-SitePerProcessFeaturePolicyBrowserTest.TestFeaturePolicyReplicationFromRemoteFrames
+
+# TODO: investigate flaky failure http://crbug.com/792740
+-IsolatedOriginTest.ProcessLimit
diff --git a/testing/buildbot/filters/site-per-process.content_browsertests.filter b/testing/buildbot/filters/site-per-process.content_browsertests.filter
index c18b6da..1aa5bfe 100644
--- a/testing/buildbot/filters/site-per-process.content_browsertests.filter
+++ b/testing/buildbot/filters/site-per-process.content_browsertests.filter
@@ -1,2 +1,6 @@
 # crbug.com/417518: Get tests working with --site-per-process
 -NavigationControllerBrowserTest.ReloadOriginalRequest
+
+# Untriaged.
+-ResourceDispatcherHostBrowserTest.CookieSameSiteStrictOpenNewNamedWindowTwice
+
diff --git a/testing/buildbot/filters/viz.content_browsertests.filter b/testing/buildbot/filters/viz.content_browsertests.filter
index de04ede..e16d43fb 100644
--- a/testing/buildbot/filters/viz.content_browsertests.filter
+++ b/testing/buildbot/filters/viz.content_browsertests.filter
@@ -85,3 +85,9 @@
 
 # TODO: investigate flaky failure http://crbug.com/790683
 -SitePerProcessBrowserTest.CrossSiteIframeBlockedByXFrameOptionsOrCSP
+
+# TODO: investigate flaky failure http://crbug.com/792739
+-SitePerProcessFeaturePolicyBrowserTest.TestFeaturePolicyReplicationFromRemoteFrames
+
+# TODO: investigate flaky failure http://crbug.com/792740
+-IsolatedOriginTest.ProcessLimit
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index dbef7873..365e2f85 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -97,6 +97,21 @@
           'shards': 20,
         },
       },
+      'Linux ChromiumOS Tests (dbg)(1)': {
+        'swarming': {
+          'shards': 20,
+        },
+      },
+      'linux-chromeos-dbg': {
+        'swarming': {
+          'shards': 20,
+        },
+      },
+      'linux-chromeos-rel': {
+        'swarming': {
+          'shards': 5,
+        },
+      },
       'Linux Tests': {
         'swarming': {
           'shards': 5,
@@ -112,6 +127,10 @@
       'Lollipop Tablet Tester',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these only run on "Linux Tests".
       'Cast Audio Linux',
       'Cast Linux',
@@ -171,6 +190,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.mac, unclear why these aren't run on "Mac10.12 Tests".
       'Mac10.12 Tests',
     ],
@@ -185,6 +208,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.mac, unclear why these aren't run on "Mac10.12 Tests".
       'Mac10.12 Tests',
     ],
@@ -246,6 +273,10 @@
   },
   'cast_unittests': {
     'remove_from': [
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # Unclear why these largely aren't run on Android.
       # TODO(kbr): why are the cast unit tests not run on the Cast bots?!
       'Cast Audio Linux',
@@ -282,6 +313,12 @@
         },
       },
     },
+    'remove_from': [
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
+    ],
   },
   'checkbins': {
     'remove_from': [
@@ -393,6 +430,14 @@
       },
     },
   },
+  'chromedriver_unittests': {
+    'remove_from': [
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
+    ],
+  },
   'components_background_task_scheduler_junit_tests': {
     'remove_from': [
       # On chromium.android, unclear why these aren't run on all bots.
@@ -408,10 +453,15 @@
   },
   'components_browsertests': {
     'remove_from': [
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on the Cast bots.
       'Cast Audio Linux',
       'Cast Linux',
       'Linux Tests (dbg)(1)(32)',
+      # chromium.win
       'Win7 Tests (dbg)(1)',
     ],
     'modifications': {
@@ -500,6 +550,21 @@
           'shards': 6,
         },
       },
+      'Linux ChromiumOS Tests (dbg)(1)': {
+        'swarming': {
+          'shards': 2,
+        },
+      },
+      'linux-chromeos-dbg': {
+        'swarming': {
+          'shards': 2,
+        },
+      },
+      'linux-chromeos-rel': {
+        'swarming': {
+          'shards': 2,
+        },
+      },
       'Lollipop Phone Tester': {
         'swarming': {
           'hard_timeout': 1800,
@@ -758,6 +823,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
@@ -899,6 +968,21 @@
           'shards': 3,
         },
       },
+      'Linux ChromiumOS Tests (dbg)(1)': {
+        'swarming': {
+          'shards': 3,
+        },
+      },
+      'linux-chromeos-dbg': {
+        'swarming': {
+          'shards': 3,
+        },
+      },
+      'linux-chromeos-rel': {
+        'swarming': {
+          'shards': 3,
+        },
+      },
       # Unclear why this isn't swarmed.
       'Mac10.10 Tests': {
         'swarming': {
@@ -998,6 +1082,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
     ],
   },
   'media_blink_unittests': {
@@ -1024,6 +1112,8 @@
   'media_service_unittests': {
     'remove_from': [
       'Linux Tests (dbg)(1)(32)',
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
     ],
   },
   'media_unittests': {
@@ -1098,6 +1188,10 @@
       'Marshmallow 64 bit Tester',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
@@ -1119,6 +1213,10 @@
       'Marshmallow 64 bit Tester',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
@@ -1140,6 +1238,10 @@
       'Marshmallow 64 bit Tester',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
@@ -1161,6 +1263,10 @@
       'Marshmallow 64 bit Tester',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
@@ -1243,6 +1349,13 @@
       },
     },
   },
+  'printing_unittests': {
+    'remove_from': [
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+    ],
+  },
   'remoting_unittests': {
     'remove_from': [
       # On chromium.android, unclear why these aren't run.
@@ -1270,6 +1383,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on 32-bit.
       'Linux Tests (dbg)(1)(32)',
     ],
@@ -1314,6 +1431,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on 32-bit.
       'Linux Tests (dbg)(1)(32)',
     ],
@@ -1351,6 +1472,21 @@
           'hard_timeout': 60,
         },
       },
+      'Linux ChromiumOS Tests (dbg)(1)': {
+        'args': [
+          '--test-launcher-print-test-stdio=always',
+        ],
+      },
+      'linux-chromeos-dbg': {
+        'args': [
+          '--test-launcher-print-test-stdio=always',
+        ],
+      },
+      'linux-chromeos-rel': {
+        'args': [
+          '--test-launcher-print-test-stdio=always',
+        ],
+      },
       'Linux Tests (dbg)(1)': {
         'args': [
           '--test-launcher-print-test-stdio=always',
@@ -1380,6 +1516,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
@@ -1490,6 +1630,10 @@
   },
   'snapshot_unittests': {
     'remove_from': [
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.win, unclear why these aren't run.
       'Win 7 Tests x64 (1)',
       'Win10 Tests x64',
@@ -1628,41 +1772,6 @@
       'Win7 Tests (dbg)(1)',
     ],
   },
-  'telemetry_unittests': {
-    'modifications': {
-      'Linux Tests': {
-        'args': [
-          '--jobs=1',
-        ],
-        'swarming': {
-          'shards': 4,
-        },
-      },
-      'Linux Tests (dbg)(1)': {
-        'args': [
-          '--jobs=1',
-        ],
-        'swarming': {
-          'shards': 4,
-        },
-      },
-      'Linux Tests (dbg)(1)(32)': {
-        'args': [
-          '--jobs=1',
-        ],
-        'swarming': {
-          'shards': 4,
-        },
-      },
-      # TODO(kbr): this looks like an accident while removing parallelism from
-      # telemetry_perf_unittests.
-      'Mac10.12 Tests': {
-        'args': [
-          '--jobs=1',
-        ],
-      },
-    },
-  },
   'traffic_annotation_auditor_unittests': {
     'modifications': {
       'Linux Tests': {
@@ -1979,6 +2088,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these only run on "Linux Tests".
       'Cast Audio Linux',
       'Cast Linux',
@@ -2046,6 +2159,10 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
+      # chromium.chromiumos
+      'Linux ChromiumOS Tests (dbg)(1)',
+      'linux-chromeos-dbg',
+      'linux-chromeos-rel',
       # On chromium.linux, unclear why these only run on "Linux Tests".
       'Cast Audio Linux',
       'Cast Linux',
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 2271dea0..03dbaa6b 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -323,8 +323,11 @@
     'metrics_python_tests': {},
     'telemetry_gpu_unittests': {},
     'telemetry_unittests': {
+      'args': [
+        '--jobs=1',
+      ],
       'swarming': {
-        'shards': 2,
+        'shards': 4,
       },
     },
     'webkit_layout_tests': {
@@ -380,6 +383,131 @@
     'snapshot_unittests': {},
   },
 
+  'linux_chromeos_rel_isolated_scripts': {
+    'telemetry_perf_unittests': {
+      'args': [
+        '--browser=exact',
+        '--browser-executable=./test_chrome',
+        '--xvfb',
+        '--skip=benchmarks.benchmark_smoke_unittest.BenchmarkSmokeTest.v8.runtime_stats.top_25',
+        '--skip=scripts_smoke_unittest.ScriptsSmokeTest.testRunTelemetryBenchmarkAsGoogletest',
+      ],
+      'swarming': {
+        'hard_timeout': 960,
+        'shards': 12,
+      },
+    },
+    'telemetry_unittests': {
+      'args': [
+        '--browser=exact',
+        '--browser-executable=./test_chrome',
+        '--jobs=1',
+        '--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForElement',
+        '--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForElementWithWrongText',
+        '--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForJavaScriptCondition',
+        '--skip=telemetry.internal.actions.key_event_unittest.KeyPressActionTest.testPressEndAndHome',
+        '--skip=telemetry.page.page_run_end_to_end_unittest.ActualPageRunEndToEndTests.testTrafficSettings',
+      ],
+      'swarming': {
+        'shards': 4,
+      },
+    },
+  },
+
+  'linux_chromeos_rel_specific_gtests': {
+    'angle_unittests': {},
+    'ash_unittests-mash': {
+      'test': 'ash_unittests',
+      'override_isolate_target': 'ash_unittests',
+      'args': [
+        '--mash',
+        '--test-launcher-filter-file=../../testing/buildbot/filters/ash_unittests_mash.filter',
+      ],
+    },
+    'ash_unittests-mus': {
+      'test': 'ash_unittests',
+      'override_isolate_target': 'ash_unittests',
+      'args': [
+        '--mus',
+        '--test-launcher-filter-file=../../testing/buildbot/filters/ash_unittests_mus.filter',
+      ],
+    },
+    'chromevox_tests': {},
+    'exo_unittests': {},
+    'gl_unittests_ozone': {},
+    'mash_browser_tests': {
+      'test': 'browser_tests',
+      'args': [
+        '--mash',
+        '--override-use-software-gl-for-tests',
+        '--test-launcher-filter-file=../../testing/buildbot/filters/mash.browser_tests.filter',
+      ],
+      'swarming': {
+        'hard_timeout': 1800,
+        'shards': 5,
+      },
+    },
+    'mash_unittests': {},
+    'mus_browser_tests': {
+      'test': 'browser_tests',
+      'args': [
+        '--mus',
+        '--ozone-platform=headless',
+        '--override-use-software-gl-for-tests',
+      ],
+      'swarming': {
+        'hard_timeout': 1500,
+        'shards': 5,
+      },
+    },
+    'content_browsertests --mus': {
+      'test': 'content_browsertests',
+      'override_isolate_target': 'content_browsertests',
+      'args': [
+        '--mus',
+        '--test-launcher-filter-file=../../testing/buildbot/filters/mus.content_browsertests.filter',
+      ],
+      'swarming': {
+        'shards': 2,
+      },
+    },
+    'ozone_gl_unittests': {
+      'args': [
+        '--ozone-platform=headless',
+      ],
+    },
+    'ozone_unittests': {},
+    'views_mus_unittests': {},
+    'views_mus_interactive_ui_tests': {},
+    'viz_content_browsertests': {
+      'test': 'content_browsertests',
+      'args': [
+         '--enable-viz',
+         '--ozone-platform=headless',
+         '--override-use-software-gl-for-tests',
+         '--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_browsertests.filter',
+      ],
+      'swarming': {
+        'shards': 2,
+      },
+    },
+    'wayland_client_perftests': {},
+  },
+
+  'linux_chromeos_specific_gtests': {
+    'app_list_presenter_unittests': {},
+    'app_list_unittests': {},
+    'app_shell_unittests': {},
+    'ash_content_unittests': {},
+    'ash_unittests': {},
+    'aura_unittests': {},
+    'chromeos_components_unittests': {},
+    'chromeos_unittests': {},
+    'nacl_helper_nonsfi_unittests': {},
+    'ui_arc_unittests': {},
+    'ui_chromeos_unittests': {},
+  },
+
   'linux_flavor_specific_chromium_gtests': {
     # Android, Chrome OS and Linux
     'sandbox_linux_unittests': {},
@@ -420,6 +548,16 @@
       'test': 'unit_tests',
     },
     'traffic_annotation_auditor_unittests': {},
+    'viz_content_browsertests': {
+      'swarming': {
+        'shards': 2,
+      },
+      'test': 'content_browsertests',
+      'args': [
+         '--enable-viz',
+         '--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_browsertests.filter'
+      ],
+    },
   },
 
   'linux_specific_chromium_isolated_scripts': {
@@ -509,19 +647,6 @@
     },
   },
 
-  'viz_gtests': {
-    'viz_content_browsertests': {
-      'args': [
-        '--enable-viz',
-        '--test-launcher-filter-file=../../testing/buildbot/filters/viz.content_browsertests.filter'
-      ],
-      'swarming': {
-        'shards': 2,
-      },
-      'test': 'content_browsertests',
-    },
-  },
-
   'vr_platform_specific_chromium_gtests': {
     # Only run on platforms that intend to support WebVR in the near
     # future.
@@ -632,7 +757,43 @@
     'non_android_and_cast_chromium_gtests',
     'non_android_and_cast_and_chromeos_chromium_gtests',
     'non_mac_chromium_gtests',
-    'viz_gtests',
+  ],
+
+  'linux_chromeos_dbg_gtests': [
+    # This is:
+    #   linux_chromium_gtests
+    #   - linux_specific_chromium_gtests
+    #   - non_android_and_cast_and_chromeos_chromium_gtests
+    #   + linux_chromeos_specific_gtests
+    'aura_gtests',
+    'chromium_gtests',
+    'chromium_gtests_for_devices_with_graphical_output',
+    'linux_and_android_specific_chromium_gtests',
+    'linux_and_chromeos_specific_chromium_gtests',
+    'linux_and_mac_specific_chromium_gtests',
+    'linux_chromeos_specific_gtests',
+    'linux_flavor_specific_chromium_gtests',
+    'non_android_chromium_gtests',
+    'non_android_and_cast_chromium_gtests',
+    'non_mac_chromium_gtests',
+  ],
+
+  'linux_chromeos_rel_gtests': [
+    # This is:
+    #   linux_chromeos_dbg_gtests
+    #   + linux_chromeos_rel_specific_gtests
+    'aura_gtests',
+    'chromium_gtests',
+    'chromium_gtests_for_devices_with_graphical_output',
+    'linux_and_android_specific_chromium_gtests',
+    'linux_and_chromeos_specific_chromium_gtests',
+    'linux_and_mac_specific_chromium_gtests',
+    'linux_chromeos_specific_gtests',
+    'linux_chromeos_rel_specific_gtests',
+    'linux_flavor_specific_chromium_gtests',
+    'non_android_chromium_gtests',
+    'non_android_and_cast_chromium_gtests',
+    'non_mac_chromium_gtests',
   ],
 
   'chromium_linux_isolated_scripts': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 27f88d6..fe781c2 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -197,7 +197,6 @@
         ],
         'test_suites': {
           'gtest_tests': 'chromium_android_gtests',
-          'isolated_scripts': 'telemetry_perf_unittests_isolated_scripts',
           'junit_tests': 'chromium_junit_tests',
         },
         'swarming': {
@@ -326,6 +325,50 @@
     },
   },
   {
+    'name': 'chromium.chrome',
+    'machines': {
+    },
+  },
+  {
+    'name': 'chromium.chromiumos',
+    'machines': {
+      'Linux ChromiumOS Builder': {
+        'additional_compile_targets': [
+          'All',
+        ],
+      },
+      'Linux ChromiumOS Tests (dbg)(1)': {
+        'test_suites': {
+          'gtest_tests': 'linux_chromeos_dbg_gtests',
+        },
+      },
+      'chromeos-amd64-generic-rel': {
+        'additional_compile_targets': [
+          'chromiumos_preflight',
+        ],
+      },
+      'chromeos-daisy-rel': {
+        'additional_compile_targets': [
+          'chromiumos_preflight',
+        ],
+      },
+      'linux-chromeos-dbg': {
+        'test_suites': {
+          'gtest_tests': 'linux_chromeos_dbg_gtests',
+        },
+      },
+      'linux-chromeos-rel': {
+        'additional_compile_targets': [
+          'All',
+        ],
+        'test_suites': {
+          'gtest_tests': 'linux_chromeos_rel_gtests',
+          'isolated_scripts': 'linux_chromeos_rel_isolated_scripts',
+        },
+      },
+    },
+  },
+  {
     'name': 'chromium.linux',
     'machines': {
       'Fuchsia ARM64': {
@@ -419,6 +462,16 @@
     },
   },
   {
+    'name': 'chromium.lkgr',
+    'machines': {
+      'ASAN Release': {
+        'additional_compile_targets': [
+          'chromium_builder_asan',
+        ],
+      },
+    },
+  },
+  {
     'name': 'chromium.mac',
     'machines': {
       'Mac Builder': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 6c56334..dae133ac 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2351,8 +2351,7 @@
                 {
                     "name": "Enabled",
                     "enable_features": [
-                        "OfflinePagesAsyncDownload",
-                        "OfflinePagesSvelte"
+                        "OfflinePagesAsyncDownload"
                     ]
                 }
             ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 9389b02b..f67475d 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -7,7 +7,7 @@
 # We currently write back whitespace-collapsed strings to LayoutText, causing
 # the following failures. Once we can paint inlines directly from fragment tree,
 # we can stop the writeback.
-crbug.com/714962 editing/text-iterator/findString-restarts-at-last-position.html [ Failure ]
+crbug.com/714962 editing/text-iterator/findString-restarts-at-last-position.html [ Failure Pass ]
 
 # Editing does not completely work with LayoutNG yet.
 
@@ -35,13 +35,13 @@
 crbug.com/591099 fast/text/whitespace/028.html [ Failure ]
 
 # Fix only in NGPaint.
-crbug.com/591099 fast/text/justify-ideograph-leading-expansion.html [ Failure ]
-crbug.com/591099 fast/text/justify-nbsp.html [ Failure ]
-crbug.com/591099 fast/text/justify-vertical.html [ Failure ]
+crbug.com/591099 fast/text/justify-ideograph-leading-expansion.html [ Failure Pass ]
+crbug.com/591099 fast/text/justify-nbsp.html [ Failure Pass ]
+crbug.com/591099 fast/text/justify-vertical.html [ Failure Pass ]
 crbug.com/591099 fast/text/word-space.html [ Failure ]
 
 # Glyph overflow.
-crbug.com/591099 fast/text/shadow-no-blur.html [ Failure ]
+crbug.com/591099 fast/text/shadow-no-blur.html [ Failure Pass ]
 
 # Improved shaping we can rebase once we switch.
 crbug.com/591099 fast/text/font-initial.html [ Failure ]
@@ -65,9 +65,9 @@
 crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vlr-002.xht [ Pass ]
 crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vlr-005.xht [ Pass ]
 crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vlr-006.xht [ Pass ]
-crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-001.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-001.xht [ Failure Pass ]
 crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-002.xht [ Pass ]
-crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-005.xht [ Pass ]
+crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-005.xht [ Failure Pass ]
 crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-006.xht [ Pass ]
 crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-vlr-in-htb-001.xht [ Pass ]
 crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-vlr-in-htb-002.xht [ Pass ]
@@ -101,7 +101,7 @@
 crbug.com/591099 accessibility/image-link-inline-cont.html [ Failure ]
 crbug.com/591099 accessibility/image-map1.html [ Failure ]
 crbug.com/591099 accessibility/img-fallsback-to-title.html [ Failure ]
-crbug.com/591099 accessibility/inline-text-bidi-bounds-for-range.html [ Crash ]
+crbug.com/591099 accessibility/inline-text-bidi-bounds-for-range.html [ Crash Failure ]
 crbug.com/591099 accessibility/inline-text-bounds-for-range.html [ Failure ]
 crbug.com/591099 accessibility/inline-text-box-next-on-line.html [ Failure ]
 crbug.com/591099 accessibility/inline-text-change-style.html [ Failure ]
@@ -118,10 +118,10 @@
 crbug.com/591099 accessibility/removed-continuation-element-causes-crash.html [ Failure ]
 crbug.com/591099 accessibility/role-attribute.html [ Crash ]
 crbug.com/591099 accessibility/scroll-div-horiz-sends-notification.html [ Failure ]
-crbug.com/591099 accessibility/set-selection-whitespace.html [ Failure ]
+crbug.com/591099 accessibility/set-selection-whitespace.html [ Failure Pass ]
 crbug.com/591099 accessibility/slider-thumb-bounds.html [ Crash ]
 crbug.com/591099 accessibility/table-cells.html [ Failure Pass ]
-crbug.com/591099 accessibility/table-header-column-row.html [ Timeout ]
+crbug.com/591099 accessibility/table-header-column-row.html [ Failure Timeout ]
 crbug.com/591099 accessibility/table-one-cell.html [ Failure ]
 crbug.com/591099 accessibility/textarea-caret-position.html [ Failure Timeout ]
 crbug.com/591099 accessibility/textarea-selection.html [ Failure ]
@@ -182,7 +182,7 @@
 crbug.com/591099 compositing/geometry/clip-inside.html [ Failure ]
 crbug.com/591099 compositing/geometry/clip-with-shadow.html [ Failure ]
 crbug.com/591099 compositing/geometry/clip.html [ Failure ]
-crbug.com/591099 compositing/geometry/clipping-foreground.html [ Failure ]
+crbug.com/591099 compositing/geometry/clipping-foreground.html [ Crash Failure ]
 crbug.com/591099 compositing/geometry/composited-html-size.html [ Failure ]
 crbug.com/591099 compositing/geometry/composited-in-columns.html [ Failure ]
 crbug.com/591099 compositing/geometry/fixed-in-composited.html [ Failure ]
@@ -192,7 +192,7 @@
 crbug.com/591099 compositing/geometry/fixed-position-transform-composited-page-scale.html [ Failure ]
 crbug.com/591099 compositing/geometry/fixed-position.html [ Failure ]
 crbug.com/591099 compositing/geometry/flipped-writing-mode.html [ Failure ]
-crbug.com/591099 compositing/geometry/foreground-layer.html [ Failure ]
+crbug.com/591099 compositing/geometry/foreground-layer.html [ Crash Failure ]
 crbug.com/591099 compositing/geometry/horizontal-scroll-composited.html [ Failure ]
 crbug.com/591099 compositing/geometry/layer-due-to-layer-children-deep-switch.html [ Failure ]
 crbug.com/591099 compositing/geometry/layer-due-to-layer-children-deep.html [ Failure ]
@@ -206,7 +206,7 @@
 crbug.com/591099 compositing/geometry/outline-change.html [ Failure ]
 crbug.com/591099 compositing/geometry/partial-layout-update.html [ Failure ]
 crbug.com/591099 compositing/geometry/preserve-3d-switching.html [ Failure ]
-crbug.com/591099 compositing/geometry/repaint-foreground-layer.html [ Failure ]
+crbug.com/591099 compositing/geometry/repaint-foreground-layer.html [ Crash Failure ]
 crbug.com/591099 compositing/geometry/root-layer-update.html [ Failure ]
 crbug.com/591099 compositing/geometry/tall-page-composited.html [ Failure ]
 crbug.com/591099 compositing/geometry/transformed-abs-position-inside-composited.html [ Failure ]
@@ -221,7 +221,7 @@
 crbug.com/591099 compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-outer.html [ Failure ]
 crbug.com/591099 compositing/gestures/gesture-tapHighlight-2-iframe.html [ Failure ]
 crbug.com/591099 compositing/gestures/gesture-tapHighlight-img-and-text-2.html [ Failure ]
-crbug.com/591099 compositing/gestures/gesture-tapHighlight-img-transformed.html [ Failure ]
+crbug.com/591099 compositing/gestures/gesture-tapHighlight-img-transformed.html [ Failure Pass ]
 crbug.com/591099 compositing/iframes/become-composited-nested-iframes.html [ Failure ]
 crbug.com/591099 compositing/iframes/become-overlapped-iframe.html [ Failure ]
 crbug.com/591099 compositing/iframes/composited-iframe-alignment.html [ Failure ]
@@ -317,7 +317,7 @@
 crbug.com/591099 compositing/overflow/clip-parent-reset.html [ Failure ]
 crbug.com/591099 compositing/overflow/clipping-ancestor-with-accelerated-scrolling-ancestor.html [ Failure ]
 crbug.com/591099 compositing/overflow/composited-layer-under-border-radius-under-composited-layer.html [ Failure ]
-crbug.com/591099 compositing/overflow/composited-nested-sticky-left.html [ Failure ]
+crbug.com/591099 compositing/overflow/composited-nested-sticky-left.html [ Failure Pass ]
 crbug.com/591099 compositing/overflow/composited-scrolling-paint-phases.html [ Failure ]
 crbug.com/591099 compositing/overflow/content-gains-scrollbars.html [ Failure ]
 crbug.com/591099 compositing/overflow/content-loses-scrollbars.html [ Failure ]
@@ -582,7 +582,7 @@
 crbug.com/591099 css2.1/20110323/border-conflict-style-079.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/border-conflict-style-088.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/border-spacing-applies-to-015.htm [ Failure ]
-crbug.com/591099 css2.1/20110323/c541-word-sp-001.htm [ Failure ]
+crbug.com/591099 css2.1/20110323/c541-word-sp-001.htm [ Failure Pass ]
 crbug.com/591099 css2.1/20110323/c543-txt-decor-000.html [ Failure ]
 crbug.com/591099 css2.1/20110323/height-width-inline-table-001.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/height-width-table-001.htm [ Failure ]
@@ -2014,16 +2014,16 @@
 crbug.com/591099 editing/deleting/delete-line-015.html [ Failure ]
 crbug.com/591099 editing/deleting/delete-line-016.html [ Failure ]
 crbug.com/591099 editing/deleting/delete-line-017.html [ Failure ]
-crbug.com/591099 editing/deleting/delete_block_merge_contents_1.html [ Failure ]
+crbug.com/591099 editing/deleting/delete_block_merge_contents_1.html [ Failure Pass ]
 crbug.com/591099 editing/deleting/merge-different-styles.html [ Failure ]
 crbug.com/591099 editing/deleting/merge-endOfParagraph.html [ Failure ]
 crbug.com/591099 editing/deleting/merge-no-br.html [ Crash Failure ]
-crbug.com/591099 editing/deleting/merge-paragraph-from-address.html [ Failure Timeout ]
-crbug.com/591099 editing/deleting/merge-paragraph-from-listing.html [ Failure ]
-crbug.com/591099 editing/deleting/merge-paragraph-into-blockquote.html [ Failure ]
-crbug.com/591099 editing/deleting/merge-paragraph-into-pre.html [ Failure ]
+crbug.com/591099 editing/deleting/merge-paragraph-from-address.html [ Failure Pass Timeout ]
+crbug.com/591099 editing/deleting/merge-paragraph-from-listing.html [ Failure Pass ]
+crbug.com/591099 editing/deleting/merge-paragraph-into-blockquote.html [ Failure Pass ]
+crbug.com/591099 editing/deleting/merge-paragraph-into-pre.html [ Failure Pass ]
 crbug.com/591099 editing/deleting/merge-whitespace-pre.html [ Failure ]
-crbug.com/591099 editing/deleting/merge_paragraph_into_h1.html [ Failure ]
+crbug.com/591099 editing/deleting/merge_paragraph_into_h1.html [ Failure Pass ]
 crbug.com/591099 editing/deleting/move-nodes-001.html [ Failure ]
 crbug.com/591099 editing/deleting/table-cells.html [ Failure ]
 crbug.com/591099 editing/deleting/transpose-empty.html [ Failure ]
@@ -2046,12 +2046,12 @@
 crbug.com/591099 editing/execCommand/insertImage.html [ Failure ]
 crbug.com/591099 editing/execCommand/outdent-collapse-table-crash-2.html [ Crash Pass ]
 crbug.com/591099 editing/execCommand/outdent-multiparagraph-list.html [ Failure ]
-crbug.com/591099 editing/execCommand/outdent-selection.html [ Crash Failure ]
+crbug.com/591099 editing/execCommand/outdent-selection.html [ Crash Failure Pass ]
 crbug.com/591099 editing/execCommand/query-command-state.html [ Timeout ]
 crbug.com/591099 editing/execCommand/query-format-block.html [ Pass Timeout ]
 crbug.com/591099 editing/execCommand/queryCommandState-02.html [ Failure ]
 crbug.com/591099 editing/execCommand/remove-list-from-range-selection.html [ Failure ]
-crbug.com/591099 editing/execCommand/selection-after-insert-list.html [ Failure ]
+crbug.com/591099 editing/execCommand/selection-after-insert-list.html [ Failure Pass ]
 crbug.com/591099 editing/input/caret-at-the-edge-of-contenteditable.html [ Failure ]
 crbug.com/591099 editing/input/caret-at-the-edge-of-input.html [ Failure ]
 crbug.com/591099 editing/input/caret-read-only-after-editable.html [ Failure ]
@@ -2106,16 +2106,16 @@
 crbug.com/591099 editing/pasteboard/7955.html [ Failure ]
 crbug.com/591099 editing/pasteboard/bad-placeholder.html [ Failure ]
 crbug.com/591099 editing/pasteboard/copy-in-password-field.html [ Failure ]
-crbug.com/591099 editing/pasteboard/copy-paste-white-space.html [ Crash ]
+crbug.com/591099 editing/pasteboard/copy-paste-white-space.html [ Crash Failure ]
 crbug.com/591099 editing/pasteboard/copy-standalone-image.html [ Failure ]
-crbug.com/591099 editing/pasteboard/drag-and-drop-image-contenteditable.html [ Timeout ]
-crbug.com/591099 editing/pasteboard/drag-and-drop-inputimage-contenteditable.html [ Timeout ]
-crbug.com/591099 editing/pasteboard/drag-and-drop-objectimage-contenteditable.html [ Timeout ]
-crbug.com/591099 editing/pasteboard/drag-drop-dead-frame.html [ Timeout ]
-crbug.com/591099 editing/pasteboard/drag-drop-modifies-page.html [ Failure ]
+crbug.com/591099 editing/pasteboard/drag-and-drop-image-contenteditable.html [ Pass Timeout ]
+crbug.com/591099 editing/pasteboard/drag-and-drop-inputimage-contenteditable.html [ Pass Timeout ]
+crbug.com/591099 editing/pasteboard/drag-and-drop-objectimage-contenteditable.html [ Pass Timeout ]
+crbug.com/591099 editing/pasteboard/drag-drop-dead-frame.html [ Pass Timeout ]
+crbug.com/591099 editing/pasteboard/drag-drop-modifies-page.html [ Failure Pass ]
 crbug.com/591099 editing/pasteboard/drag-drop-url-text.html [ Failure ]
-crbug.com/591099 editing/pasteboard/drag-drop-url-with-style.html [ Failure ]
-crbug.com/591099 editing/pasteboard/drag-image-in-about-blank-frame.html [ Failure ]
+crbug.com/591099 editing/pasteboard/drag-drop-url-with-style.html [ Failure Pass ]
+crbug.com/591099 editing/pasteboard/drag-image-in-about-blank-frame.html [ Failure Pass ]
 crbug.com/591099 editing/pasteboard/drag-image-to-contenteditable-in-iframe.html [ Failure ]
 crbug.com/591099 editing/pasteboard/drag-list-item.html [ Failure ]
 crbug.com/591099 editing/pasteboard/drag-selected-image-to-contenteditable.html [ Failure ]
@@ -2127,7 +2127,7 @@
 crbug.com/591099 editing/pasteboard/input-field-1.html [ Failure ]
 crbug.com/591099 editing/pasteboard/merge-start-blockquote.html [ Failure ]
 crbug.com/591099 editing/pasteboard/merge-start-list.html [ Failure ]
-crbug.com/591099 editing/pasteboard/mixed_editability.html [ Failure ]
+crbug.com/591099 editing/pasteboard/mixed_editability.html [ Failure Pass ]
 crbug.com/591099 editing/pasteboard/paste-blockquote-after-blockquote.html [ Failure ]
 crbug.com/591099 editing/pasteboard/paste-blockquote-into-blockquote-4.html [ Failure ]
 crbug.com/591099 editing/pasteboard/paste-line-endings-001.html [ Failure ]
@@ -2139,14 +2139,14 @@
 crbug.com/591099 editing/pasteboard/paste-pre-001.html [ Failure ]
 crbug.com/591099 editing/pasteboard/paste-text-016.html [ Failure ]
 crbug.com/591099 editing/pasteboard/paste-text-at-tabspan-003.html [ Failure ]
-crbug.com/591099 editing/pasteboard/paste-visible-script.html [ Failure ]
+crbug.com/591099 editing/pasteboard/paste-visible-script.html [ Failure Pass ]
 crbug.com/591099 editing/pasteboard/pasting-tabs.html [ Failure ]
 crbug.com/591099 editing/pasteboard/quirks-mode-br-1.html [ Failure ]
-crbug.com/591099 editing/pasteboard/smart-drag-drop.html [ Failure ]
-crbug.com/591099 editing/pasteboard/smart-paste-in-text-control.html [ Failure ]
-crbug.com/591099 editing/pasteboard/smart_paste.html [ Failure ]
+crbug.com/591099 editing/pasteboard/smart-drag-drop.html [ Failure Pass ]
+crbug.com/591099 editing/pasteboard/smart-paste-in-text-control.html [ Failure Pass ]
+crbug.com/591099 editing/pasteboard/smart_paste.html [ Failure Pass ]
 crbug.com/591099 editing/pasteboard/styled-element-markup.html [ Failure ]
-crbug.com/591099 editing/pasteboard/subframe-dragndrop-1.html [ Failure ]
+crbug.com/591099 editing/pasteboard/subframe-dragndrop-1.html [ Failure Pass ]
 crbug.com/591099 editing/selection/4402375.html [ Failure ]
 crbug.com/591099 editing/selection/4776665.html [ Failure ]
 crbug.com/591099 editing/selection/4960137.html [ Failure ]
@@ -2182,12 +2182,12 @@
 crbug.com/591099 editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed.html [ Failure ]
 crbug.com/591099 editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl.html [ Failure ]
 crbug.com/591099 editing/selection/dont-select-text-overflow-ellipsis-when-wrapping.html [ Failure ]
-crbug.com/591099 editing/selection/double_click_and_modify.html [ Failure ]
-crbug.com/591099 editing/selection/doubleclick-beside-cr-span.html [ Failure ]
-crbug.com/591099 editing/selection/doubleclick-whitespace.html [ Failure ]
+crbug.com/591099 editing/selection/double_click_and_modify.html [ Failure Pass ]
+crbug.com/591099 editing/selection/doubleclick-beside-cr-span.html [ Failure Timeout ]
+crbug.com/591099 editing/selection/doubleclick-whitespace.html [ Failure Pass ]
 crbug.com/591099 editing/selection/drag-in-iframe.html [ Failure ]
 crbug.com/591099 editing/selection/drag-select-1.html [ Failure ]
-crbug.com/591099 editing/selection/drag-selection-nodes.html [ Failure ]
+crbug.com/591099 editing/selection/drag-selection-nodes.html [ Failure Pass ]
 crbug.com/591099 editing/selection/drag-to-contenteditable-iframe.html [ Failure ]
 crbug.com/591099 editing/selection/drag_with_unfocused_selection.html [ Failure ]
 crbug.com/591099 editing/selection/editable-div-clear-on-keydown.html [ Failure ]
@@ -2201,9 +2201,9 @@
 crbug.com/591099 editing/selection/extend-selection-character.html [ Timeout ]
 crbug.com/591099 editing/selection/extend-selection-home-end.html [ Timeout ]
 crbug.com/591099 editing/selection/extend-selection-word.html [ Timeout ]
-crbug.com/591099 editing/selection/find-in-text-control.html [ Failure ]
+crbug.com/591099 editing/selection/find-in-text-control.html [ Failure Pass ]
 crbug.com/591099 editing/selection/focus-body.html [ Failure ]
-crbug.com/591099 editing/selection/focus_editable_html_element.html [ Timeout ]
+crbug.com/591099 editing/selection/focus_editable_html_element.html [ Pass Timeout ]
 crbug.com/591099 editing/selection/home-end.html [ Timeout ]
 crbug.com/591099 editing/selection/inactive-selection.html [ Failure ]
 crbug.com/591099 editing/selection/inline-closest-leaf-child.html [ Failure ]
@@ -2221,13 +2221,13 @@
 crbug.com/591099 editing/selection/mixed-editability-8.html [ Failure ]
 crbug.com/591099 editing/selection/mixed-editability-9.html [ Failure ]
 crbug.com/591099 editing/selection/modify_extend/extend_by_character.html [ Failure ]
-crbug.com/591099 editing/selection/modify_extend/extend_selection_enclosing_block.html [ Failure ]
+crbug.com/591099 editing/selection/modify_extend/extend_selection_enclosing_block.html [ Failure Pass ]
 crbug.com/591099 editing/selection/modify_move/move_by_sentence_boundary.html [ Failure ]
 crbug.com/591099 editing/selection/mouse/click-left-of-rtl-wrapping-text.html [ Failure ]
-crbug.com/591099 editing/selection/mouse/click-user-select-all-contenteditable.html [ Failure ]
+crbug.com/591099 editing/selection/mouse/click-user-select-all-contenteditable.html [ Failure Pass ]
 crbug.com/591099 editing/selection/mouse/click-user-select-all-textarea.html [ Failure ]
-crbug.com/591099 editing/selection/mouse/drag-user-select-all-contenteditable.html [ Failure ]
-crbug.com/591099 editing/selection/mouse/drag-user-select-all-textarea.html [ Failure ]
+crbug.com/591099 editing/selection/mouse/drag-user-select-all-contenteditable.html [ Failure Pass ]
+crbug.com/591099 editing/selection/mouse/drag-user-select-all-textarea.html [ Failure Pass ]
 crbug.com/591099 editing/selection/mouse/extend_by_word_with_base_is_end.html [ Failure ]
 crbug.com/591099 editing/selection/move-3875618-fix.html [ Failure ]
 crbug.com/591099 editing/selection/move-3875641-fix.html [ Failure ]
@@ -2240,12 +2240,12 @@
 crbug.com/591099 editing/selection/move-past-trailing-space.html [ Failure ]
 crbug.com/591099 editing/selection/paint-hyphen.html [ Failure ]
 crbug.com/591099 editing/selection/paragraph-granularity.html [ Failure ]
-crbug.com/591099 editing/selection/paragraph-with-ruby.html [ Failure ]
+crbug.com/591099 editing/selection/paragraph-with-ruby.html [ Failure Pass ]
 crbug.com/591099 editing/selection/previous-line-position.html [ Failure ]
 crbug.com/591099 editing/selection/programmatic-selection-on-mac-is-directionless.html [ Crash Timeout ]
 crbug.com/591099 editing/selection/range-between-block-and-inline.html [ Failure ]
 crbug.com/591099 editing/selection/readonly-disabled-hittest.html [ Failure ]
-crbug.com/591099 editing/selection/readonly-disabled-text-selection.html [ Failure ]
+crbug.com/591099 editing/selection/readonly-disabled-text-selection.html [ Failure Pass ]
 crbug.com/591099 editing/selection/replaced-boundaries-1.html [ Failure ]
 crbug.com/591099 editing/selection/replaced-boundaries-2.html [ Failure ]
 crbug.com/591099 editing/selection/replaced-boundaries-3.html [ Failure ]
@@ -2268,8 +2268,8 @@
 crbug.com/591099 editing/selection/select-text-overflow-ellipsis.html [ Failure ]
 crbug.com/591099 editing/selection/selectNode.html [ Failure ]
 crbug.com/591099 editing/selection/selectNodeContents.html [ Failure ]
-crbug.com/591099 editing/selection/select_all/select_all_overflow_hidden_table.html [ Failure ]
-crbug.com/591099 editing/selection/select_all/select_all_user_select_none.html [ Failure ]
+crbug.com/591099 editing/selection/select_all/select_all_overflow_hidden_table.html [ Failure Pass ]
+crbug.com/591099 editing/selection/select_all/select_all_user_select_none.html [ Failure Pass ]
 crbug.com/591099 editing/selection/selection-3748164-fix.html [ Failure ]
 crbug.com/591099 editing/selection/selection-background.html [ Failure ]
 crbug.com/591099 editing/selection/selection-button-text.html [ Failure ]
@@ -2277,13 +2277,13 @@
 crbug.com/591099 editing/selection/shift-click.html [ Failure ]
 crbug.com/591099 editing/selection/transformed-selection-rects.html [ Failure ]
 crbug.com/591099 editing/selection/triple-click-in-pre.html [ Failure ]
-crbug.com/591099 editing/selection/user-select-all-with-shift.html [ Failure ]
+crbug.com/591099 editing/selection/user-select-all-with-shift.html [ Failure Pass ]
 crbug.com/591099 editing/selection/user-select/user-select-all.html [ Failure ]
 crbug.com/591099 editing/selection/word-granularity.html [ Failure ]
 crbug.com/591099 editing/selection/wrapped-line-caret-1.html [ Failure ]
 crbug.com/591099 editing/selection/wrapped-line-caret-2.html [ Failure ]
-crbug.com/591099 editing/spelling/context_click_on_selected_misspelling.html [ Timeout ]
-crbug.com/591099 editing/spelling/context_click_select_misspelling.html [ Failure ]
+crbug.com/591099 editing/spelling/context_click_on_selected_misspelling.html [ Pass Timeout ]
+crbug.com/591099 editing/spelling/context_click_select_misspelling.html [ Failure Pass ]
 crbug.com/591099 editing/style/4916887.html [ Failure ]
 crbug.com/591099 editing/style/5065910.html [ Failure ]
 crbug.com/591099 editing/style/5084241.html [ Failure ]
@@ -2295,10 +2295,10 @@
 crbug.com/591099 editing/style/block-styles-007.html [ Failure ]
 crbug.com/591099 editing/style/font-family-with-space.html [ Failure ]
 crbug.com/591099 editing/style/highlight.html [ Failure ]
-crbug.com/591099 editing/style/justify-without-enclosing-block.xhtml [ Failure ]
-crbug.com/591099 editing/style/non-inheritable-styles.html [ Failure ]
-crbug.com/591099 editing/style/remove-underline-across-paragraph-in-bold.html [ Crash ]
-crbug.com/591099 editing/style/remove-underline-across-paragraph.html [ Crash ]
+crbug.com/591099 editing/style/justify-without-enclosing-block.xhtml [ Failure Pass ]
+crbug.com/591099 editing/style/non-inheritable-styles.html [ Failure Pass ]
+crbug.com/591099 editing/style/remove-underline-across-paragraph-in-bold.html [ Crash Failure ]
+crbug.com/591099 editing/style/remove-underline-across-paragraph.html [ Crash Failure ]
 crbug.com/591099 editing/style/table-selection.html [ Failure ]
 crbug.com/591099 editing/text-iterator/findString-start-search-after-selection.html [ Failure ]
 crbug.com/591099 editing/text-iterator/findString.html [ Pass Timeout ]
@@ -2340,24 +2340,24 @@
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/max-height-percentage-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/root-box-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/positioning/abspos-007.xht [ Failure ]
-crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-027.xht [ Failure ]
-crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-028.xht [ Failure ]
-crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-029.xht [ Failure ]
-crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-030.xht [ Failure ]
-crbug.com/591099 external/wpt/css/CSS2/positioning/positioning-float-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-027.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-028.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-029.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/CSS2/positioning/position-relative-030.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/CSS2/positioning/positioning-float-002.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/CSS2/positioning/relpos-calcs-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/positioning/relpos-calcs-005.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/text/text-decoration-applies-to-015.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/text/text-indent-012.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/text/text-indent-percent-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/CSS2/text/text-transform-capitalize-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-flex-002-inline.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-flex-002-none.html [ Failure ]
+crbug.com/591099 external/wpt/css/CSS2/text/text-transform-capitalize-003.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-flex-002-inline.html [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-flex-002-none.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-table-001-inline.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-display/display-flow-root-001.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-flexbox/anonymous-flex-item-001.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-flexbox/anonymous-flex-item-003.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-flexbox/anonymous-flex-item-006.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-flexbox/anonymous-flex-item-001.html [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-flexbox/anonymous-flex-item-003.html [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-flexbox/anonymous-flex-item-006.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-flexbox/percentage-heights-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-fonts/matching/stretch-distance-over-weight-distance.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/matching/style-ranges-over-weight-direction.html [ Pass ]
@@ -2374,7 +2374,7 @@
 crbug.com/591099 external/wpt/css/css-grid/grid-items/grid-item-containing-block-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/grid-items/grid-item-containing-block-003.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/grid-items/grid-item-containing-block-004.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-position/position-sticky-writing-modes.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-position/position-sticky-writing-modes.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-rhythm/line-height-step-basic-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-rhythm/line-height-step-boundary-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-rhythm/line-height-step-dynamic-001.html [ Failure ]
@@ -2519,13 +2519,13 @@
 crbug.com/591099 external/wpt/css/css-ui/box-sizing-009.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/outline-011.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-ui/outline-019.html [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-ui/text-overflow-002.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-ui/text-overflow-004.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-ui/text-overflow-007.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-002.html [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-004.html [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-007.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-012.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-013.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-014.html [ Crash Failure ]
-crbug.com/591099 external/wpt/css/css-ui/text-overflow-015.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-015.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-022.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-003.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-005.xht [ Pass ]
@@ -2539,7 +2539,7 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-014.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-018.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-020.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-009.xht [ Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-009.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-024.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-004.xht [ Failure ]
@@ -2548,18 +2548,18 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-006.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-008.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-lft-orthog-htb-in-vrl-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-rgt-orthog-htb-in-vrl-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-lft-orthog-htb-in-vrl-002.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-rgt-orthog-htb-in-vrl-003.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vlr-013.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-002.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-006.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-010.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-010.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-012.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/horizontal-rule-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/inline-block-alignment-006.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/inline-table-alignment-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/inline-table-alignment-004.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/inline-table-alignment-002.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/inline-table-alignment-004.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/margin-collapse-vrl-010.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-010.xht [ Failure ]
@@ -2606,9 +2606,9 @@
 crbug.com/591099 external/wpt/css/cssom-view/elementFromPoint-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/cssom-view/elementFromPoint-003.html [ Failure ]
 crbug.com/591099 external/wpt/css/cssom-view/elementFromPoint.html [ Failure ]
-crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-iframes.html [ Failure ]
+crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-iframes.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-svg.html [ Failure ]
-crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint.html [ Failure ]
+crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/geometry/interfaces.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/css/selectors/focus-within-004.html [ Failure ]
@@ -2761,11 +2761,11 @@
 crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-auto.html [ Failure ]
 crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-percentage.html [ Failure ]
 crbug.com/591099 external/wpt/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html [ Failure Timeout ]
-crbug.com/591099 external/wpt/html/semantics/embedded-content/the-area-element/area-coords.html [ Failure ]
-crbug.com/591099 external/wpt/html/semantics/embedded-content/the-area-element/area-processing.html [ Failure ]
-crbug.com/591099 external/wpt/html/semantics/embedded-content/the-area-element/area-shape.html [ Failure ]
-crbug.com/591099 external/wpt/html/semantics/embedded-content/the-img-element/usemap-casing.html [ Failure ]
-crbug.com/591099 external/wpt/html/semantics/embedded-content/the-object-element/usemap-casing.html [ Failure ]
+crbug.com/591099 external/wpt/html/semantics/embedded-content/the-area-element/area-coords.html [ Failure Pass ]
+crbug.com/591099 external/wpt/html/semantics/embedded-content/the-area-element/area-processing.html [ Failure Pass ]
+crbug.com/591099 external/wpt/html/semantics/embedded-content/the-area-element/area-shape.html [ Failure Pass ]
+crbug.com/591099 external/wpt/html/semantics/embedded-content/the-img-element/usemap-casing.html [ Failure Pass ]
+crbug.com/591099 external/wpt/html/semantics/embedded-content/the-object-element/usemap-casing.html [ Failure Pass ]
 crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html [ Failure ]
 crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-menu.html [ Failure ]
 crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-skip-no-boxes.html [ Failure ]
@@ -2964,12 +2964,12 @@
 crbug.com/591099 fast/block/float/negative-margin-on-element-avoiding-floats.html [ Failure ]
 crbug.com/591099 fast/block/float/nopaint-after-layer-destruction.html [ Failure ]
 crbug.com/591099 fast/block/float/nopaint-after-layer-destruction2.html [ Failure ]
-crbug.com/591099 fast/block/float/overhanging-float-crashes-when-sibling-becomes-formatting-context.html [ Failure ]
+crbug.com/591099 fast/block/float/overhanging-float-crashes-when-sibling-becomes-formatting-context.html [ Failure Pass ]
 crbug.com/591099 fast/block/float/overhanging-float-remove-from-fixed-position-block.html [ Failure ]
 crbug.com/591099 fast/block/float/overhanging-float-remove-from-fixed-position-block2.html [ Failure ]
 crbug.com/591099 fast/block/float/overlapping-floats-paint-hittest-order-1.html [ Failure ]
 crbug.com/591099 fast/block/float/overlapping-floats-paint-hittest-order-2.html [ Failure ]
-crbug.com/591099 fast/block/float/rubybase-children-moved-crash-2.html [ Crash ]
+crbug.com/591099 fast/block/float/rubybase-children-moved-crash-2.html [ Crash Failure ]
 crbug.com/591099 fast/block/float/selection-gap-clip-out-tiger-crash.html [ Failure ]
 crbug.com/591099 fast/block/float/trailing-float-with-columns.html [ Failure ]
 crbug.com/591099 fast/block/inflow-bottom-margin.html [ Failure ]
@@ -3143,7 +3143,7 @@
 crbug.com/591099 fast/canvas/canvas-shadow-source-in.html [ Failure ]
 crbug.com/591099 fast/canvas/canvas-transforms-during-path.html [ Failure ]
 crbug.com/591099 fast/canvas/fill-stroke-clip-reset-path.html [ Failure ]
-crbug.com/591099 fast/canvas/fillrect_gradient.html [ Failure ]
+crbug.com/591099 fast/canvas/fillrect_gradient.html [ Failure Pass ]
 crbug.com/591099 fast/canvas/patternfill-repeat.html [ Failure ]
 crbug.com/591099 fast/clip/001.html [ Failure ]
 crbug.com/591099 fast/clip/004.html [ Failure ]
@@ -3384,7 +3384,7 @@
 crbug.com/591099 fast/css/containment/size-and-layout-containment.html [ Failure ]
 crbug.com/591099 fast/css/continuationCrash.html [ Failure ]
 crbug.com/591099 fast/css/counters/counter-traverse-table-cell.html [ Failure ]
-crbug.com/591099 fast/css/counters/nesting.html [ Crash ]
+crbug.com/591099 fast/css/counters/nesting.html [ Crash Pass ]
 crbug.com/591099 fast/css/create_element_align.xhtml [ Failure ]
 crbug.com/591099 fast/css/css-imports.html [ Failure ]
 crbug.com/591099 fast/css/css-properties-position-relative-as-parent-fixed.html [ Failure ]
@@ -3394,7 +3394,7 @@
 crbug.com/591099 fast/css/css3-nth-child.html [ Failure ]
 crbug.com/591099 fast/css/css3-space-in-nth-and-lang.html [ Failure ]
 crbug.com/591099 fast/css/dfn-default-font-style.html [ Failure ]
-crbug.com/591099 fast/css/dynamic-class-pseudo-elements.html [ Crash ]
+crbug.com/591099 fast/css/dynamic-class-pseudo-elements.html [ Crash Pass ]
 crbug.com/591099 fast/css/dynamic-sibling-selector.html [ Failure ]
 crbug.com/591099 fast/css/empty-body-test.html [ Crash Failure ]
 crbug.com/591099 fast/css/empty-generated-content.html [ Failure ]
@@ -3443,7 +3443,7 @@
 crbug.com/591099 fast/css/h1-in-section-elements.html [ Failure ]
 crbug.com/591099 fast/css/hover-active-quirks.html [ Failure ]
 crbug.com/591099 fast/css/hover-affects-ancestor.html [ Failure ]
-crbug.com/591099 fast/css/hover-after-clicking-embed.html [ Failure ]
+crbug.com/591099 fast/css/hover-after-clicking-embed.html [ Failure Pass ]
 crbug.com/591099 fast/css/hover-subselector.html [ Failure ]
 crbug.com/591099 fast/css/hsl-color.html [ Failure ]
 crbug.com/591099 fast/css/hsla-color.html [ Failure ]
@@ -3579,8 +3579,8 @@
 crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-justify.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-left.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-text-align-right.html [ Failure ]
-crbug.com/591099 fast/css/text-overflow-ellipsis-vertical-select.html [ Failure ]
-crbug.com/591099 fast/css/text-overflow-ellipsis-vertical.html [ Failure ]
+crbug.com/591099 fast/css/text-overflow-ellipsis-vertical-select.html [ Failure Pass ]
+crbug.com/591099 fast/css/text-overflow-ellipsis-vertical.html [ Failure Pass ]
 crbug.com/591099 fast/css/text-overflow-ellipsis.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-input.html [ Failure ]
 crbug.com/591099 fast/css/text-rendering.html [ Failure ]
@@ -3612,7 +3612,7 @@
 crbug.com/591099 fast/css3-text/css3-text-indent/text-indent-each-line-hanging.html [ Failure ]
 crbug.com/591099 fast/css3-text/css3-text-indent/text-indent-leading-out-of-flow.html [ Failure ]
 crbug.com/591099 fast/css3-text/css3-text-indent/text-indent-out-of-flow-each-line-hanging.html [ Failure ]
-crbug.com/591099 fast/css3-text/css3-text-justify/text-justify-8bits.html [ Failure ]
+crbug.com/591099 fast/css3-text/css3-text-justify/text-justify-8bits.html [ Failure Pass ]
 crbug.com/591099 fast/css3-text/css3-text-justify/text-justify-distribute.html [ Failure ]
 crbug.com/591099 fast/deprecated-flexbox/004.html [ Failure ]
 crbug.com/591099 fast/deprecated-flexbox/009-horizontal.html [ Failure ]
@@ -3622,7 +3622,7 @@
 crbug.com/591099 fast/deprecated-flexbox/relpos-flex-item-with-percent-height-abspos-child.html [ Failure ]
 crbug.com/591099 fast/deprecated-flexbox/relpos-flex-item-with-percent-height-abspos-descendant.html [ Failure ]
 crbug.com/591099 fast/deprecated-flexbox/repaint-scrollbar.html [ Failure ]
-crbug.com/591099 fast/dnd/dropEffect-for-image.html [ Timeout ]
+crbug.com/591099 fast/dnd/dropEffect-for-image.html [ Pass Timeout ]
 crbug.com/591099 fast/doctypes/001.html [ Failure ]
 crbug.com/591099 fast/doctypes/002.html [ Failure ]
 crbug.com/591099 fast/doctypes/003.html [ Failure ]
@@ -3630,7 +3630,7 @@
 crbug.com/591099 fast/dom/34176.html [ Failure ]
 crbug.com/591099 fast/dom/52776.html [ Failure ]
 crbug.com/591099 fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-with-before-style.html [ Failure ]
-crbug.com/591099 fast/dom/Document/document-elementFromPoint-on-option-element.html [ Failure ]
+crbug.com/591099 fast/dom/Document/document-elementFromPoint-on-option-element.html [ Failure Pass ]
 crbug.com/591099 fast/dom/Element/class-attribute-whitespace.html [ Failure ]
 crbug.com/591099 fast/dom/Element/getBoundingClientRect.html [ Failure ]
 crbug.com/591099 fast/dom/Element/null-offset-parent.html [ Failure ]
@@ -3696,13 +3696,13 @@
 crbug.com/591099 fast/dom/empty-hash-and-search.html [ Failure ]
 crbug.com/591099 fast/dom/focus-contenteditable.html [ Failure ]
 crbug.com/591099 fast/dom/fragment-activation-focuses-target.html [ Failure ]
-crbug.com/591099 fast/dom/horizontal-scrollbar-in-rtl.html [ Failure ]
+crbug.com/591099 fast/dom/horizontal-scrollbar-in-rtl.html [ Failure Pass ]
 crbug.com/591099 fast/dom/importNodeHTML.html [ Failure ]
 crbug.com/591099 fast/dom/importNodeXML.xhtml [ Failure ]
 crbug.com/591099 fast/dom/inner-text-001.html [ Failure ]
 crbug.com/591099 fast/dom/inner-text-first-letter.html [ Failure ]
 crbug.com/591099 fast/dom/inner-text.html [ Failure ]
-crbug.com/591099 fast/dom/insertedIntoDocument-child.html [ Failure ]
+crbug.com/591099 fast/dom/insertedIntoDocument-child.html [ Failure Pass ]
 crbug.com/591099 fast/dom/insertedIntoDocument-no-crash.html [ Failure ]
 crbug.com/591099 fast/dom/insertedIntoDocument-sibling.html [ Failure ]
 crbug.com/591099 fast/dom/nodesFromRect/nodesFromRect-basic.html [ Failure ]
@@ -3713,7 +3713,7 @@
 crbug.com/591099 fast/dom/offset-parent-positioned-and-inline.html [ Failure ]
 crbug.com/591099 fast/dom/open-and-close-by-DOM.html [ Failure ]
 crbug.com/591099 fast/dom/outerText.html [ Failure ]
-crbug.com/591099 fast/dom/replaced-image-map.html [ Failure ]
+crbug.com/591099 fast/dom/replaced-image-map.html [ Failure Pass ]
 crbug.com/591099 fast/dom/row-inner-text.html [ Failure ]
 crbug.com/591099 fast/dom/rtl-scroll-to-leftmost-and-resize.html [ Failure ]
 crbug.com/591099 fast/dom/scroll-reveal-left-overflow.html [ Failure ]
@@ -3721,12 +3721,12 @@
 crbug.com/591099 fast/dom/set-outer-html.html [ Failure ]
 crbug.com/591099 fast/dom/shadow/content-child-whitespace-between-span.html [ Crash ]
 crbug.com/591099 fast/dom/shadow/querySelector-for-useragent-shadowroot.html [ Crash ]
-crbug.com/591099 fast/dom/shadow/selection-in-nested-shadow.html [ Failure ]
+crbug.com/591099 fast/dom/shadow/selection-in-nested-shadow.html [ Failure Pass ]
 crbug.com/591099 fast/dom/shadow/selections-in-shadow.html [ Timeout ]
 crbug.com/591099 fast/dom/shadow/shadow-contents-event.html [ Crash ]
 crbug.com/591099 fast/dom/shadow/shadow-dom-event-dispatching-details-summary.html [ Crash ]
 crbug.com/591099 fast/dom/shadow/shadow-dom-event-dispatching-svg-in-shadow-subtree.html [ Failure ]
-crbug.com/591099 fast/dom/vertical-scrollbar-in-rtl.html [ Failure ]
+crbug.com/591099 fast/dom/vertical-scrollbar-in-rtl.html [ Failure Pass ]
 crbug.com/591099 fast/dom/wrapper-classes.html [ Timeout ]
 crbug.com/591099 fast/dom/wrapper-context.html [ Failure ]
 crbug.com/591099 fast/dynamic/001.html [ Failure ]
@@ -3787,14 +3787,14 @@
 crbug.com/591099 fast/encoding/invalid-UTF-8.html [ Failure ]
 crbug.com/591099 fast/encoding/latin1-unencodables.html [ Failure ]
 crbug.com/591099 fast/encoding/namespace-tolerance.html [ Failure ]
-crbug.com/591099 fast/encoding/preload-encoding.html [ Crash ]
+crbug.com/591099 fast/encoding/preload-encoding.html [ Crash Pass ]
 crbug.com/591099 fast/encoding/utf-16-big-endian.html [ Failure ]
 crbug.com/591099 fast/encoding/utf-16-little-endian.html [ Failure ]
 crbug.com/591099 fast/encoding/x-user-defined-unencodables.html [ Failure ]
 crbug.com/591099 fast/encoding/xmacroman-encoding-test.html [ Failure ]
 crbug.com/591099 fast/encoding/yentest2.html [ Failure ]
 crbug.com/591099 fast/events/anchor-empty-focus.html [ Failure ]
-crbug.com/591099 fast/events/autoscroll-in-overflow-hidden-html.html [ Failure ]
+crbug.com/591099 fast/events/autoscroll-in-overflow-hidden-html.html [ Failure Pass ]
 crbug.com/591099 fast/events/autoscroll-in-textfield.html [ Failure ]
 crbug.com/591099 fast/events/autoscroll-nonscrollable-iframe-in-scrollable-div.html [ Failure ]
 crbug.com/591099 fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
@@ -3803,48 +3803,48 @@
 crbug.com/591099 fast/events/change-frame-focus.html [ Failure ]
 crbug.com/591099 fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html [ Failure ]
 crbug.com/591099 fast/events/check-defocus-event-order-when-triggered-by-tab.html [ Failure ]
-crbug.com/591099 fast/events/click-focus-anchor.html [ Failure ]
-crbug.com/591099 fast/events/click-focus-svganchor-has-ring.html [ Failure ]
+crbug.com/591099 fast/events/click-focus-anchor.html [ Failure Pass ]
+crbug.com/591099 fast/events/click-focus-svganchor-has-ring.html [ Failure Pass ]
 crbug.com/591099 fast/events/click-range-slider.html [ Crash ]
-crbug.com/591099 fast/events/click-svganchor-blur-refocus-window.html [ Failure ]
-crbug.com/591099 fast/events/click-svganchor-refocus-window.html [ Failure ]
+crbug.com/591099 fast/events/click-svganchor-blur-refocus-window.html [ Failure Pass ]
+crbug.com/591099 fast/events/click-svganchor-refocus-window.html [ Failure Pass ]
 crbug.com/591099 fast/events/context-no-deselect.html [ Failure ]
 crbug.com/591099 fast/events/domactivate-sets-underlying-click-event-as-handled.html [ Crash ]
-crbug.com/591099 fast/events/drag-and-drop-autoscroll-inner-frame.html [ Timeout ]
-crbug.com/591099 fast/events/drag-dragend-detaches.html [ Failure ]
-crbug.com/591099 fast/events/drag-image-filename.html [ Timeout ]
+crbug.com/591099 fast/events/drag-and-drop-autoscroll-inner-frame.html [ Pass Timeout ]
+crbug.com/591099 fast/events/drag-dragend-detaches.html [ Failure Pass ]
+crbug.com/591099 fast/events/drag-image-filename.html [ Pass Timeout ]
 crbug.com/591099 fast/events/drag-selects-image.html [ Failure ]
-crbug.com/591099 fast/events/drag-svg-image-crash.html [ Timeout ]
+crbug.com/591099 fast/events/drag-svg-image-crash.html [ Pass Timeout ]
 crbug.com/591099 fast/events/drag_and_drop_into_removed_on_focus.html [ Failure ]
-crbug.com/591099 fast/events/event-hit-testing-fallback-to-iframe.html [ Failure ]
+crbug.com/591099 fast/events/event-hit-testing-fallback-to-iframe.html [ Failure Pass ]
 crbug.com/591099 fast/events/event-listener-on-link.html [ Failure ]
 crbug.com/591099 fast/events/event-trusted.html [ Failure ]
-crbug.com/591099 fast/events/frame-click-focus.html [ Failure ]
-crbug.com/591099 fast/events/frame-detached-in-mousedown.html [ Timeout ]
+crbug.com/591099 fast/events/frame-click-focus.html [ Failure Pass ]
+crbug.com/591099 fast/events/frame-detached-in-mousedown.html [ Pass Timeout ]
 crbug.com/591099 fast/events/frame-programmatic-focus.html [ Failure ]
 crbug.com/591099 fast/events/frame-scroll-fake-mouse-move.html [ Failure ]
 crbug.com/591099 fast/events/frame-tab-focus.html [ Failure ]
 crbug.com/591099 fast/events/hit-test-counts.html [ Failure ]
-crbug.com/591099 fast/events/iframe-mousewheel.html [ Failure ]
-crbug.com/591099 fast/events/iframe-onmousemove.html [ Timeout ]
-crbug.com/591099 fast/events/inputevents/beforeinput-remove-iframe-crash.html [ Failure ]
+crbug.com/591099 fast/events/iframe-mousewheel.html [ Failure Pass ]
+crbug.com/591099 fast/events/iframe-onmousemove.html [ Pass Timeout ]
+crbug.com/591099 fast/events/inputevents/beforeinput-remove-iframe-crash.html [ Failure Pass ]
 crbug.com/591099 fast/events/js-keyboard-event-creation.html [ Failure ]
 crbug.com/591099 fast/events/key-events-in-input-text.html [ Failure ]
 crbug.com/591099 fast/events/keyboardevent-getModifierState.html [ Timeout ]
-crbug.com/591099 fast/events/keydown-1.html [ Failure ]
+crbug.com/591099 fast/events/keydown-1.html [ Failure Pass ]
 crbug.com/591099 fast/events/keydown-keypress-focus-change.html [ Failure ]
 crbug.com/591099 fast/events/keydown-keypress-preventDefault.html [ Failure ]
 crbug.com/591099 fast/events/keypress-focus-change.html [ Failure ]
 crbug.com/591099 fast/events/media-element-focus-tab.html [ Failure ]
-crbug.com/591099 fast/events/middleClickAutoscroll-in-iframe.html [ Timeout ]
+crbug.com/591099 fast/events/middleClickAutoscroll-in-iframe.html [ Pass Timeout ]
 crbug.com/591099 fast/events/middleClickAutoscroll-nested-divs-forbidden.html [ Timeout ]
-crbug.com/591099 fast/events/mouse-cursor-style-change-iframe.html [ Failure ]
+crbug.com/591099 fast/events/mouse-cursor-style-change-iframe.html [ Failure Pass ]
 crbug.com/591099 fast/events/mouse-drag-from-frame-to-other-frame.html [ Failure ]
-crbug.com/591099 fast/events/mouse-drag-from-frame.html [ Failure ]
+crbug.com/591099 fast/events/mouse-drag-from-frame.html [ Failure Pass ]
 crbug.com/591099 fast/events/mouse-event-buttons-attribute.html [ Timeout ]
-crbug.com/591099 fast/events/mouse-events-within-no-element.html [ Failure ]
-crbug.com/591099 fast/events/mouse-focus-imagemap.html [ Failure ]
-crbug.com/591099 fast/events/mouse-moved-remove-frame-crash.html [ Timeout ]
+crbug.com/591099 fast/events/mouse-events-within-no-element.html [ Failure Pass ]
+crbug.com/591099 fast/events/mouse-focus-imagemap.html [ Failure Pass ]
+crbug.com/591099 fast/events/mouse-moved-remove-frame-crash.html [ Pass Timeout ]
 crbug.com/591099 fast/events/mouseevent-getModifierState.html [ Timeout ]
 crbug.com/591099 fast/events/mousemove-after-drag-over-scrollbar.html [ Failure ]
 crbug.com/591099 fast/events/mousemove-to-resizer-changes-cursor.html [ Failure ]
@@ -3855,29 +3855,29 @@
 crbug.com/591099 fast/events/onclick-list-marker.html [ Failure ]
 crbug.com/591099 fast/events/onload-re-entry.html [ Failure ]
 crbug.com/591099 fast/events/onload-webkit-before-webcore.html [ Failure ]
-crbug.com/591099 fast/events/page-scaled-mouse-click-iframe.html [ Failure ]
+crbug.com/591099 fast/events/page-scaled-mouse-click-iframe.html [ Failure Pass ]
 crbug.com/591099 fast/events/pointer-events-2.html [ Failure ]
-crbug.com/591099 fast/events/pointerevents/mouse-on-object.html [ Failure ]
+crbug.com/591099 fast/events/pointerevents/mouse-on-object.html [ Failure Pass ]
 crbug.com/591099 fast/events/pointerevents/mouse-pointer-capture-transition-events.html [ Timeout ]
-crbug.com/591099 fast/events/pointerevents/mouse-pointer-capture.html [ Pass Timeout ]
+crbug.com/591099 fast/events/pointerevents/mouse-pointer-capture.html [ Failure Pass Timeout ]
 crbug.com/591099 fast/events/pointerevents/mouse-pointer-event-properties.html [ Timeout ]
-crbug.com/591099 fast/events/pointerevents/mouse-pointer-preventdefault.html [ Timeout ]
-crbug.com/591099 fast/events/pointerevents/multi-pointer-preventdefault.html [ Pass Timeout ]
+crbug.com/591099 fast/events/pointerevents/mouse-pointer-preventdefault.html [ Failure Timeout ]
+crbug.com/591099 fast/events/pointerevents/multi-pointer-preventdefault.html [ Failure Pass Timeout ]
 crbug.com/591099 fast/events/pointerevents/touch-capture-in-iframe.html [ Timeout ]
 crbug.com/591099 fast/events/pointerevents/touch-capture.html [ Timeout ]
 crbug.com/591099 fast/events/popup-allowed-from-gesture-initiated-event.html [ Crash Failure ]
 crbug.com/591099 fast/events/popup-allowed-from-gesture-only-once-iframes.html [ Timeout ]
 crbug.com/591099 fast/events/popup-blocked-from-different-frames.html [ Failure ]
-crbug.com/591099 fast/events/popup-blocking-click-in-iframe.html [ Timeout ]
-crbug.com/591099 fast/events/remove-target-in-mouseup.html [ Failure ]
-crbug.com/591099 fast/events/remove-target-with-shadow-in-drag.html [ Failure ]
+crbug.com/591099 fast/events/popup-blocking-click-in-iframe.html [ Pass Timeout ]
+crbug.com/591099 fast/events/remove-target-in-mouseup.html [ Failure Pass ]
+crbug.com/591099 fast/events/remove-target-with-shadow-in-drag.html [ Failure Pass ]
 crbug.com/591099 fast/events/reveal-link-when-focused.html [ Failure ]
 crbug.com/591099 fast/events/right-click-focus.html [ Failure ]
 crbug.com/591099 fast/events/scroll-after-click-on-tab-index.html [ Failure ]
 crbug.com/591099 fast/events/scroll-div-with-prevent-default-in-subframe.html [ Failure ]
 crbug.com/591099 fast/events/scroll-to-anchor-in-overflow-hidden.html [ Failure ]
 crbug.com/591099 fast/events/select-element.html [ Timeout ]
-crbug.com/591099 fast/events/select-onchange-mouse-released-outside.html [ Failure ]
+crbug.com/591099 fast/events/select-onchange-mouse-released-outside.html [ Failure Pass ]
 crbug.com/591099 fast/events/selectstart-by-double-triple-clicks.html [ Failure ]
 crbug.com/591099 fast/events/selectstart-by-drag.html [ Failure ]
 crbug.com/591099 fast/events/selectstart-by-single-click-with-shift.html [ Failure ]
@@ -3889,12 +3889,12 @@
 crbug.com/591099 fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
 crbug.com/591099 fast/events/touch/gesture/gesture-click-on-inline-continations.html [ Failure ]
 crbug.com/591099 fast/events/touch/gesture/gesture-tap-frame-move.html [ Failure ]
-crbug.com/591099 fast/events/touch/gesture/gesture-tap-mouse-events-between-frames.html [ Failure ]
-crbug.com/591099 fast/events/touch/gesture/gesture-tap-near-iframe.html [ Failure ]
-crbug.com/591099 fast/events/touch/gesture/long-press-drag-drop-touch-editing-combined-in-iframe.html [ Failure ]
-crbug.com/591099 fast/events/touch/gesture/long-press-focuses-frame.html [ Failure ]
-crbug.com/591099 fast/events/touch/gesture/touch-gesture-scroll-iframe-editable.html [ Failure ]
-crbug.com/591099 fast/events/touch/gesture/touch-gesture-scroll-iframe-past-extent.html [ Timeout ]
+crbug.com/591099 fast/events/touch/gesture/gesture-tap-mouse-events-between-frames.html [ Failure Pass ]
+crbug.com/591099 fast/events/touch/gesture/gesture-tap-near-iframe.html [ Failure Pass ]
+crbug.com/591099 fast/events/touch/gesture/long-press-drag-drop-touch-editing-combined-in-iframe.html [ Failure Pass ]
+crbug.com/591099 fast/events/touch/gesture/long-press-focuses-frame.html [ Failure Pass ]
+crbug.com/591099 fast/events/touch/gesture/touch-gesture-scroll-iframe-editable.html [ Failure Pass ]
+crbug.com/591099 fast/events/touch/gesture/touch-gesture-scroll-iframe-past-extent.html [ Failure Timeout ]
 crbug.com/591099 fast/events/touch/touch-action-range-input-csp.html [ Crash ]
 crbug.com/591099 fast/events/touch/touch-action-range-input.html [ Crash ]
 crbug.com/591099 fast/events/touch/touch-fractional-coordinates.html [ Failure ]
@@ -3905,7 +3905,7 @@
 crbug.com/591099 fast/events/window-onerror-11.html [ Failure ]
 crbug.com/591099 fast/events/window-onerror-12.html [ Failure ]
 crbug.com/591099 fast/files/file-in-input-display.html [ Failure Timeout ]
-crbug.com/591099 fast/files/null-origin-string.html [ Timeout ]
+crbug.com/591099 fast/files/null-origin-string.html [ Pass Timeout ]
 crbug.com/591099 fast/forms/001.html [ Failure ]
 crbug.com/591099 fast/forms/006.html [ Failure ]
 crbug.com/591099 fast/forms/007.html [ Failure ]
@@ -4078,12 +4078,12 @@
 crbug.com/591099 fast/forms/select/listbox-appearance-basic.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-bidi-align.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-clip.html [ Failure ]
-crbug.com/591099 fast/forms/select/listbox-drag-in-non-multiple.html [ Failure ]
+crbug.com/591099 fast/forms/select/listbox-drag-in-non-multiple.html [ Failure Pass ]
 crbug.com/591099 fast/forms/select/listbox-in-multi-column.html [ Failure ]
-crbug.com/591099 fast/forms/select/listbox-onchange.html [ Failure ]
+crbug.com/591099 fast/forms/select/listbox-onchange.html [ Failure Pass ]
 crbug.com/591099 fast/forms/select/listbox-scrollbar-incremental-load.html [ Failure ]
-crbug.com/591099 fast/forms/select/listbox-selection-2.html [ Failure ]
-crbug.com/591099 fast/forms/select/listbox-selection.html [ Failure ]
+crbug.com/591099 fast/forms/select/listbox-selection-2.html [ Failure Pass ]
+crbug.com/591099 fast/forms/select/listbox-selection.html [ Failure Pass ]
 crbug.com/591099 fast/forms/select/listbox-tap.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-width-change.html [ Failure ]
 crbug.com/591099 fast/forms/select/listbox-with-display-none-option.html [ Failure ]
@@ -4101,7 +4101,7 @@
 crbug.com/591099 fast/forms/select/menulist-style-color.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-update-text-popup.html [ Failure ]
 crbug.com/591099 fast/forms/select/menulist-width-change.html [ Failure ]
-crbug.com/591099 fast/forms/select/multiselect-in-listbox-mouse-release-outside.html [ Failure ]
+crbug.com/591099 fast/forms/select/multiselect-in-listbox-mouse-release-outside.html [ Failure Pass ]
 crbug.com/591099 fast/forms/select/optgroup-clicking.html [ Failure ]
 crbug.com/591099 fast/forms/select/optgroup-disabled.html [ Failure ]
 crbug.com/591099 fast/forms/select/optgroup-rendering.html [ Failure ]
@@ -4130,7 +4130,7 @@
 crbug.com/591099 fast/forms/select/select-generated-content.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-initial-position.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-item-background-clip.html [ Failure ]
-crbug.com/591099 fast/forms/select/select-list-box-mouse-focus.html [ Failure ]
+crbug.com/591099 fast/forms/select/select-list-box-mouse-focus.html [ Failure Pass ]
 crbug.com/591099 fast/forms/select/select-list-box-with-height.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-listbox-multiple-no-focusring.html [ Failure ]
 crbug.com/591099 fast/forms/select/select-multiple-elements-with-mouse-drag-with-options-less-than-size.html [ Failure ]
@@ -4323,8 +4323,8 @@
 crbug.com/591099 fast/hidpi/image-set-list-style-image.html [ Failure ]
 crbug.com/591099 fast/hidpi/image-set-shape-outside.html [ Failure ]
 crbug.com/591099 fast/hidpi/image-srcset-intrinsic-size.html [ Failure ]
-crbug.com/591099 fast/history/form-submit-in-frame-via-onclick.html [ Timeout ]
-crbug.com/591099 fast/history/form-submit-in-frame.html [ Timeout ]
+crbug.com/591099 fast/history/form-submit-in-frame-via-onclick.html [ Pass Timeout ]
+crbug.com/591099 fast/history/form-submit-in-frame.html [ Pass Timeout ]
 crbug.com/591099 fast/history/saves-state-after-frame-nav.html [ Failure ]
 crbug.com/591099 fast/html/draggable-controls.html [ Failure ]
 crbug.com/591099 fast/html/select-dropdown-consistent-background-color.html [ Failure ]
@@ -4338,7 +4338,7 @@
 crbug.com/591099 fast/inline/continuation-outlines-with-layers.html [ Failure ]
 crbug.com/591099 fast/inline/continuation-outlines.html [ Failure ]
 crbug.com/591099 fast/inline/drawStyledEmptyInlines.html [ Failure ]
-crbug.com/591099 fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure ]
+crbug.com/591099 fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure Pass ]
 crbug.com/591099 fast/inline/emptyInlinesWithinLists.html [ Failure ]
 crbug.com/591099 fast/inline/inline-borders-with-bidi-override.html [ Failure ]
 crbug.com/591099 fast/inline/inline-box-background-long-image.html [ Failure ]
@@ -4351,7 +4351,7 @@
 crbug.com/591099 fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ]
 crbug.com/591099 fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline.html [ Failure ]
 crbug.com/591099 fast/inline/outline-continuations.html [ Failure ]
-crbug.com/591099 fast/inline/relative-positioned-overflow.html [ Failure ]
+crbug.com/591099 fast/inline/relative-positioned-overflow.html [ Failure Pass ]
 crbug.com/591099 fast/inline/styledEmptyInlinesWithBRs.html [ Failure ]
 crbug.com/591099 fast/innerHTML/004.xhtml [ Failure ]
 crbug.com/591099 fast/innerHTML/005.html [ Failure ]
@@ -4440,7 +4440,7 @@
 crbug.com/591099 fast/lists/dynamic-marker-crash.html [ Failure ]
 crbug.com/591099 fast/lists/inline-before-content-after-list-marker.html [ Failure ]
 crbug.com/591099 fast/lists/inlineBoxWrapperNullCheck.html [ Failure ]
-crbug.com/591099 fast/lists/li-style-alpha-huge-value-crash.html [ Failure ]
+crbug.com/591099 fast/lists/li-style-alpha-huge-value-crash.html [ Failure Pass ]
 crbug.com/591099 fast/lists/list-color-change-no-layout.html [ Failure ]
 crbug.com/591099 fast/lists/list-item-line-height.html [ Failure ]
 crbug.com/591099 fast/lists/list-marker-before-content-table.html [ Failure ]
@@ -4455,15 +4455,15 @@
 crbug.com/591099 fast/lists/ordered-list-with-no-ol-tag.html [ Failure ]
 crbug.com/591099 fast/lists/remove-listmarker-and-make-anonblock-empty-2.html [ Failure Pass ]
 crbug.com/591099 fast/lists/scrolled-marker-paint.html [ Failure ]
-crbug.com/591099 fast/loader/child-frame-add-after-back-forward.html [ Failure ]
+crbug.com/591099 fast/loader/child-frame-add-after-back-forward.html [ Failure Timeout ]
 crbug.com/591099 fast/loader/frame-creation-removal.html [ Failure ]
 crbug.com/591099 fast/loader/local-CSS-from-local.html [ Failure ]
 crbug.com/591099 fast/loader/local-JavaScript-from-local.html [ Failure ]
 crbug.com/591099 fast/loader/local-iFrame-source-from-local.html [ Failure ]
 crbug.com/591099 fast/loader/local-image-from-local.html [ Failure ]
-crbug.com/591099 fast/loader/navigation-scheduler-user-gesture.html [ Failure ]
+crbug.com/591099 fast/loader/navigation-scheduler-user-gesture.html [ Failure Timeout ]
 crbug.com/591099 fast/loader/opaque-base-url.html [ Failure ]
-crbug.com/591099 fast/loader/show-only-one-beforeunload-dialog.html [ Failure ]
+crbug.com/591099 fast/loader/show-only-one-beforeunload-dialog.html [ Failure Pass ]
 crbug.com/591099 fast/loader/text-document-wrapping.html [ Failure ]
 crbug.com/591099 fast/masking/clip-path-inset-large-radii.html [ Failure ]
 crbug.com/591099 fast/masking/clip-path-selection.html [ Failure ]
@@ -4517,7 +4517,7 @@
 crbug.com/591099 fast/multicol/composited-layer.html [ Failure ]
 crbug.com/591099 fast/multicol/composited-opacity-2nd-and-3rd-column.html [ Crash Failure ]
 crbug.com/591099 fast/multicol/composited-relpos-clipped.html [ Crash Failure ]
-crbug.com/591099 fast/multicol/composited-relpos-in-clipped.html [ Pass ]
+crbug.com/591099 fast/multicol/composited-relpos-in-clipped.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/composited-relpos-overlapping-will-change.html [ Crash Failure ]
 crbug.com/591099 fast/multicol/composited-relpos-resize.html [ Crash Failure ]
 crbug.com/591099 fast/multicol/composited-relpos.html [ Crash Failure ]
@@ -4540,8 +4540,8 @@
 crbug.com/591099 fast/multicol/dynamic/insert-block-between-spanners.html [ Failure ]
 crbug.com/591099 fast/multicol/dynamic/insert-block-into-content.html [ Failure ]
 crbug.com/591099 fast/multicol/dynamic/insert-block-into-inline-beside-ex-spanner-table-column.html [ Crash ]
-crbug.com/591099 fast/multicol/dynamic/insert-float-after-content-in-spanner.html [ Failure ]
-crbug.com/591099 fast/multicol/dynamic/insert-float-before-content-in-spanner.html [ Failure ]
+crbug.com/591099 fast/multicol/dynamic/insert-float-after-content-in-spanner.html [ Failure Pass ]
+crbug.com/591099 fast/multicol/dynamic/insert-float-before-content-in-spanner.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/dynamic/insert-spanner-after-abspos-subtree-crash.html [ Crash ]
 crbug.com/591099 fast/multicol/dynamic/insert-spanner-after-content.html [ Failure ]
 crbug.com/591099 fast/multicol/dynamic/insert-spanner-after-inner-multicol-crash.html [ Crash ]
@@ -4820,7 +4820,7 @@
 crbug.com/591099 fast/multicol/tall-float2.html [ Failure ]
 crbug.com/591099 fast/multicol/text-shadow-at-column-boundaries.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/three-inner-rows.html [ Failure ]
-crbug.com/591099 fast/multicol/transform-inside-opacity.html [ Failure ]
+crbug.com/591099 fast/multicol/transform-inside-opacity.html [ Failure Pass ]
 crbug.com/591099 fast/multicol/unforced-break-after-complex-margin-collapsing.html [ Failure ]
 crbug.com/591099 fast/multicol/unsplittable-inline-block.html [ Failure ]
 crbug.com/591099 fast/multicol/vertical-lr/abspos-auto-position-on-line.html [ Crash Failure ]
@@ -4915,66 +4915,291 @@
 crbug.com/591099 fast/pagination/multicol.html [ Failure ]
 crbug.com/591099 fast/pagination/paged-x-column-gap.html [ Failure ]
 # This one is really just very slow:
+crbug.com/714962 accessibility/adjacent-continuations-cause-assertion-failure.html [ Failure ]
 crbug.com/591099 accessibility/anchor-linked-anonymous-block-crash.html [ Crash ]
 crbug.com/591099 accessibility/aom-decrement-action.html [ Crash ]
 crbug.com/591099 accessibility/aom-increment-action.html [ Crash ]
 crbug.com/591099 accessibility/aria-hidden-hides-all-elements.html [ Crash ]
 crbug.com/591099 accessibility/aria-modal.html [ Crash ]
 crbug.com/591099 accessibility/aria-roles.html [ Crash ]
+crbug.com/714962 accessibility/aria-tables.html [ Failure ]
+crbug.com/714962 accessibility/background-color.html [ Failure ]
+crbug.com/714962 accessibility/bounds-calc.html [ Failure ]
 crbug.com/591099 accessibility/canvas-fallback-content-labels.html [ Crash ]
+crbug.com/714962 accessibility/click-event.html [ Timeout ]
 crbug.com/591099 accessibility/clickable.html [ Crash ]
 crbug.com/591099 accessibility/corresponding-control-deleted-crash.html [ Crash ]
+crbug.com/714962 accessibility/css-first-letter-children.html [ Failure ]
 crbug.com/591099 accessibility/description-calc-summary.html [ Crash ]
+crbug.com/714962 accessibility/dimensions-include-descendants.html [ Failure ]
 crbug.com/591099 accessibility/disabled-controls-not-focusable.html [ Crash ]
 crbug.com/591099 accessibility/disabled-controls.html [ Crash ]
+crbug.com/714962 accessibility/div-within-anchors-causes-crash.html [ Failure ]
+crbug.com/714962 accessibility/dl-role.html [ Failure ]
+crbug.com/714962 accessibility/ellipsis-text.html [ Failure ]
+crbug.com/714962 accessibility/first-letter-text-transform-causes-crash.html [ Failure ]
+crbug.com/714962 accessibility/in-page-link-target.html [ Failure ]
+crbug.com/714962 accessibility/inline-text-bounds-for-range-br.html [ Failure ]
 crbug.com/591099 accessibility/input-type-range-value-change-event.html [ Crash ]
 crbug.com/591099 accessibility/input-type-range-value-change.html [ Crash ]
+crbug.com/714962 accessibility/label-for-control-hittest.html [ Failure ]
+crbug.com/714962 accessibility/legend.html [ Failure ]
+crbug.com/714962 accessibility/name-calc-inputs.html [ Failure ]
 crbug.com/591099 accessibility/name-calc-summary.html [ Crash ]
+crbug.com/714962 accessibility/selection-events.html [ Failure ]
+crbug.com/714962 accessibility/set-selection-link.html [ Failure ]
+crbug.com/714962 accessibility/table-detection.html [ Failure ]
+crbug.com/714962 accessibility/table-with-empty-thead-causes-crash.html [ Failure ]
+crbug.com/714962 accessibility/table-with-rules.html [ Failure ]
+crbug.com/714962 animations/3d/matrix-transform-type-animation.html [ Failure ]
 crbug.com/591099 animations/interpolation/height-interpolation.html [ Crash ]
+crbug.com/714962 compositing/background-color/view-blending-base-background.html [ Failure ]
+crbug.com/714962 compositing/flex-composited-animated-table-row-background.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-composite.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-noncomposite.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-composited.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe-scrolled.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-iframe.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-composited-scroll-clip.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-composited-scrolled.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-composited.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change-2.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled-late-composite.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled-late-noncomposite.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-1-overflow-div.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-iframe-composited-inner.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner-scroll-inner.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner-scroll-outer.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer-scroll-inner.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer-scroll-outer.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-scrolled-inner.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div-scrolled-outer.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-2-overflow-div.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-img-and-text.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-img.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-invisible-inline-squashing.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-invisible-inline.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-on-promoted-overflow-div-scrolled.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-pixel-rotated-link.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-pixel-transparent.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-shadow-tree.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-cancel.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-cancel2.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-longPress.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-margin.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-multi-line.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-navigate.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-nested.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-scaled-document.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-scaledX.html [ Failure ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-scaledY.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple-window-scroll.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-simple.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-with-box-shadow.html [ Crash ]
+crbug.com/714962 compositing/gestures/gesture-tapHighlight-with-squashing.html [ Crash ]
+crbug.com/714962 compositing/images/direct-image-clip-path.html [ Failure ]
+crbug.com/714962 compositing/images/direct-image-dynamic-clip-path.html [ Failure ]
+crbug.com/714962 compositing/overflow/absolute-element-in-isolated-composited-ancestor.html [ Failure ]
 crbug.com/591099 compositing/overflow/border-radius-on-squashed-layers.html [ Failure Pass ]
 crbug.com/591099 compositing/overflow/composited-scroll-with-fractional-translation.html [ Pass ]
 crbug.com/591099 compositing/overflow/do-not-crash-use-after-free-update-widget-positions.html [ Crash ]
+crbug.com/714962 compositing/overflow/fixed-element-in-isolated-composited-ancestor.html [ Failure ]
 crbug.com/591099 compositing/overflow/get-transform-from-non-box-container.html [ Crash ]
+crbug.com/714962 compositing/overflow/image-load-overflow-scrollbars.html [ Failure ]
+crbug.com/714962 compositing/overflow/mixed-composited-nested-sticky-overflow-scroller.html [ Failure ]
 crbug.com/591099 compositing/overflow/overflow-with-negative-z-index-child.html [ Failure ]
+crbug.com/714962 compositing/overflow/rtl-overflow.html [ Failure ]
 crbug.com/591099 compositing/perspective-interest-rect.html [ Failure ]
+crbug.com/714962 compositing/squashing/squash-composited-input.html [ Failure ]
+crbug.com/714962 compositing/squashing/squash-overflow-hidden-scrolltop.html [ Failure ]
 crbug.com/591099 compositing/squashing/squashing-does-not-stop-transform-propagation.html [ Crash ]
+crbug.com/714962 compositing/squashing/universal-accelerated-overflow-scrolling.html [ Failure ]
+crbug.com/714962 compositing/transitions/transform-on-large-layer.html [ Failure ]
+crbug.com/714962 compositing/visibility/visibility-image-layers.html [ Failure ]
 crbug.com/591099 compositing/will-change/will-change-preserve-backface-visibility.html [ Crash ]
 crbug.com/591099 compositing/z-order/collect-layers-does-not-initialize-pos-z-order-list.html [ Crash ]
+crbug.com/714962 css1/font_properties/font.html [ Failure ]
+crbug.com/714962 css1/text_properties/text_align.html [ Failure ]
+crbug.com/714962 css2.1/20110323/border-conflict-element-001d.htm [ Failure ]
+crbug.com/714962 css2.1/20110323/border-conflict-element-021a.htm [ Failure ]
+crbug.com/714962 css2.1/20110323/outline-color-applies-to-010.htm [ Failure ]
+crbug.com/714962 css2.1/20110323/overflow-applies-to-007.htm [ Failure ]
+crbug.com/714962 css2.1/20110323/overflow-applies-to-009.htm [ Failure ]
+crbug.com/714962 css2.1/20110323/overflow-applies-to-010.htm [ Failure ]
+crbug.com/714962 css2.1/20110323/overflow-applies-to-012.htm [ Failure ]
+crbug.com/714962 css3/blending/effect-background-blend-mode-stacking.html [ Failure ]
+crbug.com/714962 css3/blending/effect-background-blend-mode-tiled.html [ Failure ]
+crbug.com/714962 css3/blending/effect-background-blend-mode.html [ Failure ]
+crbug.com/714962 css3/filters/effect-reference-image-lazy-attach.html [ Failure ]
+crbug.com/714962 css3/filters/effect-reference-image.html [ Failure ]
+crbug.com/714962 css3/filters/effect-reference-on-transparent-element.html [ Failure ]
+crbug.com/714962 css3/filters/effect-reference-tile.html [ Crash ]
+crbug.com/714962 css3/filters/empty-element-with-filter.html [ Failure ]
+crbug.com/714962 css3/filters/filter-region-transformed-child.html [ Failure ]
+crbug.com/714962 css3/filters/filterRegions.html [ Failure ]
+crbug.com/714962 css3/filters/nested-filter.html [ Failure ]
+crbug.com/714962 css3/flexbox/content-height-with-scrollbars.html [ Failure ]
+crbug.com/714962 css3/flexbox/flex-flow-auto-margins-no-available-space.html [ Failure ]
 crbug.com/591099 css3/flexbox/flexitem-stretch-range.html [ Crash ]
+crbug.com/714962 css3/flexbox/mozilla/flexbox-items-as-stacking-contexts-2.html [ Failure ]
+crbug.com/714962 css3/flexbox/overflow-auto-dynamic-changes.html [ Failure ]
+crbug.com/714962 css3/fonts/font-style-matching-0.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-1.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-2.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-3.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-4.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-5.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-6.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-7.html [ Timeout ]
+crbug.com/714962 css3/fonts/font-style-matching-8.html [ Timeout ]
+crbug.com/714962 css3/masking/clip-path-columns-shape.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-columns-svg-clippath-usou.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-polygon-percentage.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference-box-1.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference-box-2.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference-box-3.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference-box-inline.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference-local-url-with-base.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference-restore.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference-userSpaceOnUse.html [ Failure ]
+crbug.com/714962 css3/masking/clip-path-reference.html [ Failure ]
+crbug.com/714962 css3/masking/mask-composite-missing-image.html [ Failure ]
+crbug.com/714962 css3/tab-size-complex-path.html [ Failure ]
+crbug.com/714962 css3/tab-size.html [ Failure ]
 crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLImageElement05.xhtml [ Failure ]
 crbug.com/591099 dom/legacy_dom_conformance/xhtml/level2/html/HTMLImageElement12.xhtml [ Failure ]
 crbug.com/591099 editing/caret/caret-painting-low-dpi.html [ Failure ]
+crbug.com/714962 editing/caret/in-multicol-child.html [ Failure ]
+crbug.com/714962 editing/deleting/4916235-1.html [ Failure ]
+crbug.com/714962 editing/deleting/delete-across-editable-content-boundaries-2.html [ Crash ]
+crbug.com/714962 editing/execCommand/button.html [ Failure ]
+crbug.com/714962 editing/execCommand/remove-format-multiple-elements-mac.html [ Failure ]
+crbug.com/714962 editing/execCommand/remove-format-multiple-elements-win.html [ Failure ]
+crbug.com/714962 editing/input/textcontrol-doubleclick-at-end.html [ Failure ]
+crbug.com/714962 editing/pasteboard/copy-element-with-conflicting-background-color-from-rule.html [ Failure ]
+crbug.com/714962 editing/pasteboard/copy-paste-pre-line-content.html [ Failure ]
 crbug.com/591099 editing/pasteboard/copy-summary-crash.html [ Crash ]
-crbug.com/591099 editing/selection/5354455-1.html [ Failure ]
+crbug.com/714962 editing/pasteboard/drag-drop-copy-text.html [ Failure ]
+crbug.com/714962 editing/pasteboard/drag-drop-input-textarea.html [ Failure ]
+crbug.com/714962 editing/pasteboard/file-input-files-access.html [ Failure ]
+crbug.com/714962 editing/pasteboard/paste-table-001.html [ Failure ]
+crbug.com/591099 editing/selection/5354455-1.html [ Failure Pass ]
+crbug.com/714962 editing/selection/anchor-focus1.html [ Failure ]
+crbug.com/714962 editing/selection/anchor-focus2.html [ Failure ]
+crbug.com/714962 editing/selection/anchor-focus3.html [ Failure ]
+crbug.com/714962 editing/selection/android-longtap-not-select-empty.html [ Failure ]
+crbug.com/714962 editing/selection/caret-bidi-first-and-last-letters.html [ Failure ]
+crbug.com/714962 editing/selection/caret-in-div-containing-empty-block.html [ Failure ]
+crbug.com/714962 editing/selection/click-in-focusable-link-should-not-clear-selection.html [ Failure ]
+crbug.com/714962 editing/selection/click-on-body-margin.html [ Timeout ]
+crbug.com/714962 editing/selection/click-on-head-margin.html [ Timeout ]
+crbug.com/714962 editing/selection/deleteFromDocument-undo-crash.html [ Crash ]
+crbug.com/714962 editing/selection/drag-drop-events.html [ Failure ]
+crbug.com/714962 editing/selection/drag-drop-restore.html [ Failure ]
+crbug.com/714962 editing/selection/drag-select-rapidly.html [ Failure ]
+crbug.com/714962 editing/selection/drag-text-delay.html [ Failure ]
+crbug.com/714962 editing/selection/extend-selection-after-double-click.html [ Failure ]
+crbug.com/714962 editing/selection/extend-to-line-boundary.html [ Failure ]
+crbug.com/714962 editing/selection/focus-and-display-none.html [ Failure ]
+crbug.com/714962 editing/selection/last-empty-inline.html [ Failure ]
+crbug.com/714962 editing/selection/modify_extend/extend_backward_line_table_button.html [ Failure ]
+crbug.com/714962 editing/selection/modify_extend/extend_forward_line_crash.html [ Failure ]
+crbug.com/714962 editing/selection/modify_move/move-by-paragraph.html [ Failure ]
+crbug.com/714962 editing/selection/modify_move/move-forward-after-line-break.html [ Failure ]
+crbug.com/714962 editing/selection/modify_move/move_by_word_with_underscore.html [ Failure ]
+crbug.com/714962 editing/selection/modify_move/move_forward_line_mixed_editability.html [ Failure ]
 crbug.com/591099 editing/selection/mouse/double_click_after_last_cell.html [ Failure ]
 crbug.com/591099 editing/selection/mouse/drag_focus_node.html [ Failure ]
 crbug.com/591099 editing/selection/mouse/drags_within_user-select_combos.html [ Failure ]
+crbug.com/714962 editing/selection/mouse/mouse_up_focus.html [ Timeout ]
+crbug.com/714962 editing/selection/mouse/overidden_user_select_in_dom_tree.html [ Failure ]
+crbug.com/714962 editing/selection/mouse/user-drag-element-and-user-select-none.html [ Failure ]
+crbug.com/714962 editing/selection/offset-from-point-complex-scripts.html [ Failure ]
+crbug.com/714962 editing/selection/offset-from-point.html [ Failure ]
+crbug.com/714962 editing/selection/select-from-textfield-outwards.html [ Failure ]
+crbug.com/714962 editing/selection/select-line-break-with-opposite-directionality.html [ Failure ]
 crbug.com/591099 editing/selection/selection-linebreaks-rtl-writing-modes.html [ Failure ]
+crbug.com/714962 editing/selection/skip-over-contenteditable.html [ Failure ]
+crbug.com/714962 editing/selection/table-lineboundary.html [ Failure ]
+crbug.com/714962 editing/shadow/compare-positions-in-nested-shadow.html [ Failure ]
+crbug.com/714962 editing/surrounding-text/surrounding-text.html [ Failure ]
 crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_AES-CBC.https.worker.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_AES-CTR.https.worker.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_AES-GCM.https.worker.html [ Pass Timeout ]
+crbug.com/714962 external/wpt/WebCryptoAPI/generateKey/failures_RSA-OAEP.https.worker.html [ Timeout ]
+crbug.com/714962 external/wpt/WebCryptoAPI/import_export/test_rsa_importKey.https.html [ Timeout ]
 crbug.com/591099 external/wpt/acid/acid3/test.html [ Crash ]
-crbug.com/591099 external/wpt/compat/webkit-text-fill-color-property-005.html [ Pass ]
+crbug.com/591099 external/wpt/compat/webkit-text-fill-color-property-005.html [ Failure Pass ]
+crbug.com/714962 external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/linebox/inline-formatting-context-015.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/linebox/vertical-align-baseline-005a.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-non-replaced-width-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-005.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-007.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/inline-block-valign-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/inline-block-valign-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/inline-block-zorder-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/inline-block-zorder-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-replaced-height-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-replaced-height-005.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/inline-replaced-height-007.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/inline-table-zorder-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/inline-table-zorder-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/max-width-105.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/max-width-106.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/max-width-107.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/min-height-104.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/normal-flow/min-height-106.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/positioning/absolute-replaced-height-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/bottom-offset-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/bottom-offset-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/bottom-offset-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/left-offset-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/left-offset-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/position-relative-032.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/right-offset-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/right-offset-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/right-offset-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/top-offset-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/top-offset-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/positioning/top-offset-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/text/text-indent-overflow-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/CSS2/text/text-indent-overflow-004.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-size/background-size-cover.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-backgrounds/css3-background-clip.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-001.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-first-letter-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-table-002-none.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-replaced-001.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-text-inherit.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-flexbox/flexbox_columns-flexitems-2.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/flexbox_columns-flexitems.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/percentage-heights-003.html [ Pass ]
+crbug.com/714962 external/wpt/css/css-flexbox/percentage-heights-004.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-flexbox/position-absolute-005.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-fonts/font-display/font-display.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-1.html [ Pass ]
+crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-3.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/font-variant-01.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/font-variant-02.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/font-variant-03.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/font-variant-04.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/matching/fixed-stretch-style-over-weight.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/test_font_family_parsing.html [ Timeout ]
+crbug.com/714962 external/wpt/css/css-grid/abspos/grid-positioned-children-writing-modes-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-005.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-006.html [ Failure ]
@@ -5068,9 +5293,9 @@
 crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-003.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-groove-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-hidden-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-hidden-000.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-large-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-none-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-none-000.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-percent-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-px-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-ridge-000.xht [ Failure ]
@@ -5106,80 +5331,314 @@
 crbug.com/591099 external/wpt/css/css-multicol/multicol-width-003.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-multicol/multicol-width-large-001.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-multicol/multicol-width-large-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-paint-api/background-image-alpha.https.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-paint-api/paint-arguments.https.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-paint-api/paint-function-arguments.https.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-paint-api/style-background-image.https.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-paint-api/style-before-pseudo.https.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-paint-api/style-first-letter-pseudo.https.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-inline.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-left.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-margins.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-sticky-nested-inline.html [ Crash ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-nested-left.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-nested-right.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-nested-top.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-overflow-padding.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-right.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-position/position-sticky-top.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-scroll-anchoring/start-edge-in-block-layout-direction.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-scroll-anchoring/wrapped-text.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-tables/visibility-collapse-colspan-003.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-left-001.xht [ Crash ]
 crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-right-001.xht [ Crash ]
 crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-below-left-001.xht [ Crash ]
 crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-below-right-001.xht [ Crash ]
 crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-style-string-001.xht [ Crash ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-036.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-037.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-038.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-039.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-040.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-041.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-042.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-043.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-044.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-045.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-046.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-047.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/matrix/svg-matrix-048.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/transform-abspos-006.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/transform-abspos-007.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-transforms/transform-generated-001.html [ Crash Failure ]
 crbug.com/591099 external/wpt/css/css-transforms/transform-input-015.html [ Crash ]
-crbug.com/591099 external/wpt/css/css-ui/text-overflow-006.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-transforms/transform-origin-006.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-ui/outline-004.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-ui/text-overflow-001.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-ui/text-overflow-003.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-ui/text-overflow-006.html [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-ui/text-overflow-008.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-ui/text-overflow-009.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-ui/text-overflow-010.html [ Pass ]
+crbug.com/714962 external/wpt/css/css-ui/text-overflow-016.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-033.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-006.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-016.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-030.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-017.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-029.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-041.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-077.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-095.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-125.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-173.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-201.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-205.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-225.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-004.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-028.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-034.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-040.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-052.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-064.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-088.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-104.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-108.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-112.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-116.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-124.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-128.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-136.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-140.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-148.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-156.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-160.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-172.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-176.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-188.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-192.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-204.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-208.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-220.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-224.xht [ Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-013.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-015.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-017.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-021.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-023.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-029.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-031.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-033.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-035.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-037.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-039.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-041.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-043.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-045.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-047.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-051.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-071.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-075.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-077.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-079.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-081.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-087.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-093.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-095.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-103.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-111.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-123.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-125.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-127.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-129.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-131.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-133.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-135.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-145.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-147.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-149.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-159.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-161.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-163.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-165.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-167.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-173.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-175.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-177.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-181.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-183.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-193.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-195.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-197.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-199.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-201.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-203.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-205.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-207.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-209.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-213.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-215.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-219.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-223.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-225.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-004.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-006.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-008.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-012.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-014.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-018.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-020.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-022.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-024.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-026.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-028.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-030.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-032.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-034.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-036.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-038.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-040.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-042.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-044.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-046.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-048.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-050.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-052.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-054.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-056.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-058.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-060.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-064.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-066.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-068.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-070.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-072.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-074.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-078.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-080.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-082.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-084.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-086.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-088.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-090.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-092.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-094.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-096.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-102.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-104.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-106.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-108.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-110.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-112.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-114.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-116.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-118.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-120.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-122.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-124.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-126.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-128.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-130.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-132.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-134.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-136.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-138.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-140.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-142.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-146.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-148.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-150.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-152.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-154.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-156.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-158.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-160.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-162.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-164.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-166.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-168.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-170.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-172.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-174.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-176.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-178.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-180.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-182.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-184.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-186.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-188.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-190.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-192.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-194.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-196.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-198.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-200.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-202.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-204.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-206.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-208.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-210.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-212.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-214.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-216.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-218.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-220.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-222.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-224.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-226.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-228.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-005.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-006.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-011.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-012.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-013.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-021.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-025.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/clearance-calculations-vrl-008.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/different-block-flow-dir-002.xht [ Crash ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/float-contiguous-vlr-009.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/float-shrink-to-fit-vrl-008.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-005.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-007.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/float-vrl-008.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/inline-block-alignment-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/inline-block-alignment-004.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/inline-block-alignment-orthogonal-vrl-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/inline-block-alignment-orthogonal-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/line-box-direction-vrl-009.xht [ Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/line-box-direction-vrl-011.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/line-box-direction-vrl-012.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/normal-flow-overconstrained-vrl-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/normal-flow-overconstrained-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001b.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001d.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001f.html [ Crash ]
@@ -5188,13 +5647,58 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001l.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001n.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001p.html [ Crash ]
+crbug.com/714962 external/wpt/css/css-writing-modes/outline-inline-block-vrl-006.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/outline-inline-vrl-006.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/overconstrained-rel-pos-ltr-top-bottom-vrl-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/overconstrained-rel-pos-rtl-left-right-vrl-008.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/overconstrained-rel-pos-rtl-top-bottom-vrl-006.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/percent-padding-vrl-004.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/percent-padding-vrl-006.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-007.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-008.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-009.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-011.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-012.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-015.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-019.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-020.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-021.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-023.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-024.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-004.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-007.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-008.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-002.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-003.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-004.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-005.xht [ Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-005.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-011.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-013.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-015.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-018.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-decorations-001.html [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-011.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-013.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-004.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-004.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-010.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-012.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-orientation-script-001a.html [ Crash ]
@@ -5214,6 +5718,33 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/text-orientation-script-001o.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-orientation-script-001p.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-orientation-script-001q.html [ Crash ]
+crbug.com/714962 external/wpt/css/css-writing-modes/wm-propagation-body-015.xht [ Failure ]
+crbug.com/714962 external/wpt/css/cssom-view/DOMRectList.html [ Failure ]
+crbug.com/714962 external/wpt/css/cssom/medialist-dynamic-001.html [ Failure ]
+crbug.com/714962 external/wpt/css/selectors/focus-within-001.html [ Failure ]
+crbug.com/714962 external/wpt/css/selectors/focus-within-007.html [ Failure ]
+crbug.com/714962 external/wpt/css/selectors/focus-within-008.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-004.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-line-horiz-001.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-line-horiz-002.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-line-vert-001.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-line-vert-002.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-basic-block-horiz-001.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-basic-fieldset-horiz-001.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-basic-img-horiz-001.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-basic-textarea-horiz-001.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-flow-002.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-003.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-004.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-items-as-stacking-contexts-002.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-items-as-stacking-contexts-003.html [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-002.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-mbp-horiz-001-rtl-reverse.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-mbp-horiz-001.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-mbp-horiz-002a.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-mbp-horiz-002b.xhtml [ Failure ]
+crbug.com/714962 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html [ Failure ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-001.html [ Crash ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-002.html [ Crash ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/writing-modes-3/text-combine-upright-compression-005.html [ Crash ]
@@ -5247,6 +5778,9 @@
 crbug.com/591099 external/wpt/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements.html [ Crash ]
 crbug.com/591099 external/wpt/html/dom/documents/resource-metadata-management/document-lastModified-01.html [ Pass ]
 crbug.com/591099 external/wpt/html/editing/focus/tabindex-focus-flag.html [ Crash ]
+crbug.com/714962 external/wpt/html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html [ Failure ]
+crbug.com/714962 external/wpt/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change.html [ Failure ]
+crbug.com/714962 external/wpt/html/semantics/document-metadata/the-link-element/stylesheet-change-href.html [ Failure ]
 crbug.com/591099 external/wpt/html/semantics/embedded-content/the-img-element/current-pixel-density/basic.html [ Failure ]
 crbug.com/591099 external/wpt/html/semantics/forms/the-form-element/form-elements-filter.html [ Crash ]
 crbug.com/591099 external/wpt/html/semantics/forms/the-form-element/form-nameditem.html [ Crash ]
@@ -5263,9 +5797,36 @@
 crbug.com/591099 external/wpt/html/semantics/interactive-elements/the-summary-element/activation-behavior.html [ Crash ]
 crbug.com/591099 external/wpt/html/semantics/selectors/pseudo-classes/inrange-outofrange.html [ Crash ]
 crbug.com/591099 external/wpt/html/semantics/selectors/pseudo-classes/readwrite-readonly.html [ Crash ]
+crbug.com/714962 external/wpt/intersection-observer/root-margin.html [ Failure ]
 crbug.com/591099 external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html [ Pass ]
 crbug.com/591099 external/wpt/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker.html [ Pass ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_capture_mouse-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_capture_suppressing_mouse-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_lostpointercapture_is_first-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-keyboard-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-mouse-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-none-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-down-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-left-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-right-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-up-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-pan-y-css_touch-manual.html [ Timeout ]
+crbug.com/714962 external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Timeout ]
 crbug.com/591099 external/wpt/quirks-mode/table-cell-width-calculation.html [ Pass ]
+crbug.com/714962 external/wpt/shadow-dom/MouseEvent-prototype-offsetX-offsetY.html [ Failure ]
+crbug.com/714962 external/wpt/shadow-dom/untriaged/styles/test-008.html [ Failure ]
+crbug.com/714962 external/wpt/uievents/order-of-events/mouse-events/click-cancel.html [ Failure ]
 crbug.com/591099 external/wpt/webrtc/interfaces.https.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/websockets/cookies/005.html [ Pass ]
 crbug.com/591099 external/wpt/websockets/cookies/007.html [ Failure Pass ]
@@ -5274,34 +5835,156 @@
 crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html [ Crash ]
 crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html [ Crash ]
 crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped.html [ Crash ]
+crbug.com/714962 fast/backgrounds/root-background-propagation3.html [ Failure ]
+crbug.com/714962 fast/backgrounds/selection-background-color.html [ Failure ]
+crbug.com/714962 fast/block/basic/015.html [ Failure ]
+crbug.com/714962 fast/block/basic/016.html [ Failure ]
 crbug.com/591099 fast/block/block-remove-child-delete-line-box-crash.html [ Crash ]
 crbug.com/591099 fast/block/child-not-removed-from-parent-lineboxes-crash.html [ Crash ]
+crbug.com/714962 fast/block/float/002.html [ Failure ]
+crbug.com/714962 fast/block/float/015.html [ Failure ]
+crbug.com/714962 fast/block/float/017.html [ Failure ]
+crbug.com/714962 fast/block/float/021.html [ Failure ]
+crbug.com/714962 fast/block/float/025.html [ Failure ]
+crbug.com/714962 fast/block/float/026.html [ Failure ]
+crbug.com/714962 fast/block/float/027.html [ Failure ]
+crbug.com/714962 fast/block/float/028.html [ Failure ]
+crbug.com/714962 fast/block/float/avoidance-percent-width-strict.html [ Failure ]
 crbug.com/591099 fast/block/float/float-on-line-obeys-container-padding.html [ Failure ]
-crbug.com/591099 fast/block/float/overhanging-tall-block.html [ Failure ]
+crbug.com/714962 fast/block/float/float-should-dirty-line-even-when-it-doesnt-intersect-it-3.html [ Failure ]
+crbug.com/714962 fast/block/float/float-should-dirty-line-when-adjacent-to-line-breaks-2.html [ Failure ]
+crbug.com/714962 fast/block/float/float-should-dirty-line-when-adjacent-to-line-breaks.html [ Failure ]
+crbug.com/714962 fast/block/float/intruding-float-add-in-sibling-block-on-static-position.html [ Failure ]
+crbug.com/714962 fast/block/float/intruding-float-add-in-sibling-block-on-static-position2.html [ Failure ]
+crbug.com/714962 fast/block/float/intruding-float-remove-from-sibling-block-on-absolute-position.html [ Failure ]
+crbug.com/714962 fast/block/float/intruding-float-remove-from-sibling-block-on-absolute-position2.html [ Failure ]
+crbug.com/714962 fast/block/float/intruding-float-remove-from-sibling-block-on-fixed-position.html [ Failure ]
+crbug.com/714962 fast/block/float/intruding-float-remove-from-sibling-block-on-fixed-position2.html [ Failure ]
+crbug.com/714962 fast/block/float/max-width-clear-float-with-overflow-hidden.html [ Failure ]
+crbug.com/714962 fast/block/float/overhanging-after-height-decrease.html [ Failure ]
+crbug.com/714962 fast/block/float/overhanging-float-add-in-static-position-block.html [ Failure ]
+crbug.com/714962 fast/block/float/overhanging-float-add-in-static-position-block2.html [ Failure ]
+crbug.com/714962 fast/block/float/overhanging-float-remove-from-absolute-position-block.html [ Failure ]
+crbug.com/714962 fast/block/float/overhanging-float-remove-from-absolute-position-block2.html [ Failure ]
+crbug.com/591099 fast/block/float/overhanging-tall-block.html [ Failure Pass ]
+crbug.com/714962 fast/block/float/relayout-nested-float-after-line.html [ Failure ]
+crbug.com/714962 fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ]
+crbug.com/714962 fast/block/float/trailing-float-with-content.html [ Failure ]
+crbug.com/714962 fast/block/layer-not-removed-from-parent-crash.html [ Failure ]
 crbug.com/591099 fast/block/line-layout/line-break-removal-near-textarea-crash.html [ Crash Failure ]
+crbug.com/714962 fast/block/margin-collapse/044.html [ Failure ]
+crbug.com/714962 fast/block/margin-collapse/line-beside-float-complex-margin-collapsing.html [ Failure ]
 crbug.com/591099 fast/block/percent-height-descendant-not-removed-crash2.html [ Crash ]
 crbug.com/591099 fast/block/positioning/052.html [ Crash ]
 crbug.com/591099 fast/block/positioning/058.html [ Crash ]
 crbug.com/591099 fast/block/positioning/abspositioned-object-under-split-relpositioned-inline-crash.html [ Crash ]
+crbug.com/714962 fast/block/positioning/auto/006.html [ Failure ]
+crbug.com/714962 fast/block/positioning/auto/vertical-lr/006.html [ Failure ]
+crbug.com/714962 fast/block/positioning/auto/vertical-rl/006.html [ Failure ]
 crbug.com/591099 fast/block/positioning/complex-positioned-movement-inline-ancestor.html [ Crash ]
 crbug.com/591099 fast/block/positioning/complex-positioned-movement-inline.html [ Crash ]
+crbug.com/714962 fast/block/positioning/differing-writing-modes-replaced.html [ Failure ]
+crbug.com/714962 fast/block/positioning/differing-writing-modes.html [ Failure ]
 crbug.com/591099 fast/block/positioning/insert-positioned-in-anonymous-crash.html [ Crash ]
+crbug.com/714962 fast/block/positioning/offsetLeft-offsetTop-multicolumn.html [ Failure ]
 crbug.com/591099 fast/block/positioning/positioned-movement-layout-when-height-changes.html [ Crash ]
 crbug.com/591099 fast/block/positioning/removing-inside-relpositioned-inline-crash.html [ Crash ]
+crbug.com/714962 fast/borders/block-mask-overlay-image.html [ Failure ]
+crbug.com/714962 fast/borders/border-image-fill-no-border.html [ Failure ]
+crbug.com/714962 fast/borders/border-image-outset-split-inline.html [ Failure ]
+crbug.com/714962 fast/borders/border-image-scaled.html [ Failure ]
+crbug.com/714962 fast/borders/border-inner-bleed.html [ Failure ]
+crbug.com/714962 fast/borders/border-radius-inline-flow.html [ Failure ]
+crbug.com/714962 fast/borders/border-radius-percent.html [ Failure ]
+crbug.com/714962 fast/borders/border-radius-split-inline.html [ Failure ]
+crbug.com/714962 fast/borders/border-radius-with-composited-child.html [ Failure ]
+crbug.com/714962 fast/borders/border-styles-split.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusArcs01.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusDouble01.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusDouble02.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusDouble03.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusGroove01.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusGroove02.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusInset01.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusInvalidColor.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusOutset01.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusRidge01.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusSolid01.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusSolid02.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusSolid03.html [ Failure ]
+crbug.com/714962 fast/borders/borderRadiusSolid04.html [ Failure ]
+crbug.com/714962 fast/borders/dashed-1px-with-border-radius.html [ Failure ]
+crbug.com/714962 fast/borders/different-color-borders.html [ Failure ]
+crbug.com/714962 fast/borders/table-borders.html [ Failure ]
+crbug.com/714962 fast/borders/thin-dotted-borders.html [ Failure ]
+crbug.com/714962 fast/box-shadow/image-box-shadow.html [ Failure ]
 crbug.com/591099 fast/box-sizing/replaced.html [ Failure ]
+crbug.com/714962 fast/canvas-api/canvas-scroll-path-into-view.html [ Failure ]
 crbug.com/591099 fast/canvas-api/fallback-content.html [ Crash ]
+crbug.com/714962 fast/canvas/canvas-css-clip-path.html [ Failure ]
+crbug.com/714962 fast/canvas/canvas-text-ideographic-space.html [ Failure ]
+crbug.com/714962 fast/canvas/canvas-textMetrics-width.html [ Failure ]
+crbug.com/714962 fast/canvas/image-object-in-canvas.html [ Failure ]
+crbug.com/714962 fast/canvas/setWidthResetAfterForcedRender.html [ Failure ]
 crbug.com/591099 fast/css-generated-content/details-before-after-content.html [ Crash ]
 crbug.com/591099 fast/css-generated-content/empty-first-letter-with-columns-crash.html [ Crash ]
+crbug.com/714962 fast/css-generated-content/hover-inline.html [ Failure ]
 crbug.com/591099 fast/css-generated-content/summary-before-after-content.html [ Crash ]
 crbug.com/591099 fast/css-grid-layout/grid-baseline-margins.html [ Pass ]
+crbug.com/714962 fast/css-grid-layout/grid-content-alignment-overflow.html [ Failure ]
+crbug.com/714962 fast/css-grid-layout/grid-item-margins-and-writing-modes.html [ Failure ]
+crbug.com/714962 fast/css-grid-layout/grid-item-paddings-and-writing-modes.html [ Failure ]
+crbug.com/714962 fast/css-grid-layout/grid-self-baseline-vertical-lr-06.html [ Failure ]
+crbug.com/714962 fast/css-grid-layout/min-width-height-auto-overflow.html [ Failure ]
 crbug.com/591099 fast/css-intrinsic-dimensions/height-flexbox.html [ Failure ]
 crbug.com/591099 fast/css-intrinsic-dimensions/height-positioned-replaced.html [ Crash ]
 crbug.com/591099 fast/css-intrinsic-dimensions/height.html [ Failure ]
 crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ]
+crbug.com/714962 fast/css/absolute-inline-alignment.html [ Failure ]
+crbug.com/714962 fast/css/active-pseudo-and-focus-move.html [ Failure ]
+crbug.com/714962 fast/css/border-current-color.html [ Failure ]
+crbug.com/714962 fast/css/button-first-line-change-color.html [ Failure ]
+crbug.com/714962 fast/css/containment/contain-paint-composited-scroll.html [ Crash ]
 crbug.com/591099 fast/css/containment/style-contain-dialogue-element.html [ Crash ]
+crbug.com/714962 fast/css/disabled-form-control-elements-should-not-be-active.html [ Failure ]
 crbug.com/591099 fast/css/dynamic-class-backdrop-pseudo.html [ Crash ]
+crbug.com/714962 fast/css/first-letter-before-hit-test.html [ Failure ]
+crbug.com/714962 fast/css/first-letter-hit-test.html [ Failure ]
+crbug.com/714962 fast/css/first-letter-hover-002.html [ Failure ]
+crbug.com/714962 fast/css/first-letter-hover-hit-test.html [ Failure ]
+crbug.com/714962 fast/css/first-letter-range-insert.html [ Failure ]
+crbug.com/714962 fast/css/first-line-change-color-direct.html [ Failure ]
+crbug.com/714962 fast/css/first-line-change-color.html [ Failure ]
+crbug.com/714962 fast/css/first-line-hover-001.html [ Failure ]
+crbug.com/714962 fast/css/focus-ring-recursive-continuations.html [ Failure ]
+crbug.com/714962 fast/css/focus-ring-recursive-inlines.html [ Failure ]
+crbug.com/714962 fast/css/font-face-add-same-family-later.html [ Failure ]
+crbug.com/714962 fast/css/font-face-cache-version.html [ Failure ]
+crbug.com/714962 fast/css/getComputedStyle/getComputedStyle-zoom-and-background-size.html [ Failure ]
+crbug.com/714962 fast/css/heightless-list-item.html [ Failure ]
+crbug.com/714962 fast/css/hover-pseudo-element-quirks.html [ Failure ]
+crbug.com/714962 fast/css/inline-block-tricky-baselines.html [ Failure ]
+crbug.com/714962 fast/css/inline-table-first-row-empty-cell-non-auto.html [ Failure ]
+crbug.com/714962 fast/css/inline-table-first-row-non-empty-cell-non-auto-content.html [ Failure ]
+crbug.com/714962 fast/css/invalidation/add-first-line-style.html [ Failure ]
+crbug.com/714962 fast/css/invalidation/remove-first-line-style.html [ Failure ]
+crbug.com/714962 fast/css/invalidation/sheet-loaded-before-invalidation.html [ Failure ]
+crbug.com/714962 fast/css/invalidation/style-invalidation-before-attach.html [ Failure ]
 crbug.com/591099 fast/css/large-number-round-trip.html [ Crash ]
+crbug.com/714962 fast/css/object-fit-canvas.html [ Failure ]
+crbug.com/714962 fast/css/object-fit-embed.html [ Failure ]
+crbug.com/714962 fast/css/object-fit-img-svg.html [ Failure ]
+crbug.com/714962 fast/css/object-fit-img-svg2.html [ Failure ]
+crbug.com/714962 fast/css/object-fit-img.html [ Failure ]
+crbug.com/714962 fast/css/object-fit-input-image.html [ Failure ]
+crbug.com/714962 fast/css/object-fit-shrink.html [ Failure ]
+crbug.com/714962 fast/css/object-fit-video-poster.html [ Failure ]
 crbug.com/591099 fast/css/object-position-svg.html [ Crash Pass ]
+crbug.com/714962 fast/css/object-position-with-fit-contain.html [ Failure ]
+crbug.com/714962 fast/css/object-position-with-fit-cover.html [ Failure ]
+crbug.com/714962 fast/css/object-position-with-fit-none.html [ Failure ]
+crbug.com/714962 fast/css/object-position.html [ Failure ]
+crbug.com/714962 fast/css/outline-small-visual-overflow.html [ Failure ]
 crbug.com/591099 fast/css/placeholder-shown-basics.html [ Crash ]
 crbug.com/591099 fast/css/positioned-in-relative-position-inline-crash.html [ Crash ]
 crbug.com/591099 fast/css/pseudo-default-checkbox-radio.html [ Crash ]
@@ -5309,38 +5992,199 @@
 crbug.com/591099 fast/css/pseudo-required-optional-005.html [ Crash ]
 crbug.com/591099 fast/css/shadow-dom-scope.html [ Crash ]
 crbug.com/591099 fast/css/sticky/inline-sticky-abspos-child.html [ Crash ]
+crbug.com/714962 fast/css/sticky/replaced-sticky.html [ Failure ]
+crbug.com/714962 fast/css/sticky/sticky-both-sides-bottom-right-constrained.html [ Failure ]
+crbug.com/714962 fast/css/sticky/sticky-top-overflow.html [ Failure ]
 crbug.com/591099 fast/css/sticky/sticky-vertically-overconstrained.html [ Failure ]
+crbug.com/714962 fast/css/text-align-webkit-match-parent.html [ Failure ]
+crbug.com/714962 fast/css/text-overflow-ellipsis-vertical-hittest.html [ Timeout ]
 crbug.com/591099 fast/css/usecounter-summary-display-block.html [ Crash ]
+crbug.com/714962 fast/css/user-drag-none.html [ Crash ]
+crbug.com/714962 fast/css/whitespace-between-text-flex-preserve.html [ Failure ]
+crbug.com/714962 fast/css/whitespace-between-text-flex.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/repaint/repaint-text-decoration-style.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-decoration-style-inherit-links.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-decoration-style-inherit-simple-underlines.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-decoration-style-inherit.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-decoration-style.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-dynamic.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-subscript.html [ Crash ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow.html [ Failure ]
+crbug.com/714962 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-vertical.html [ Failure ]
+crbug.com/714962 fast/deprecated-flexbox/009.html [ Failure ]
+crbug.com/714962 fast/deprecated-flexbox/023.html [ Failure ]
+crbug.com/714962 fast/deprecated-flexbox/024.html [ Failure ]
+crbug.com/714962 fast/dnd/link-dragging-draggable-link.html [ Failure ]
+crbug.com/714962 fast/dom/Document/CaretRangeFromPoint/basic.html [ Failure ]
+crbug.com/714962 fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox.html [ Failure ]
+crbug.com/714962 fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-user-select-none.html [ Failure ]
+crbug.com/714962 fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll.html [ Failure ]
+crbug.com/714962 fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-with-first-letter-style.html [ Failure ]
+crbug.com/714962 fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport.html [ Failure ]
+crbug.com/714962 fast/dom/Document/CaretRangeFromPoint/replace-element.html [ Failure ]
+crbug.com/714962 fast/dom/Element/client-rect-list-argument.html [ Failure ]
+crbug.com/714962 fast/dom/Element/getClientRects.html [ Failure ]
 crbug.com/591099 fast/dom/HTMLDocument/object-by-name-or-id.html [ Crash ]
 crbug.com/591099 fast/dom/HTMLImageElement/fallback-image-moved-across-documents.html [ Failure ]
+crbug.com/714962 fast/dom/HTMLObjectElement/fallback-content-behaviour.html [ Failure ]
+crbug.com/714962 fast/dom/HTMLProgressElement/progress-writing-mode.html [ Failure ]
+crbug.com/714962 fast/dom/MutationObserver/observe-element-resize.html [ Failure ]
 crbug.com/591099 fast/dom/MutationObserver/shadow-dom.html [ Crash ]
+crbug.com/714962 fast/dom/Range/collapsed-range-bounding-client-rect.html [ Failure ]
+crbug.com/714962 fast/dom/Range/get-bounding-client-rect-empty-and-non-empty.html [ Timeout ]
+crbug.com/714962 fast/dom/Range/getBoundingClientRect-getClientRects-relative-to-viewport.html [ Failure ]
+crbug.com/714962 fast/dom/Range/getBoundingClientRect-linebreak-character.html [ Failure ]
+crbug.com/714962 fast/dom/Range/getBoundingClientRect.html [ Failure ]
+crbug.com/714962 fast/dom/Range/getClientRects-character.html [ Failure ]
+crbug.com/714962 fast/dom/Range/range-spanning-elements-bounding-client-rect.html [ Failure ]
+crbug.com/714962 fast/dom/Window/window-postmessage-clone-frames.html [ Failure Timeout ]
+crbug.com/714962 fast/dom/Window/window-postmessage-clone.html [ Failure ]
+crbug.com/714962 fast/dom/anchor-without-content.html [ Failure ]
+crbug.com/714962 fast/dom/elementFromPoint-relative-to-viewport.html [ Failure ]
+crbug.com/714962 fast/dom/elementFromPoint-scaled-scrolled.html [ Failure ]
+crbug.com/714962 fast/dom/elementsFromPoint/elementsFromPoint-inline.html [ Failure ]
+crbug.com/714962 fast/dom/empty-anchor-in-overflow-scroller.html [ Failure ]
+crbug.com/714962 fast/dom/inert/inert-inlines.html [ Failure ]
+crbug.com/714962 fast/dom/inert/inert-node-is-uneditable.html [ Failure ]
+crbug.com/714962 fast/dom/nodesFromRect/nodesFromRect-culled-inline-with-linebreak.html [ Failure ]
+crbug.com/714962 fast/dom/nodesFromRect/nodesFromRect-culled-inlines-between-silblings-bidi.html [ Failure ]
+crbug.com/714962 fast/dom/nodesFromRect/nodesFromRect-culled-inlines.html [ Failure ]
+crbug.com/714962 fast/dom/nodesFromRect/nodesFromRect-links-and-text.html [ Failure ]
+crbug.com/714962 fast/dom/nodesFromRect/nodesFromRect-svg.html [ Failure ]
+crbug.com/714962 fast/dom/search-shadow-host-crash.html [ Failure ]
+crbug.com/714962 fast/dom/shadow/content-pseudo-element-dynamic-attribute-change.html [ Failure ]
+crbug.com/714962 fast/dom/shadow/cppevent-input-in-shadow.html [ Failure ]
 crbug.com/591099 fast/dom/shadow/details-summary-distributed.html [ Crash ]
+crbug.com/714962 fast/dom/shadow/drop-event-for-input-in-shadow.html [ Failure ]
 crbug.com/591099 fast/dom/shadow/event-path-for-user-agent-shadow-tree.html [ Crash ]
 crbug.com/591099 fast/dom/shadow/focus-navigation-with-distributed-nodes.html [ Crash ]
 crbug.com/591099 fast/dom/shadow/form-in-shadow.html [ Crash ]
+crbug.com/714962 fast/dom/shadow/hover-active-drag-distributed-nodes.html [ Failure ]
+crbug.com/714962 fast/dom/shadow/import-rule-in-shadow-tree-needs-document-style-recalc.html [ Failure ]
+crbug.com/714962 fast/dom/shadow/input-color-in-content.html [ Timeout ]
 crbug.com/591099 fast/dom/shadow/normalize-progress-element-crash.html [ Crash ]
+crbug.com/714962 fast/dom/shadow/scrollbar.html [ Crash ]
+crbug.com/714962 fast/dom/shadow/select-in-shadowdom.html [ Failure ]
+crbug.com/714962 fast/dom/shadow/shadow-boundary-crossing.html [ Failure ]
 crbug.com/591099 fast/dom/shadow/shadow-contents-select.html [ Crash ]
+crbug.com/714962 fast/dom/shadow/touch-event.html [ Failure ]
+crbug.com/714962 fast/dom/shadow/wheel-event-on-input-in-shadow-dom.html [ Failure ]
 crbug.com/591099 fast/dynamic/continuation-detach-crash.html [ Crash ]
+crbug.com/714962 fast/dynamic/focus-clear-resolver-crash.html [ Failure ]
 crbug.com/591099 fast/dynamic/static-to-relative-with-absolute-child.html [ Crash ]
+crbug.com/714962 fast/events/autoscroll-disabled-in-fix.html [ Timeout ]
+crbug.com/714962 fast/events/autoscroll-upwards-propagation-overflow-hidden-body.html [ Failure ]
+crbug.com/714962 fast/events/click-checkbox-blur-refocus-window.html [ Failure ]
+crbug.com/714962 fast/events/click-checkbox-refocus-window.html [ Failure ]
+crbug.com/714962 fast/events/click-over-descendant-elements.html [ Crash Failure ]
+crbug.com/714962 fast/events/click-with-large-negative-text-indent.html [ Failure ]
+crbug.com/714962 fast/events/content-changed-during-drop.html [ Failure ]
+crbug.com/714962 fast/events/contextmenu-follows-focus.html [ Failure ]
+crbug.com/714962 fast/events/contextmenu-scrolled-page-with-frame.html [ Failure ]
+crbug.com/714962 fast/events/document-elementFromPoint.html [ Failure ]
+crbug.com/714962 fast/events/drag-and-drop-subframe-dataTransfer.html [ Timeout ]
+crbug.com/714962 fast/events/drag-dataTransferItemList-file-handling.html [ Failure ]
+crbug.com/714962 fast/events/drag-in-frames.html [ Failure ]
+crbug.com/714962 fast/events/event-on-culled-inline-with-pseudo.html [ Failure ]
+crbug.com/714962 fast/events/event-on-culled_inline.html [ Failure ]
+crbug.com/714962 fast/events/file-input-hidden-in-ondrop.html [ Timeout ]
+crbug.com/714962 fast/events/input-element-display-none-in-dragleave-crash.html [ Failure ]
+crbug.com/714962 fast/events/inputevents/inputevent-drag-drop.html [ Failure ]
+crbug.com/714962 fast/events/middleClickAutoscroll-click-hyperlink.html [ Timeout ]
+crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Timeout ]
+crbug.com/714962 fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ]
+crbug.com/714962 fast/events/mouse-events-on-textarea-resize.html [ Failure ]
 crbug.com/591099 fast/events/mouse-relative-position.html [ Failure ]
+crbug.com/714962 fast/events/mouseenter-mouseleave-inline-attributes.html [ Failure ]
+crbug.com/714962 fast/events/mouseenter-mouseleave.html [ Failure ]
+crbug.com/714962 fast/events/offsetX-offsetY.html [ Failure ]
+crbug.com/714962 fast/events/onchange-click-hang.html [ Failure ]
+crbug.com/714962 fast/events/pointerevents/mouse-node-remove.html [ Failure ]
+crbug.com/714962 fast/events/pointerevents/mouse-pointer-boundary-events-for-shadowdom.html [ Failure ]
+crbug.com/714962 fast/events/pointerevents/mouse-pointer-transition-events.html [ Failure ]
+crbug.com/714962 fast/events/pointerevents/mouse-pointer-updown-events.html [ Failure ]
+crbug.com/714962 fast/events/pointerevents/pointer-event-pen-coords-in-zoom-and-scroll.html [ Pass Timeout ]
+crbug.com/714962 fast/events/pointerevents/pointer-use-count.html [ Failure ]
+crbug.com/714962 fast/events/pointerevents/touch-pointer-events.html [ Failure ]
+crbug.com/714962 fast/events/pointerevents/touch-pointercancel.html [ Failure ]
+crbug.com/714962 fast/events/popup-blocked-from-untrusted-mouse-click.html [ Timeout ]
+crbug.com/714962 fast/events/popup-blocked-from-wrong-event.html [ Timeout ]
+crbug.com/714962 fast/events/simulated-click-coords.html [ Failure ]
 crbug.com/591099 fast/events/tabindex-focus-blur-all.html [ Crash ]
+crbug.com/714962 fast/events/touch/gesture/gesture-tap-input-after-composition.html [ Failure ]
+crbug.com/714962 fast/events/touch/gesture/gesture-tap-mouse-events.html [ Failure ]
+crbug.com/714962 fast/events/touch/gesture/gesture-tap-result.html [ Failure ]
 crbug.com/591099 fast/events/touch/touch-action-range-input-crash.html [ Crash ]
+crbug.com/714962 fast/events/touch/touch-before-pressing-spin-button.html [ Failure ]
 crbug.com/591099 fast/events/touch/touch-handler-assert-input-range.html [ Crash ]
 crbug.com/591099 fast/events/touch/touch-slider-no-js-touch-listener.html [ Crash ]
 crbug.com/591099 fast/events/wheel/latched-scroll-node-removed.html [ Pass ]
-crbug.com/591099 fast/files/apply-blob-url-to-img.html [ Failure ]
+crbug.com/714962 fast/events/wheel/wheelevent-basic.html [ Failure ]
+crbug.com/591099 fast/files/apply-blob-url-to-img.html [ Failure Timeout ]
+crbug.com/714962 fast/forms/25153.html [ Failure ]
 crbug.com/591099 fast/forms/access-key-for-all-elements.html [ Crash ]
+crbug.com/714962 fast/forms/button/button-generated-content.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-ar.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-coarse.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-minimum-date.html [ Failure Timeout ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-required-ar.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-required.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-ru.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-step.html [ Failure Timeout ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance-zoom200.html [ Failure Timeout ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-mouse-operations.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/calendar-picker-type-change-onclick.html [ Timeout ]
+crbug.com/714962 fast/forms/calendar-picker/month-picker-appearance-step.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/month-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/month-picker-mouse-operations.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/week-picker-appearance-step.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/week-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/calendar-picker/week-picker-mouse-operations.html [ Failure ]
+crbug.com/714962 fast/forms/checkbox/checkbox-focus-by-mouse.html [ Failure ]
+crbug.com/714962 fast/forms/color/input-color-chooser-shown-readonly.html [ Failure ]
+crbug.com/714962 fast/forms/color/input-color-chooser-shown.html [ Failure ]
+crbug.com/714962 fast/forms/cursor-at-editable-content-boundary.html [ Failure ]
 crbug.com/591099 fast/forms/datalist/input-appearance-range-with-datalist-rtl.html [ Crash ]
 crbug.com/591099 fast/forms/datalist/range-snap-to-datalist.html [ Crash ]
 crbug.com/591099 fast/forms/datalist/update-range-with-datalist.html [ Crash ]
+crbug.com/714962 fast/forms/date-multiple-fields/date-clearbutton-preventdefault-mousecapture-status.html [ Failure ]
+crbug.com/714962 fast/forms/date-multiple-fields/date-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/date-multiple-fields/date-multiple-fields-mouse-events.html [ Failure ]
+crbug.com/714962 fast/forms/date-multiple-fields/date-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/date/date-appearance-l10n.html [ Failure ]
+crbug.com/714962 fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-mouse-events.html [ Failure ]
+crbug.com/714962 fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/datetimelocal/datetimelocal-appearance-l10n.html [ Failure ]
+crbug.com/714962 fast/forms/disabled-mousedown-event.html [ Failure ]
 crbug.com/591099 fast/forms/fieldset/fieldset-elements.html [ Crash ]
+crbug.com/714962 fast/forms/file/file-cloneNode.html [ Timeout ]
+crbug.com/714962 fast/forms/file/file-input-change-event.html [ Failure ]
+crbug.com/714962 fast/forms/file/file-input-empty-validation.html [ Timeout ]
+crbug.com/714962 fast/forms/file/file-input-reset-validation.html [ Timeout ]
+crbug.com/714962 fast/forms/file/file-input-reset.html [ Failure ]
+crbug.com/714962 fast/forms/file/file-reset-in-change.html [ Failure ]
+crbug.com/714962 fast/forms/file/file-vertical-padding-border.html [ Failure ]
+crbug.com/714962 fast/forms/file/input-file-entries.html [ Timeout ]
+crbug.com/714962 fast/forms/file/input-file-value-with-zoom.html [ Failure ]
+crbug.com/714962 fast/forms/file/input-file-value.html [ Failure ]
+crbug.com/714962 fast/forms/file/input-file-write-files.html [ Failure ]
+crbug.com/714962 fast/forms/file/recover-file-input-in-unposted-form.html [ Failure Timeout ]
+crbug.com/714962 fast/forms/file/selected-files-from-history-state.html [ Failure ]
 crbug.com/591099 fast/forms/focus-with-display-block.html [ Crash ]
 crbug.com/591099 fast/forms/focus2.html [ Crash ]
 crbug.com/591099 fast/forms/form-collection-elements.html [ Crash ]
 crbug.com/591099 fast/forms/form-collection-radio-node-list.html [ Crash ]
 crbug.com/591099 fast/forms/hide-validation-message-crash.html [ Failure ]
 crbug.com/591099 fast/forms/indeterminate-input-types.html [ Crash ]
+crbug.com/714962 fast/forms/input-step-as-double.html [ Failure ]
+crbug.com/714962 fast/forms/label/continous-click-on-label.html [ Failure ]
+crbug.com/714962 fast/forms/label/hover-on-moving-mouse-checkbox-to-parent-label.html [ Failure ]
+crbug.com/714962 fast/forms/label/label-click.html [ Failure ]
 crbug.com/591099 fast/forms/label/label-contains-other-interactive-content.html [ Crash ]
+crbug.com/714962 fast/forms/label/label-selection-by-dragging.html [ Failure ]
 crbug.com/591099 fast/forms/label/labelable-elements.html [ Crash ]
 crbug.com/591099 fast/forms/label/labels-add-htmlFor-label.html [ Crash ]
 crbug.com/591099 fast/forms/label/labels-add-parent-label.html [ Crash ]
@@ -5352,7 +6196,22 @@
 crbug.com/591099 fast/forms/label/labels-remove-parent-label.html [ Crash ]
 crbug.com/591099 fast/forms/label/labels-set-htmlFor-attribute.html [ Crash ]
 crbug.com/591099 fast/forms/min-content-form-controls.html [ Crash ]
+crbug.com/714962 fast/forms/month-multiple-fields/month-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/month-multiple-fields/month-multiple-fields-mouse-events.html [ Failure ]
+crbug.com/714962 fast/forms/month-multiple-fields/month-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/month/month-appearance-l10n.html [ Failure ]
+crbug.com/714962 fast/forms/number/number-change-type-on-focus.html [ Failure ]
+crbug.com/714962 fast/forms/number/number-spinbutton-capturing.html [ Failure ]
+crbug.com/714962 fast/forms/number/number-spinbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/number/number-spinbutton-changeevent-trigger.html [ Failure ]
+crbug.com/714962 fast/forms/number/number-spinbutton-gets-disabled-or-readonly.html [ Failure ]
+crbug.com/714962 fast/forms/number/number-spinbutton-state.html [ Failure ]
+crbug.com/714962 fast/forms/password-placeholder-text-security.html [ Failure ]
 crbug.com/591099 fast/forms/percent-height-auto-width-form-controls.html [ Crash ]
+crbug.com/714962 fast/forms/placeholder-in-invisible-elements.html [ Failure ]
+crbug.com/714962 fast/forms/radio/radio-arrow-with-modifier-keys.html [ Failure ]
+crbug.com/714962 fast/forms/radio/radio-focus-by-mouse.html [ Failure ]
+crbug.com/714962 fast/forms/radio/radio-group-arrow-cycle-edge.html [ Failure ]
 crbug.com/591099 fast/forms/range/ValidityState-stepMismatch-range.html [ Crash ]
 crbug.com/591099 fast/forms/range/input-appearance-range-rtl.html [ Crash ]
 crbug.com/591099 fast/forms/range/input-range-progress-indicator.html [ Crash ]
@@ -5371,21 +6230,144 @@
 crbug.com/591099 fast/forms/range/range-value-rounding.html [ Crash ]
 crbug.com/591099 fast/forms/range/slider-hit-testing.html [ Crash ]
 crbug.com/591099 fast/forms/range/slider-zero-size-crash.html [ Crash ]
+crbug.com/714962 fast/forms/search/disabled-search-input.html [ Failure ]
+crbug.com/714962 fast/forms/search/search-cancel-button-events.html [ Failure ]
+crbug.com/714962 fast/forms/search/search-click-in-placeholder.html [ Failure ]
+crbug.com/714962 fast/forms/search/search-disabled-readonly.html [ Failure ]
+crbug.com/714962 fast/forms/search/search-hidden-cancel-button.html [ Failure ]
+crbug.com/714962 fast/forms/search/search-hide-cancel-on-cancel.html [ Failure ]
+crbug.com/714962 fast/forms/search/search-transformed.html [ Failure ]
+crbug.com/714962 fast/forms/search/search-zoomed.html [ Failure ]
+crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-coarse.html [ Failure ]
+crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-long.html [ Failure ]
+crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-many.html [ Failure ]
+crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-minimum-font.html [ Failure ]
+crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-styled.html [ Failure ]
+crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-transform.html [ Failure ]
+crbug.com/714962 fast/forms/select-popup/popup-menu-appearance-zoom.html [ Failure ]
+crbug.com/714962 fast/forms/select/remove-element-from-within-focus-handler-crash.html [ Failure ]
+crbug.com/714962 fast/forms/select/select-percent-width.html [ Failure ]
+crbug.com/714962 fast/forms/setrangetext-within-events.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/date-suggestion-picker-appearance-rtl.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar.html [ Crash ]
+crbug.com/714962 fast/forms/suggestion-picker/date-suggestion-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-locale-hebrew.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-rtl.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-with-scroll-bar.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/month-suggestion-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/time-suggestion-picker-appearance-with-scroll-bar.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/time-suggestion-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/week-suggestion-picker-appearance-with-scroll-bar.html [ Failure ]
+crbug.com/714962 fast/forms/suggestion-picker/week-suggestion-picker-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-appearance-autocomplete-suggested-value-over-placeholder-value.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-appearance-autocomplete-suggested-value-when-underlying-placeholder-is-removed.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-appearance-autocomplete-very-long-value.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-appearance-autocomplete-with-initial-value.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-appearance-autocomplete.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-placeholder-paint-order.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-readonly-focus.html [ Failure ]
+crbug.com/714962 fast/forms/text/input-select-on-click.html [ Failure ]
+crbug.com/714962 fast/forms/text/password-input-suggested-value-appearance.html [ Failure ]
+crbug.com/714962 fast/forms/text/placeholder-pseudo-style.html [ Failure ]
+crbug.com/714962 fast/forms/text/placeholder-with-positioned-element.html [ Failure ]
+crbug.com/714962 fast/forms/text/textfield-inside-anchor.html [ Failure ]
+crbug.com/714962 fast/forms/textarea/drag-out-of-textarea.html [ Failure ]
+crbug.com/714962 fast/forms/textarea/textarea-inline-block-baseline.html [ Failure ]
+crbug.com/714962 fast/forms/textarea/textarea-resize-above-min-size-and-below-initial-size.html [ Failure ]
+crbug.com/714962 fast/forms/textarea/textarea-resize-below-min-intrinsic-size.html [ Failure ]
+crbug.com/714962 fast/forms/textarea/textarea-resize-below-min-size-zoomed.html [ Failure ]
+crbug.com/714962 fast/forms/textarea/textarea-resize-below-min-size.html [ Failure ]
+crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-mouse-events.html [ Failure ]
+crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-narrow-width-scroll.html [ Failure ]
+crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/type-after-focus-rule-shrink-width.html [ Timeout ]
+crbug.com/714962 fast/forms/validation-bubble-appearance-rtl-ui.html [ Failure ]
+crbug.com/714962 fast/forms/week-multiple-fields/week-multiple-fields-clearbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/forms/week-multiple-fields/week-multiple-fields-mouse-events.html [ Failure ]
+crbug.com/714962 fast/forms/week-multiple-fields/week-multiple-fields-spinbutton-change-and-input-events.html [ Failure ]
+crbug.com/714962 fast/gradients/css3-color-stop-units.html [ Failure ]
+crbug.com/714962 fast/gradients/unprefixed-color-stop-units.html [ Failure ]
+crbug.com/714962 fast/harness/legacy-results.html [ Failure ]
 crbug.com/591099 fast/hidpi/broken-image-icon-hidpi.html [ Failure ]
-crbug.com/591099 fast/history/window-open.html [ Crash ]
+crbug.com/714962 fast/hidpi/clip-text-in-hidpi.html [ Failure ]
+crbug.com/714962 fast/history/visited-link-hover-background-color.html [ Failure ]
+crbug.com/714962 fast/history/visited-link-hover-border-color.html [ Failure ]
+crbug.com/714962 fast/history/visited-link-hover-emphasis-color.html [ Failure ]
+crbug.com/714962 fast/history/visited-link-hover-text-decoration-color.html [ Failure ]
+crbug.com/714962 fast/history/visited-link-hover-text-fill-color.html [ Failure ]
+crbug.com/714962 fast/history/visited-link-hover-text-stroke-color.html [ Failure ]
+crbug.com/714962 fast/history/visited-link-hover.html [ Failure ]
+crbug.com/591099 fast/history/window-open.html [ Crash Pass ]
 crbug.com/591099 fast/html/clone-range.html [ Crash ]
+crbug.com/714962 fast/html/layout-runs-and-floats-crash.html [ Failure ]
+crbug.com/714962 fast/html/meter-user-modify.html [ Failure ]
+crbug.com/714962 fast/inline-block/inline-block-vertical-align-2.html [ Failure ]
+crbug.com/714962 fast/inline-block/tricky-baseline.html [ Failure ]
+crbug.com/714962 fast/inline/continuation-outlines-with-layers-2.html [ Failure ]
 crbug.com/591099 fast/inline/continuation-positioned-reparenting.html [ Crash ]
 crbug.com/591099 fast/inline/inline-destroy-dirty-lines-crash.html [ Failure ]
+crbug.com/714962 fast/inline/inline-offsetLeft-continuation.html [ Failure ]
 crbug.com/591099 fast/inline/inline-position-top-align.html [ Failure ]
 crbug.com/591099 fast/inline/inline-width-containing-collapsed-whitespace-and-image-in-float.html [ Failure ]
 crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ]
+crbug.com/714962 fast/inline/outline-offset.html [ Failure ]
 crbug.com/591099 fast/lists/list-and-grid.html [ Failure ]
 crbug.com/591099 fast/lists/list-and-margin-collapse.html [ Failure ]
 crbug.com/591099 fast/lists/list-marker-inside-overflow-hidden.html [ Failure ]
 crbug.com/591099 fast/lists/remove-listmarker-from-anonblock-with-continuation-crash.html [ Crash ]
 crbug.com/591099 fast/loader/javascript-url-iframe-crash.html [ Crash ]
 crbug.com/591099 fast/media/mq-display-mode-fullscreen.html [ Crash ]
+crbug.com/714962 fast/multicol/change-height.html [ Failure ]
+crbug.com/714962 fast/multicol/content-change-same-height.html [ Failure ]
+crbug.com/714962 fast/multicol/event-offset-complex-tree.html [ Failure ]
+crbug.com/714962 fast/multicol/event-offset.html [ Failure ]
+crbug.com/714962 fast/multicol/float-truncation.html [ Failure ]
+crbug.com/714962 fast/multicol/focus-outline.html [ Crash ]
+crbug.com/714962 fast/multicol/huge-column-count.html [ Failure ]
+crbug.com/714962 fast/multicol/huge-column-gap-crash.html [ Failure ]
+crbug.com/714962 fast/multicol/input-type-number.html [ Failure ]
+crbug.com/714962 fast/multicol/layers-split-across-columns.html [ Failure ]
+crbug.com/714962 fast/multicol/multicol-becomes-abspos-crash.html [ Failure ]
+crbug.com/714962 fast/multicol/multicol-becomes-paged-fixed-height.html [ Failure ]
+crbug.com/714962 fast/multicol/nested-after-composited-layer-crash.html [ Failure ]
+crbug.com/714962 fast/multicol/newmulticol/balance-maxheight1.html [ Failure ]
+crbug.com/714962 fast/multicol/newmulticol/balance1.html [ Failure ]
+crbug.com/714962 fast/multicol/newmulticol/balance5.html [ Failure ]
+crbug.com/714962 fast/multicol/newmulticol/regular-block-becomes-multicol.html [ Failure ]
+crbug.com/714962 fast/multicol/paged-becomes-multicol-auto-height.html [ Failure ]
+crbug.com/714962 fast/multicol/paged-becomes-multicol-fixed-height.html [ Failure ]
+crbug.com/714962 fast/multicol/regular-block-becomes-multicol.html [ Failure ]
+crbug.com/714962 fast/multicol/scale-transform-text.html [ Failure ]
+crbug.com/714962 fast/multicol/span/update-after-content-before-child-crash.html [ Crash ]
+crbug.com/714962 fast/multicol/unbreakable-content-taller-than-height-crash.html [ Failure ]
+crbug.com/714962 fast/multicol/vertical-lr/float-truncation.html [ Failure ]
+crbug.com/714962 fast/multicol/vertical-rl/rule-style.html [ Failure ]
+crbug.com/714962 fast/overflow/001.html [ Failure ]
+crbug.com/714962 fast/overflow/002.html [ Failure ]
+crbug.com/714962 fast/overflow/005.html [ Failure ]
+crbug.com/714962 fast/overflow/006.html [ Failure ]
+crbug.com/714962 fast/overflow/childFocusRingClip.html [ Failure ]
+crbug.com/714962 fast/overflow/clip-rects-fixed-ancestor.html [ Failure ]
+crbug.com/714962 fast/overflow/dynamic-hidden.html [ Failure ]
+crbug.com/714962 fast/overflow/hidden-scrollbar-resize.html [ Failure ]
+crbug.com/714962 fast/overflow/line-clamp-hides-trailing-anchor.html [ Failure ]
+crbug.com/714962 fast/overflow/overflow-float-stacking.html [ Failure ]
+crbug.com/714962 fast/overflow/overflow-stacking.html [ Failure ]
+crbug.com/714962 fast/overflow/overflow-text-hit-testing.html [ Failure ]
 crbug.com/591099 fast/overflow/overflow-visible-should-ignore-scroll.html [ Failure ]
+crbug.com/714962 fast/overflow/overflow-x-y.html [ Failure ]
+crbug.com/714962 fast/overflow/scroll-div-hide-show.html [ Failure ]
+crbug.com/714962 fast/overflow/scrollRevealButton.html [ Failure ]
+crbug.com/714962 fast/pagination/caret-range-outside-paged-x-rtl-vertical-rl.html [ Failure ]
+crbug.com/714962 fast/pagination/caret-range-outside-paged-x-vertical-rl.html [ Failure ]
+crbug.com/714962 fast/pagination/caret-range-outside-paged-y-rtl.html [ Failure ]
+crbug.com/714962 fast/pagination/caret-range-outside-paged-y.html [ Failure ]
 crbug.com/591099 fast/pagination/div-x-vertical-lr-ltr.html [ Failure ]
 crbug.com/591099 fast/pagination/div-x-vertical-lr-rtl.html [ Failure ]
 crbug.com/591099 fast/pagination/modal-dialog-crash.html [ Crash ]
@@ -5408,7 +6390,7 @@
 crbug.com/591099 fast/parser/fonts.html [ Failure ]
 crbug.com/591099 fast/parser/innerhtml-with-prefixed-elements.xhtml [ Failure ]
 crbug.com/591099 fast/parser/nofoo-tags-inside-paragraph.html [ Failure ]
-crbug.com/591099 fast/parser/noscript-with-javascript-disabled.html [ Failure ]
+crbug.com/591099 fast/parser/noscript-with-javascript-disabled.html [ Crash Failure ]
 crbug.com/591099 fast/parser/open-comment-in-style.html [ Failure ]
 crbug.com/591099 fast/parser/open-comment-in-textarea.html [ Failure ]
 crbug.com/591099 fast/parser/stray-end-tags-with-attributes-002-alt-quirks.html [ Failure ]
@@ -5439,17 +6421,17 @@
 crbug.com/591099 fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr.html [ Failure ]
 crbug.com/591099 fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor.html [ Failure ]
 crbug.com/591099 fast/replaced/image-map-2.html [ Failure ]
-crbug.com/591099 fast/replaced/image-map-alt-content.html [ Failure ]
-crbug.com/591099 fast/replaced/image-map-bug16782.html [ Failure ]
-crbug.com/591099 fast/replaced/image-map-cursor.html [ Failure ]
-crbug.com/591099 fast/replaced/image-map-on-image-with-inline-content-data.html [ Failure ]
-crbug.com/591099 fast/replaced/image-map.html [ Failure ]
+crbug.com/591099 fast/replaced/image-map-alt-content.html [ Failure Pass ]
+crbug.com/591099 fast/replaced/image-map-bug16782.html [ Failure Pass ]
+crbug.com/591099 fast/replaced/image-map-cursor.html [ Failure Pass ]
+crbug.com/591099 fast/replaced/image-map-on-image-with-inline-content-data.html [ Failure Pass ]
+crbug.com/591099 fast/replaced/image-map.html [ Failure Pass ]
 crbug.com/591099 fast/replaced/max-width-percent.html [ Failure ]
 crbug.com/591099 fast/replaced/no-focus-ring-embed.html [ Timeout ]
 crbug.com/591099 fast/replaced/no-focus-ring-iframe.html [ Timeout ]
 crbug.com/591099 fast/replaced/no-focus-ring-object.html [ Timeout ]
 crbug.com/591099 fast/replaced/object-with-non-empty-classid-triggers-fallback.html [ Failure ]
-crbug.com/591099 fast/replaced/outline-replaced-elements.html [ Failure ]
+crbug.com/591099 fast/replaced/outline-replaced-elements.html [ Failure Pass ]
 crbug.com/591099 fast/replaced/percent-height-in-anonymous-block-in-table.html [ Failure ]
 crbug.com/591099 fast/replaced/percent-height-in-anonymous-block.html [ Failure ]
 crbug.com/591099 fast/replaced/preferred-widths.html [ Failure ]
@@ -5457,13 +6439,16 @@
 crbug.com/591099 fast/replaced/replaced-last-line-layout.html [ Crash ]
 crbug.com/591099 fast/replaced/selection-rect-in-table-cell.html [ Failure Pass ]
 crbug.com/591099 fast/replaced/selection-rect-transform.html [ Failure ]
-crbug.com/591099 fast/replaced/selection-rect.html [ Failure ]
+crbug.com/591099 fast/replaced/selection-rect.html [ Failure Pass ]
 crbug.com/591099 fast/replaced/table-percent-height.html [ Failure ]
 crbug.com/591099 fast/replaced/table-percent-width.html [ Failure Pass ]
 crbug.com/591099 fast/replaced/table-replaced-element.html [ Failure ]
 crbug.com/591099 fast/replaced/vertical-resize-100percent-element.html [ Failure ]
 crbug.com/591099 fast/replaced/vertical-rl/absolute-position-percentage-width.html [ Failure ]
+crbug.com/714962 fast/replaced/vertical-rl/absolute-position-with-auto-height-and-top-and-bottom.html [ Failure ]
+crbug.com/714962 fast/replaced/vertical-rl/absolute-position-with-auto-width-and-left-and-right.html [ Failure ]
 crbug.com/591099 fast/replaced/width100percent-image.html [ Failure Pass ]
+crbug.com/714962 fast/replaced/width100percent-textarea.html [ Failure ]
 crbug.com/591099 fast/rootscroller/set-root-scroller.html [ Failure ]
 crbug.com/591099 fast/ruby/add-text-to-block-ruby-with-after-pseudo-crash.html [ Crash ]
 crbug.com/591099 fast/ruby/base-shorter-than-text.html [ Failure ]
@@ -5471,7 +6456,7 @@
 crbug.com/591099 fast/ruby/float-overhang-from-ruby-text.html [ Failure ]
 crbug.com/591099 fast/ruby/floating-ruby-text.html [ Failure ]
 crbug.com/591099 fast/ruby/list-item-marker-in-block-ruby.html [ Crash ]
-crbug.com/591099 fast/ruby/merge-adjacent-anonymous-blocks-inside-ruby-run.html [ Failure ]
+crbug.com/591099 fast/ruby/merge-adjacent-anonymous-blocks-inside-ruby-run.html [ Failure Pass ]
 crbug.com/591099 fast/ruby/nested-ruby.html [ Failure ]
 crbug.com/591099 fast/ruby/overhang-horizontal-no-overlap1.html [ Failure ]
 crbug.com/591099 fast/ruby/overhang-horizontal-no-overlap2.html [ Failure ]
@@ -5508,6 +6493,8 @@
 crbug.com/591099 fast/ruby/rubyDOM-remove-text1.html [ Failure ]
 crbug.com/591099 fast/ruby/rubyDOM-remove-text2.html [ Failure ]
 crbug.com/591099 fast/ruby/select-ruby.html [ Failure ]
+crbug.com/714962 fast/scroll-behavior/scroll-iframe-into-view-twice.html [ Failure ]
+crbug.com/714962 fast/scroll-behavior/scroll-over-resizer.html [ Failure ]
 crbug.com/591099 fast/scroll-behavior/subframe-interrupted-scroll.html [ Failure Pass ]
 crbug.com/591099 fast/scrolling/content-box-smaller-than-scrollbar.html [ Failure ]
 crbug.com/591099 fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Crash ]
@@ -5516,6 +6503,12 @@
 crbug.com/591099 fast/scrolling/scroll-into-view-collapsed-div.html [ Failure ]
 crbug.com/591099 fast/scrolling/scroll-max-value.html [ Failure ]
 crbug.com/591099 fast/scrolling/scrollable-area-frame-overflow-hidden.html [ Failure ]
+crbug.com/714962 fast/scrolling/scrollable-area-frame-overried-inherited-visibility-hidden.html [ Failure ]
+crbug.com/714962 fast/scrolling/scrollable-area-frame-scrolling-yes.html [ Failure ]
+crbug.com/714962 fast/scrolling/scrollable-area-frame-visibility-hidden-child.html [ Failure ]
+crbug.com/714962 fast/scrolling/scrollable-area-frame.html [ Failure ]
+crbug.com/714962 fast/scrolling/scrollbar-tickmarks-styled-after-onload.html [ Failure ]
+crbug.com/714962 fast/scrolling/scrollbar-tickmarks-styled.html [ Failure ]
 crbug.com/591099 fast/selectors/018.html [ Failure ]
 crbug.com/591099 fast/selectors/018b.html [ Failure ]
 crbug.com/591099 fast/selectors/019.html [ Failure ]
@@ -5600,6 +6593,7 @@
 crbug.com/591099 fast/selectors/placeholder-shown-sibling-style-update.html [ Failure ]
 crbug.com/591099 fast/selectors/placeholder-shown-style-update.html [ Failure ]
 crbug.com/591099 fast/selectors/querySelector-in-range-crash.html [ Crash ]
+crbug.com/714962 fast/selectors/selection-window-inactive.html [ Failure ]
 crbug.com/591099 fast/selectors/shadow-host-div-with-span.html [ Failure ]
 crbug.com/591099 fast/selectors/shadow-host-div-with-text.html [ Failure ]
 crbug.com/591099 fast/selectors/unqualified-hover-quirks.html [ Failure ]
@@ -5672,38 +6666,126 @@
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-boxes-001.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-boxes-002.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-inset.html [ Crash Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-1st-stop.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-clipped-overflowed-content.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-container-only-white-space.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-container-white-space.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-date.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-div-scrollable-but-without-focusable-content.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-fully-aligned-horizontally.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-fully-aligned-vertically.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-hidden-focusable-element.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-hidden-iframe-zero-size.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-hidden-iframe.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-iframe-nested.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-iframe-no-focusable-content.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-iframe-no-scrollable-content.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-iframe-recursive-offset-parent.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html [ Failure Pass ]
+crbug.com/714962 fast/spatial-navigation/snav-imagemap-area-not-focusable.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-imagemap-area-without-image.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-imagemap-overlapped-areas.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-imagemap-simple.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-input.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-media-elements.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-multiple-select-focusring.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-multiple-select.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-offscreen-content.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-radio-group.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-radio.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-single-select-list.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-single-select.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-table-traversal.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-textarea.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-tiny-table-traversal.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-two-elements-one-line.html [ Failure ]
+crbug.com/714962 fast/spatial-navigation/snav-zero-margin-content.html [ Failure ]
 crbug.com/591099 fast/sub-pixel/computedstylemargin.html [ Failure ]
 crbug.com/591099 fast/sub-pixel/float-wrap-zoom.html [ Failure ]
+crbug.com/714962 fast/sub-pixel/inline-block-baseline.html [ Failure ]
 crbug.com/591099 fast/sub-pixel/inline-block-with-padding.html [ Failure ]
+crbug.com/714962 fast/sub-pixel/position-right-aligns-with-container.html [ Failure ]
 crbug.com/591099 fast/sub-pixel/repaint-subpixel-layer-in-subpixel-composited-layer.html [ Failure ]
 crbug.com/591099 fast/sub-pixel/should-not-repaint-subpixel-composited-layer.html [ Failure ]
+crbug.com/714962 fast/sub-pixel/size-of-span-with-different-positions.html [ Failure ]
 crbug.com/591099 fast/sub-pixel/sub-pixel-border-2.html [ Failure ]
+crbug.com/714962 fast/sub-pixel/sub-pixel-iframe-copy-on-scroll.html [ Failure ]
 crbug.com/591099 fast/sub-pixel/table-cells-with-padding-do-not-wrap.html [ Failure Pass ]
 crbug.com/591099 fast/sub-pixel/table-rtl-padding.html [ Failure Pass ]
+crbug.com/714962 fast/sub-pixel/transformed-iframe-copy-on-scroll.html [ Failure ]
+crbug.com/714962 fast/sub-pixel/width-of-inline-in-float.html [ Failure ]
+crbug.com/714962 fast/table/008.html [ Failure ]
 crbug.com/591099 fast/table/018.html [ Failure ]
 crbug.com/591099 fast/table/032.html [ Failure ]
+crbug.com/714962 fast/table/035-vertical.html [ Failure ]
+crbug.com/714962 fast/table/040-vertical.html [ Failure ]
+crbug.com/714962 fast/table/040.html [ Failure ]
+crbug.com/714962 fast/table/041.html [ Failure ]
+crbug.com/714962 fast/table/absolute-table-at-bottom.html [ Failure ]
 crbug.com/591099 fast/table/absolute-table-percent-lengths.html [ Failure ]
+crbug.com/714962 fast/table/auto-with-percent-height-vertical.html [ Failure ]
+crbug.com/714962 fast/table/auto-with-percent-height.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-cell-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-cell.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-column-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-column-group-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-column-group.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-column.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-quirks-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-quirks.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-row-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-row-group-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-row-group.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table-row.html [ Failure ]
+crbug.com/714962 fast/table/backgr_border-table.html [ Failure ]
+crbug.com/714962 fast/table/backgr_layers-hide-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_layers-hide.html [ Failure ]
 crbug.com/591099 fast/table/backgr_layers-opacity-collapsed-border.html [ Failure ]
 crbug.com/591099 fast/table/backgr_layers-opacity.html [ Failure ]
 crbug.com/591099 fast/table/backgr_layers-show-collapsed-border.html [ Failure ]
 crbug.com/591099 fast/table/backgr_layers-show.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-cell-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-cell.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-column-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-column-group-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-column-group.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-column.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-row-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-row-group-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-row-group.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table-row.html [ Failure ]
+crbug.com/714962 fast/table/backgr_position-table.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-cell-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-cell.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-column-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-column-group-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-column-group.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-column.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-row-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-row-group-collapsed-border.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-row-group.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table-row.html [ Failure ]
+crbug.com/714962 fast/table/backgr_simple-table.html [ Failure ]
 crbug.com/591099 fast/table/border-collapsing/001-vertical.html [ Failure Pass ]
+crbug.com/714962 fast/table/border-collapsing/001.html [ Failure ]
+crbug.com/714962 fast/table/border-collapsing/002-vertical.html [ Failure ]
+crbug.com/714962 fast/table/border-collapsing/002.html [ Failure ]
 crbug.com/591099 fast/table/border-collapsing/003-vertical.html [ Failure ]
 crbug.com/591099 fast/table/border-collapsing/004-vertical.html [ Failure ]
 crbug.com/591099 fast/table/border-collapsing/004.html [ Failure Pass ]
 crbug.com/591099 fast/table/border-collapsing/border-collapsing-head-foot-vertical.html [ Failure ]
+crbug.com/714962 fast/table/border-collapsing/border-collapsing-head-foot.html [ Failure ]
+crbug.com/714962 fast/table/border-collapsing/rtl-border-collapsing-vertical.html [ Failure ]
+crbug.com/714962 fast/table/border-collapsing/rtl-border-collapsing.html [ Failure ]
 crbug.com/591099 fast/table/change-col-border-width.html [ Failure ]
 crbug.com/591099 fast/table/change-row-border-width-floating-container.html [ Failure ]
 crbug.com/591099 fast/table/change-table-border-width.html [ Failure ]
 crbug.com/591099 fast/table/change-tbody-border-width.html [ Failure ]
 crbug.com/591099 fast/table/column-in-inline.html [ Failure ]
-crbug.com/591099 fast/table/convert-inline-to-table-cell.html [ Failure ]
+crbug.com/591099 fast/table/convert-inline-to-table-cell.html [ Failure Pass ]
 crbug.com/591099 fast/table/dynamic-descendant-percentage-height.html [ Failure ]
 crbug.com/591099 fast/table/empty-table-percent-height.html [ Failure ]
 crbug.com/591099 fast/table/fixed-table-layout/table-with-percent-width.html [ Failure ]
@@ -5711,8 +6793,13 @@
 crbug.com/591099 fast/table/form-with-table-style.html [ Failure ]
 crbug.com/591099 fast/table/height-percent-test-vertical.html [ Failure ]
 crbug.com/591099 fast/table/height-percent-test.html [ Failure ]
+crbug.com/714962 fast/table/hittest-tablecell-bottom-edge.html [ Failure ]
+crbug.com/714962 fast/table/hittest-tablecell-right-edge.html [ Failure ]
+crbug.com/714962 fast/table/hittest-tablecell-with-borders-bottom-edge.html [ Failure ]
+crbug.com/714962 fast/table/hittest-tablecell-with-borders-right-edge.html [ Failure ]
 crbug.com/591099 fast/table/incomplete-table-in-fragment-2.html [ Failure ]
 crbug.com/591099 fast/table/incomplete-table-in-fragment-hang.html [ Failure ]
+crbug.com/714962 fast/table/inline-table-in-inline-block-last-baseline-align.html [ Failure ]
 crbug.com/591099 fast/table/inline-table-margin-baseline.html [ Failure ]
 crbug.com/591099 fast/table/large-shrink-wrapped-width.html [ Failure ]
 crbug.com/591099 fast/table/min-max-width-preferred-size.html [ Failure Pass ]
@@ -5726,9 +6813,30 @@
 crbug.com/591099 fast/table/percent-widths-stretch-vertical.html [ Failure ]
 crbug.com/591099 fast/table/recalc-section-first-body-crash-main.html [ Failure ]
 crbug.com/591099 fast/table/row-in-inline-block.html [ Failure ]
+crbug.com/714962 fast/table/rowspan-paint-order-vertical.html [ Failure ]
+crbug.com/714962 fast/table/rowspan-paint-order.html [ Failure ]
+crbug.com/714962 fast/table/rtl-cell-display-none-assert.html [ Failure ]
+crbug.com/714962 fast/table/rules-attr-dynchange1.html [ Failure ]
+crbug.com/714962 fast/table/rules-attr-dynchange2.html [ Failure ]
+crbug.com/714962 fast/table/split-table-section-before-anonymous-block-2.html [ Failure ]
+crbug.com/714962 fast/table/split-table-section-before-anonymous-block-3.html [ Failure ]
+crbug.com/714962 fast/table/split-table-section-before-anonymous-block-4.html [ Failure ]
+crbug.com/714962 fast/table/table-after-child-in-table.html [ Failure ]
+crbug.com/714962 fast/table/table-and-parts-outline.html [ Failure ]
+crbug.com/714962 fast/table/table-before-child-in-table.html [ Failure ]
+crbug.com/714962 fast/table/table-cell-after-child-in-block.html [ Failure ]
+crbug.com/714962 fast/table/table-cell-after-child-in-table.html [ Failure ]
+crbug.com/714962 fast/table/table-cell-before-after-content-around-table-block.html [ Failure ]
+crbug.com/714962 fast/table/table-cell-before-after-content-around-table-row.html [ Failure ]
+crbug.com/714962 fast/table/table-cell-before-after-content-around-table.html [ Failure ]
+crbug.com/714962 fast/table/table-cell-before-child-in-block.html [ Failure ]
+crbug.com/714962 fast/table/table-cell-before-child-in-table.html [ Failure ]
 crbug.com/591099 fast/table/table-display-types-vertical.html [ Failure ]
 crbug.com/591099 fast/table/table-overflow-crash.html [ Pass ]
 crbug.com/591099 fast/table/table-parts-not-ortho-writing-mode-root.html [ Failure Timeout ]
+crbug.com/714962 fast/table/table-row-after-child-in-block.html [ Failure ]
+crbug.com/714962 fast/table/table-row-before-after-content-around-block.html [ Failure ]
+crbug.com/714962 fast/table/table-row-before-child-in-block.html [ Failure ]
 crbug.com/591099 fast/table/table-rowspan-table-height-and-row-precent-height-too-large.html [ Failure ]
 crbug.com/591099 fast/table/table-sections-border-spacing.html [ Failure ]
 crbug.com/591099 fast/table/table-split-positioned-object-crash.html [ Crash ]
@@ -5736,6 +6844,7 @@
 crbug.com/591099 fast/table/table-with-borderattr-null.html [ Failure ]
 crbug.com/591099 fast/table/table-with-borderattr-set-to-null.html [ Failure ]
 crbug.com/591099 fast/table/td-bordercolor-attribute.html [ Failure ]
+crbug.com/714962 fast/table/text-field-baseline.html [ Failure ]
 crbug.com/591099 fast/table/unbreakable-images-quirk.html [ Failure Pass ]
 crbug.com/591099 fast/table/unused-percent-heights.html [ Failure ]
 crbug.com/591099 fast/table/vertical-align-baseline-readjust.html [ Failure Pass ]
@@ -5791,7 +6900,20 @@
 crbug.com/591099 fast/text-autosizing/resize-window.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/similar-clusters.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/span-child.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/fixed-table-lots-of-text-many-cells.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/fixed-table-single-cell-lots-of-text.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/lots-of-text-many-cells.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/narrow-percentage-width.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/narrow-specified-width.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/nested-table-wrapping.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/nested-tables.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/single-cell-lots-of-text.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/single-percent-width-cell-lots-of-text.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/table-cell-inflation.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/table-for-layout.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/tables/table-with-inline-block.html [ Failure Pass ]
+crbug.com/714962 fast/text-autosizing/tables/wide-percentage-width.html [ Failure ]
+crbug.com/714962 fast/text-autosizing/tables/wide-specified-width.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/unwrappable-blocks.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/unwrappable-inlines.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/various-font-sizes.html [ Failure ]
@@ -5799,24 +6921,36 @@
 crbug.com/591099 fast/text-autosizing/wide-block.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/wide-child.html [ Failure ]
 crbug.com/591099 fast/text-autosizing/wide-in-narrow-overflow-scroll.html [ Failure ]
-crbug.com/591099 fast/text/atomic-inline-before-ellipsis.html [ Failure ]
+crbug.com/714962 fast/text/align-center-rtl-spill.html [ Failure ]
+crbug.com/591099 fast/text/atomic-inline-before-ellipsis.html [ Failure Pass ]
+crbug.com/714962 fast/text/atsui-multiple-renderers.html [ Failure ]
+crbug.com/714962 fast/text/basic/002.html [ Failure ]
 crbug.com/591099 fast/text/basic/007.html [ Failure Pass ]
+crbug.com/714962 fast/text/basic/009.html [ Failure ]
+crbug.com/714962 fast/text/basic/013.html [ Failure ]
 crbug.com/591099 fast/text/basic/015.html [ Failure ]
+crbug.com/714962 fast/text/basic/generic-family-changes.html [ Failure ]
+crbug.com/714962 fast/text/bidi-img-alt-text.html [ Failure ]
 crbug.com/591099 fast/text/break-word-with-floats.html [ Failure ]
 crbug.com/591099 fast/text/capitalize-boundaries.html [ Failure Pass ]
+crbug.com/714962 fast/text/cg-fallback-bolding.html [ Failure ]
 crbug.com/591099 fast/text/chromium-linux-fontconfig-renderstyle.html [ Failure ]
+crbug.com/714962 fast/text/color-emoji.html [ Failure ]
 crbug.com/591099 fast/text/complex-text-opacity.html [ Failure ]
 crbug.com/591099 fast/text/container-align-with-inlines.html [ Failure ]
-crbug.com/591099 fast/text/decorations-transformed.html [ Failure ]
+crbug.com/714962 fast/text/content-following-inline-isolate-with-collapsed-whitespace.html [ Failure ]
+crbug.com/591099 fast/text/decorations-transformed.html [ Failure Pass ]
 crbug.com/591099 fast/text/decorations-with-text-combine.html [ Failure ]
-crbug.com/591099 fast/text/descent-clip-in-scaled-page.html [ Failure ]
+crbug.com/591099 fast/text/descent-clip-in-scaled-page.html [ Failure Pass ]
+crbug.com/714962 fast/text/drawBidiText.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-at-edge-of-ltr-text-in-rtl-flow.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-at-edge-of-rtl-text-in-ltr-flow.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-in-absolute-block.html [ Failure ]
+crbug.com/714962 fast/text/ellipsis-in-justified-text.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-in-relative-inline-right.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-in-relative-inline.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-ltr-text-in-ltr-flow-underline.html [ Failure ]
-crbug.com/591099 fast/text/ellipsis-ltr-text-in-ltr-flow.html [ Failure ]
+crbug.com/591099 fast/text/ellipsis-ltr-text-in-ltr-flow.html [ Failure Pass ]
 crbug.com/591099 fast/text/ellipsis-ltr-text-in-rtl-flow-leading-space.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-ltr-text-in-rtl-flow-underline.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-ltr-text-in-rtl-flow.html [ Failure ]
@@ -5828,39 +6962,73 @@
 crbug.com/591099 fast/text/ellipsis-rtl-text-in-ltr-flow-underline.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-rtl-text-in-ltr-flow.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-rtl-text-in-rtl-flow-underline.html [ Failure ]
-crbug.com/591099 fast/text/ellipsis-rtl-text-in-rtl-flow.html [ Failure ]
-crbug.com/591099 fast/text/ellipsis-stroked.html [ Failure ]
+crbug.com/591099 fast/text/ellipsis-rtl-text-in-rtl-flow.html [ Failure Pass ]
+crbug.com/591099 fast/text/ellipsis-stroked.html [ Failure Pass ]
 crbug.com/591099 fast/text/ellipsis-with-list-marker-in-ltr-flow.html [ Failure ]
 crbug.com/591099 fast/text/ellipsis-with-list-marker-in-rtl-flow.html [ Failure ]
-crbug.com/591099 fast/text/emoji-web-font.html [ Pass ]
+crbug.com/591099 fast/text/emoji-web-font.html [ Failure Pass ]
+crbug.com/714962 fast/text/emoticons.html [ Failure ]
 crbug.com/591099 fast/text/emphasis-avoid-ruby.html [ Failure ]
 crbug.com/591099 fast/text/emphasis-combined-text.html [ Failure ]
 crbug.com/591099 fast/text/emphasis-complex.html [ Failure ]
 crbug.com/591099 fast/text/emphasis-ellipsis-complextext.html [ Failure ]
 crbug.com/591099 fast/text/emphasis-overlap.html [ Failure ]
+crbug.com/714962 fast/text/fake-italic.html [ Failure ]
 crbug.com/591099 fast/text/find-kana.html [ Timeout ]
+crbug.com/714962 fast/text/font-fallback-synthetic-italics.html [ Failure ]
+crbug.com/714962 fast/text/font-ligature-letter-spacing.html [ Failure ]
 crbug.com/591099 fast/text/font-smallcaps-layout.html [ Failure ]
+crbug.com/714962 fast/text/font-stretch-variant.html [ Failure ]
+crbug.com/714962 fast/text/font-stretch.html [ Failure ]
+crbug.com/714962 fast/text/font-variant-width.html [ Failure ]
+crbug.com/714962 fast/text/fractional-word-and-letter-spacing-with-kerning.html [ Failure ]
+crbug.com/714962 fast/text/get-client-rects-grapheme.html [ Failure ]
+crbug.com/714962 fast/text/glyph-reordering.html [ Failure ]
 crbug.com/591099 fast/text/hide-atomic-inlines-after-ellipsis.html [ Failure ]
+crbug.com/714962 fast/text/hyphen-min-preferred-width.html [ Failure ]
 crbug.com/591099 fast/text/international/002.html [ Failure Pass ]
 crbug.com/591099 fast/text/international/bidi-AN-after-empty-run.html [ Failure ]
+crbug.com/714962 fast/text/international/bidi-CS-after-AN.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-LDB-2-CSS.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-LDB-2-HTML.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-LDB-2-formatting-characters.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-ignored-for-first-child-inline.html [ Failure ]
+crbug.com/714962 fast/text/international/bidi-innertext.html [ Failure ]
+crbug.com/714962 fast/text/international/bidi-layout-across-linebreak.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-linebreak-001.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-linebreak-002.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-linebreak-003.html [ Failure ]
+crbug.com/714962 fast/text/international/bidi-listbox-atsui.html [ Failure ]
 crbug.com/591099 fast/text/international/bidi-mirror-he-ar.html [ Failure ]
-crbug.com/591099 fast/text/international/draw-complex-text-from-to.html [ Failure ]
+crbug.com/714962 fast/text/international/bidi-neutral-directionality-paragraph-start.html [ Failure ]
+crbug.com/714962 fast/text/international/bidi-override.html [ Failure ]
+crbug.com/714962 fast/text/international/cjk-segmentation.html [ Failure ]
+crbug.com/714962 fast/text/international/combining-marks-position.html [ Failure ]
+crbug.com/714962 fast/text/international/complex-character-based-fallback.html [ Failure ]
+crbug.com/714962 fast/text/international/danda-space.html [ Failure ]
+crbug.com/591099 fast/text/international/draw-complex-text-from-to.html [ Failure Pass ]
+crbug.com/714962 fast/text/international/hindi-whitespace.html [ Failure ]
 crbug.com/591099 fast/text/international/inline-plaintext-is-isolated.html [ Failure Pass ]
-crbug.com/591099 fast/text/international/rtl-negative-letter-spacing.html [ Failure ]
+crbug.com/714962 fast/text/international/iso-8859-8.html [ Failure ]
+crbug.com/714962 fast/text/international/listbox-width-rtl.html [ Failure ]
+crbug.com/714962 fast/text/international/plane2.html [ Failure ]
+crbug.com/591099 fast/text/international/rtl-negative-letter-spacing.html [ Failure Pass ]
+crbug.com/714962 fast/text/international/rtl-selection-rect-with-fallback.html [ Failure ]
 crbug.com/591099 fast/text/international/shape-across-elements.html [ Failure ]
 crbug.com/591099 fast/text/international/text-combine-image-test.html [ Failure ]
+crbug.com/714962 fast/text/international/thai-baht-space.html [ Failure ]
+crbug.com/714962 fast/text/international/unicode-bidi-plaintext-line-wrap.html [ Failure ]
+crbug.com/714962 fast/text/international/unicode-bidi-plaintext.html [ Failure ]
+crbug.com/714962 fast/text/international/vertical-text-glyph-test.html [ Failure ]
+crbug.com/714962 fast/text/international/vertical-text-metrics-test.html [ Failure ]
 crbug.com/591099 fast/text/justify-ideograph-vertical.html [ Failure ]
+crbug.com/714962 fast/text/justify-padding-distribution.html [ Failure ]
 crbug.com/591099 fast/text/large-text-composed-char.html [ Timeout ]
 crbug.com/591099 fast/text/letter-spacing-leading-and-trailing.html [ Crash ]
-crbug.com/591099 fast/text/long-word.html [ Failure ]
-crbug.com/591099 fast/text/offsetForPosition-cluster-at-zero.html [ Failure ]
+crbug.com/714962 fast/text/line-break-after-inline-latin1.html [ Failure ]
+crbug.com/591099 fast/text/long-word.html [ Failure Pass ]
+crbug.com/714962 fast/text/multiglyph-characters.html [ Failure ]
+crbug.com/591099 fast/text/offsetForPosition-cluster-at-zero.html [ Failure Pass ]
 crbug.com/591099 fast/text/orientation-sideways.html [ Failure ]
 crbug.com/591099 fast/text/place-ellipsis-in-inline-block-adjacent-float-2.html [ Failure ]
 crbug.com/591099 fast/text/place-ellipsis-in-inline-block-adjacent-float.html [ Failure ]
@@ -5885,32 +7053,62 @@
 crbug.com/591099 fast/text/place-rtl-ellipsis-in-inline-blocks-align-left.html [ Failure ]
 crbug.com/591099 fast/text/place-rtl-ellipsis-in-inline-blocks-align-right.html [ Failure ]
 crbug.com/591099 fast/text/place-rtl-ellipsis-in-inline-blocks.html [ Failure ]
+crbug.com/714962 fast/text/recalc-position-of-linebox-after-deleting-ellipsis.html [ Failure ]
+crbug.com/714962 fast/text/remove-zero-length-run.html [ Failure ]
+crbug.com/714962 fast/text/selection/atsui-partial-selection.html [ Failure ]
+crbug.com/714962 fast/text/selection/atsui-rtl-override-selection.html [ Failure ]
+crbug.com/714962 fast/text/selection/complex-text-rtl-selection-repaint.html [ Failure ]
+crbug.com/714962 fast/text/selection/flexbox-selection-nested.html [ Failure ]
 crbug.com/591099 fast/text/selection/flexbox-selection.html [ Failure ]
+crbug.com/714962 fast/text/selection/insert-text-crash.html [ Failure ]
+crbug.com/714962 fast/text/selection/justified-selection.html [ Failure ]
 crbug.com/591099 fast/text/selection/khmer-selection.html [ Failure ]
 crbug.com/591099 fast/text/selection/offsetForPosition-complex-fallback.html [ Failure ]
+crbug.com/714962 fast/text/selection/pre-wrap-overflow-selection.html [ Failure ]
+crbug.com/714962 fast/text/selection/reset-drag-on-mouse-down.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-hard-linebreak.html [ Failure ]
+crbug.com/714962 fast/text/selection/selection-multiple-runs.html [ Failure ]
+crbug.com/714962 fast/text/selection/selection-painted-separately.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-painting-hidpi.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-rect-line-height-too-big.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-rect-line-height-too-small.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-rect-rounding.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-with-inline-padding.html [ Failure ]
+crbug.com/714962 fast/text/selection/shaping-selection-rect.html [ Failure ]
+crbug.com/714962 fast/text/selection/should-use-atsui.html [ Failure ]
+crbug.com/714962 fast/text/selection/thai-offsetForPosition-inside-character.html [ Failure ]
 crbug.com/591099 fast/text/shaping/same-script-different-lang.html [ Failure ]
+crbug.com/714962 fast/text/stroking-decorations.html [ Failure ]
 crbug.com/591099 fast/text/sub-pixel/text-scaling-pixel.html [ Failure ]
+crbug.com/714962 fast/text/tab-min-size.html [ Failure ]
+crbug.com/714962 fast/text/text-between-two-brs-in-nowrap-overflow.html [ Failure ]
 crbug.com/591099 fast/text/text-letter-spacing.html [ Failure ]
+crbug.com/714962 fast/text/text-range-bounds.html [ Failure ]
 crbug.com/591099 fast/text/textIteratorNilRenderer.html [ Failure ]
 crbug.com/591099 fast/text/trailing-white-space-2.html [ Failure ]
 crbug.com/591099 fast/text/trailing-white-space.html [ Failure ]
+crbug.com/714962 fast/text/transform-text-first-line-capitalize.html [ Failure ]
+crbug.com/714962 fast/text/transform-text-first-line-lowercase.html [ Failure ]
+crbug.com/714962 fast/text/transform-text-first-line.html [ Failure ]
+crbug.com/714962 fast/text/unicode-fallback-font.html [ Failure ]
+crbug.com/714962 fast/text/wbr-styled.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/018.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/inline-whitespace-wrapping-3.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/inline-whitespace-wrapping-4.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/inline-whitespace-wrapping-5.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/normal-after-nowrap-breaking.html [ Failure ]
+crbug.com/714962 fast/text/whitespace/nowrap-line-break-after-white-space.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/pre-wrap-spaces-after-newline.html [ Failure ]
+crbug.com/714962 fast/text/whitespace/reattach-before-pseudo-nondistributed-whitespace.html [ Failure ]
+crbug.com/714962 fast/text/whitespace/reattach-before-pseudo-slot-fallback-whitespace.html [ Failure ]
+crbug.com/714962 fast/text/whitespace/reattach-before-pseudo.html [ Failure ]
+crbug.com/714962 fast/text/whitespace/reattach-slotted-whitespace.html [ Failure ]
 crbug.com/636993 fast/text/whitespace/text-align-justify-and-whitespace-pre.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/whitespace-in-pre.html [ Failure ]
-crbug.com/591099 fast/text/wide-preformatted.html [ Failure ]
+crbug.com/591099 fast/text/wide-preformatted.html [ Failure Pass ]
+crbug.com/714962 fast/text/word-break-soft-hyphen.html [ Failure ]
 crbug.com/591099 fast/text/word-break.html [ Failure ]
-crbug.com/591099 fast/text/word-space-between-inlines.html [ Failure ]
+crbug.com/591099 fast/text/word-space-between-inlines.html [ Failure Pass ]
 crbug.com/591099 fast/text/writing-root-with-overflow-clip-baseline.html [ Crash ]
 crbug.com/591099 fast/text/zero-width-characters-complex-script.html [ Failure ]
 crbug.com/591099 fast/text/zero-width-characters.html [ Failure ]
@@ -5923,25 +7121,38 @@
 crbug.com/591099 fast/tokenizer/nested-multiple-scripts.html [ Crash Pass ]
 crbug.com/591099 fast/tokenizer/script-after-frameset.html [ Failure ]
 crbug.com/591099 fast/tokenizer/script_extra_close.html [ Failure ]
-crbug.com/591099 fast/tokenizer/write-partial-entity.html [ Crash ]
+crbug.com/591099 fast/tokenizer/write-partial-entity.html [ Crash Pass ]
 crbug.com/591099 fast/url/degenerate-file-base.html [ Crash Pass ]
 crbug.com/591099 fast/workers/shared-worker-location.html [ Failure ]
 crbug.com/591099 fast/workers/worker-location.html [ Failure ]
 crbug.com/591099 fast/writing-mode/Kusa-Makura-background-canvas.html [ Failure ]
 crbug.com/591099 fast/writing-mode/auto-margins-across-boundaries.html [ Failure ]
 crbug.com/591099 fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ]
+crbug.com/714962 fast/writing-mode/background-vertical-lr.html [ Failure ]
 crbug.com/591099 fast/writing-mode/background-vertical-rl.html [ Failure ]
 crbug.com/591099 fast/writing-mode/basic-vertical-line.html [ Failure ]
 crbug.com/591099 fast/writing-mode/border-image-vertical-lr.html [ Failure ]
+crbug.com/714962 fast/writing-mode/border-image-vertical-rl.html [ Failure ]
 crbug.com/591099 fast/writing-mode/border-radius-clipping-vertical-lr.html [ Failure ]
+crbug.com/714962 fast/writing-mode/border-styles-vertical-lr.html [ Failure ]
+crbug.com/714962 fast/writing-mode/border-styles-vertical-rl.html [ Failure ]
+crbug.com/714962 fast/writing-mode/border-vertical-lr.html [ Failure ]
 crbug.com/591099 fast/writing-mode/borders.html [ Failure ]
-crbug.com/591099 fast/writing-mode/box-shadow-horizontal-tb-tile-edge.html [ Failure ]
+crbug.com/591099 fast/writing-mode/box-shadow-horizontal-tb-tile-edge.html [ Failure Pass ]
+crbug.com/714962 fast/writing-mode/broken-ideograph-small-caps.html [ Failure ]
+crbug.com/714962 fast/writing-mode/broken-ideographic-font.html [ Failure ]
+crbug.com/714962 fast/writing-mode/english-lr-text.html [ Failure ]
 crbug.com/591099 fast/writing-mode/english-rl-text.html [ Failure ]
 crbug.com/591099 fast/writing-mode/fieldsets.html [ Failure ]
+crbug.com/714962 fast/writing-mode/flipped-blocks-hit-test-line-edges.html [ Failure ]
 crbug.com/591099 fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ]
+crbug.com/714962 fast/writing-mode/flipped-blocks-text-map-local-to-container.html [ Failure ]
+crbug.com/714962 fast/writing-mode/japanese-lr-selection.html [ Failure ]
+crbug.com/714962 fast/writing-mode/japanese-rl-selection.html [ Failure ]
 crbug.com/591099 fast/writing-mode/japanese-ruby-vertical-lr.html [ Failure ]
 crbug.com/591099 fast/writing-mode/japanese-ruby-vertical-rl.html [ Failure ]
 crbug.com/591099 fast/writing-mode/logical-height-after-clear.html [ Failure ]
+crbug.com/714962 fast/writing-mode/orthogonal-inline-block.html [ Failure ]
 crbug.com/591099 fast/writing-mode/orthogonal-writing-modes-available-width-absolute-crash.html [ Failure ]
 crbug.com/591099 fast/writing-mode/orthogonal-writing-modes-in-layoutview-with-floats.html [ Crash ]
 crbug.com/591099 fast/writing-mode/percentage-height-orthogonal-writing-modes-quirks.html [ Failure ]
@@ -5954,7 +7165,9 @@
 crbug.com/591099 fast/writing-mode/text-combine-justify.html [ Failure ]
 crbug.com/591099 fast/writing-mode/text-combine-line-break.html [ Failure ]
 crbug.com/591099 fast/writing-mode/text-combine-various-fonts.html [ Failure ]
+crbug.com/714962 fast/writing-mode/text-orientation-basic.html [ Failure ]
 crbug.com/591099 fast/writing-mode/vertical-baseline-alignment.html [ Failure ]
+crbug.com/714962 fast/writing-mode/vertical-font-fallback.html [ Failure ]
 crbug.com/591099 fast/writing-mode/vertical-lr-replaced-selection.html [ Failure ]
 crbug.com/591099 fast/xmlhttprequest/xmlhttprequest-open-after-iframe-onload-remove-self.html [ Failure ]
 crbug.com/591099 fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html [ Failure ]
@@ -6072,13 +7285,13 @@
 crbug.com/591099 fragmentation/unbreakable-tall-float-before-block.html [ Failure ]
 crbug.com/591099 fragmentation/unbreakable-tall-float-before-line.html [ Failure ]
 crbug.com/591099 fullscreen/enter-exit-full-screen-hover.html [ Crash ]
-crbug.com/591099 fullscreen/exit-full-screen-iframe.html [ Timeout ]
+crbug.com/591099 fullscreen/exit-full-screen-iframe.html [ Pass Timeout ]
 crbug.com/591099 fullscreen/full-screen-css.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-element-stack.html [ Crash ]
-crbug.com/591099 fullscreen/full-screen-iframe-allowed-nested.html [ Timeout ]
-crbug.com/591099 fullscreen/full-screen-iframe-allowed.html [ Timeout ]
+crbug.com/591099 fullscreen/full-screen-iframe-allowed-nested.html [ Pass Timeout ]
+crbug.com/591099 fullscreen/full-screen-iframe-allowed.html [ Pass Timeout ]
 crbug.com/591099 fullscreen/full-screen-iframe-not-allowed.html [ Failure Timeout ]
-crbug.com/591099 fullscreen/full-screen-iframe-ua-style.html [ Timeout ]
+crbug.com/591099 fullscreen/full-screen-iframe-ua-style.html [ Pass Timeout ]
 crbug.com/591099 fullscreen/full-screen-remove-ancestor-after.html [ Crash Pass ]
 crbug.com/591099 fullscreen/full-screen-ruleset-crash.html [ Crash Pass ]
 crbug.com/591099 fullscreen/full-screen-twice-newapi.html [ Crash ]
@@ -6089,11 +7302,14 @@
 crbug.com/591099 fullscreen/model/fully-exit-fullscreen-nested-iframe.html [ Crash ]
 crbug.com/591099 fullscreen/non-ancestor-iframe.html [ Crash ]
 crbug.com/591099 hittesting/border-hittest-inlineFlowBox.html [ Failure ]
-crbug.com/591099 hittesting/hittest-child-of-inlineblock.html [ Failure ]
+crbug.com/714962 hittesting/border-hittest-with-image-fallback.html [ Failure ]
+crbug.com/714962 hittesting/culled-inline.html [ Failure ]
+crbug.com/591099 hittesting/hittest-child-of-inlineblock.html [ Failure Pass ]
 crbug.com/591099 hittesting/image-with-border-radius.html [ Failure ]
+crbug.com/714962 hittesting/image-with-clip-path.html [ Failure ]
 crbug.com/591099 hittesting/inline-with-clip-path.html [ Failure ]
 crbug.com/591099 hittesting/inner-border-radius-hittest.html [ Failure ]
-crbug.com/591099 hittesting/text-overflow-inline-image.html [ Timeout ]
+crbug.com/591099 hittesting/text-overflow-inline-image.html [ Pass Timeout ]
 crbug.com/591099 html/details_summary/details-add-child-1.html [ Crash ]
 crbug.com/591099 html/details_summary/details-add-child-2.html [ Crash ]
 crbug.com/591099 html/details_summary/details-add-details-child-1.html [ Crash ]
@@ -6207,6 +7423,8 @@
 crbug.com/591099 html/grouping_content/listing.html [ Failure ]
 crbug.com/591099 html/marquee/marquee-scroll.html [ Failure ]
 crbug.com/591099 html/marquee/marquee-scrollamount.html [ Failure ]
+crbug.com/714962 html/marquee/marquee-vspace-hspace.html [ Failure ]
+crbug.com/714962 html/sections/body-legacy-colors.html [ Timeout ]
 crbug.com/591099 html/tabular_data/col_width_resizing_table.html [ Failure ]
 crbug.com/591099 html/tabular_data/table_border_invalid.html [ Failure ]
 crbug.com/591099 html/tabular_data/table_createcaption.html [ Failure ]
@@ -6216,11 +7434,14 @@
 crbug.com/591099 http/tests/appcache/offline-access.html [ Failure ]
 crbug.com/591099 http/tests/cache/xhr-vary-header.html [ Failure ]
 crbug.com/591099 http/tests/css/css-image-valued-shape.html [ Failure ]
+crbug.com/714962 http/tests/css/css-resources-referrer-srcdoc.html [ Failure ]
 crbug.com/591099 http/tests/css/shape-image-file.html [ Failure ]
 crbug.com/591099 http/tests/csspaint/border-color.html [ Failure ]
 crbug.com/591099 http/tests/csspaint/invalidation-background-image.html [ Timeout ]
 crbug.com/591099 http/tests/csspaint/invalidation-border-image.html [ Timeout ]
 crbug.com/591099 http/tests/csspaint/invalidation-content-image.html [ Timeout ]
+crbug.com/714962 http/tests/devtools/animation/animation-group-matching-animations.js [ Crash ]
+crbug.com/714962 http/tests/devtools/animation/animation-group-matching-transitions.js [ Crash ]
 crbug.com/591099 http/tests/devtools/audits2/audits2-limited-run.js [ Crash ]
 crbug.com/591099 http/tests/devtools/audits2/audits2-successful-run.js [ Crash ]
 crbug.com/591099 http/tests/devtools/console/console-format.js [ Failure ]
@@ -6229,31 +7450,88 @@
 crbug.com/591099 http/tests/devtools/console/shadow-element.js [ Crash Timeout ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Crash Timeout ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Pass Timeout ]
+crbug.com/714962 http/tests/devtools/editor/text-editor-enter-behaviour.js [ Timeout ]
+crbug.com/714962 http/tests/devtools/editor/text-editor-formatter.js [ Timeout ]
+crbug.com/714962 http/tests/devtools/editor/text-editor-indent-autodetection.js [ Timeout ]
+crbug.com/714962 http/tests/devtools/editor/text-editor-reveal-line.js [ Timeout ]
+crbug.com/714962 http/tests/devtools/elements/breadcrumb-updates.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/css-rule-hover-highlights-selectors.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-1.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-2.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-3.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-4.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-shadow-2.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/edit-trimmed-attribute-value.js [ Crash Pass ]
+crbug.com/714962 http/tests/devtools/elements/edit/insert-node-collapsed.js [ Crash Pass ]
+crbug.com/714962 http/tests/devtools/elements/edit/remove-node.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/set-attribute.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/set-outer-html-2.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/set-outer-html-for-xhtml.xhtml [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/set-outer-html.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/undo-dom-edits-2.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/undo-dom-edits.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/undo-set-outer-html-2.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/edit/undo-set-outer-html.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/elements-linkify-attributes.js [ Crash Pass ]
+crbug.com/714962 http/tests/devtools/elements/elements-panel-limited-children.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/elements-panel-restore-selection-when-node-comes-later.js [ Failure ]
-crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-jquery1.js [ Failure ]
-crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-jquery2.js [ Failure ]
+crbug.com/714962 http/tests/devtools/elements/elements-panel-selection-after-delete.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/elements-treeoutline-copy.js [ Crash ]
+crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-jquery1.js [ Crash Failure ]
+crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-jquery2.js [ Crash Failure ]
 crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar.js [ Failure ]
+crbug.com/714962 http/tests/devtools/elements/hide-shortcut.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside-scroll.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside.js [ Failure ]
+crbug.com/714962 http/tests/devtools/elements/highlight/highlight-dom-updates.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scaled-and-scrolled.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scaled.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scroll.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node.js [ Failure ]
-crbug.com/591099 http/tests/devtools/elements/styles-3/styles-add-new-rule-tab.js [ Failure Pass ]
-crbug.com/591099 http/tests/devtools/elements/styles-3/styles-add-new-rule.js [ Failure Pass ]
-crbug.com/591099 http/tests/devtools/elements/styles-3/styles-change-node-while-editing.js [ Failure ]
+crbug.com/714962 http/tests/devtools/elements/iframe-load-event.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/insert-node.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/inspect-pseudo-element.js [ Timeout ]
+crbug.com/714962 http/tests/devtools/elements/modify-chardata.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/shadow/breadcrumb-shadow-roots.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/shadow/create-shadow-root.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/shadow/inspect-deep-shadow-element.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/shadow/shadow-distribution.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/shadow/shadow-host-display-modes.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-1/edit-value-url-with-color.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-2/force-pseudo-state.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-2/paste-property.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-2/pseudo-elements.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-3/styles-add-blank-property.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-3/styles-add-invalid-property.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-3/styles-add-new-rule-colon.js [ Crash ]
+crbug.com/591099 http/tests/devtools/elements/styles-3/styles-add-new-rule-tab.js [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/elements/styles-3/styles-add-new-rule.js [ Crash Failure Pass ]
+crbug.com/591099 http/tests/devtools/elements/styles-3/styles-change-node-while-editing.js [ Crash Failure ]
+crbug.com/714962 http/tests/devtools/elements/styles-3/styles-commit-editing.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/styles-3/styles-disable-inherited.js [ Failure Pass ]
+crbug.com/714962 http/tests/devtools/elements/styles-4/styles-live-locations-leak.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-4/styles-update-from-js.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/styles-4/svg-style.xhtml [ Failure ]
-crbug.com/591099 http/tests/devtools/extensions/extensions-network.html [ Failure ]
-crbug.com/591099 http/tests/devtools/extensions/extensions-sidebar.html [ Failure ]
-crbug.com/591099 http/tests/devtools/extensions/extensions-timeline-api.html [ Failure ]
+crbug.com/714962 http/tests/devtools/elements/styles-4/undo-add-new-rule.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles-4/undo-add-property.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles/stylesheet-tracking.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles/undo-change-property.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles/undo-property-toggle.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles/undo-set-selector-text.js [ Crash ]
+crbug.com/591099 http/tests/devtools/extensions/extensions-network.js [ Failure ]
+crbug.com/591099 http/tests/devtools/extensions/extensions-sidebar.js [ Failure ]
+crbug.com/591099 http/tests/devtools/extensions/extensions-timeline-api.js [ Failure ]
 crbug.com/591099 http/tests/devtools/indexeddb/resources-panel.js [ Failure Timeout ]
+crbug.com/714962 http/tests/devtools/jump-to-previous-editing-location.js [ Failure ]
+crbug.com/714962 http/tests/devtools/layers/layer-canvas-log.js [ Failure ]
 crbug.com/591099 http/tests/devtools/network/network-columns-visible.js [ Failure Timeout ]
 crbug.com/591099 http/tests/devtools/network/network-datareceived.js [ Failure ]
 crbug.com/591099 http/tests/devtools/network/network-disable-cache-preloads.php [ Failure ]
 crbug.com/591099 http/tests/devtools/persistence/automapping-sourcemap-nameclash.js [ Failure ]
 crbug.com/591099 http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js [ Failure Timeout ]
 crbug.com/591099 http/tests/devtools/runtime/runtime-getProperties.js [ Failure ]
+crbug.com/714962 http/tests/devtools/service-workers/service-workers-view.js [ Failure ]
 crbug.com/591099 http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js [ Failure Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-pause-in-internal.js [ Failure ]
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-pause-on-exception.js [ Failure Pass ]
@@ -6263,8 +7541,12 @@
 crbug.com/591099 http/tests/devtools/sources/debugger/properties-special.js [ Failure ]
 crbug.com/591099 http/tests/devtools/startup/console/console-format-startup.html [ Failure ]
 crbug.com/591099 http/tests/devtools/text-autosizing-override.js [ Failure ]
+crbug.com/714962 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Crash Failure ]
-crbug.com/591099 http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Crash ]
+crbug.com/714962 http/tests/devtools/tracing/timeline-misc/timeline-grouped-invalidations.js [ Failure ]
+crbug.com/591099 http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Crash Timeout ]
+crbug.com/714962 http/tests/devtools/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.js [ Failure ]
+crbug.com/714962 http/tests/devtools/tracing/timeline-paint/timeline-paint.js [ Failure ]
 crbug.com/591099 http/tests/devtools/websocket/network-preserve-selection-on-frame-receive.js [ Crash Pass ]
 crbug.com/591099 http/tests/feature-policy-experimental-features/vibrate-allowed-by-container-policy-relocate-and-no-reload.html [ Timeout ]
 crbug.com/591099 http/tests/feature-policy-experimental-features/vibrate-allowed-by-container-policy-relocate-and-reload.html [ Timeout ]
@@ -6275,9 +7557,9 @@
 crbug.com/591099 http/tests/feature-policy/fullscreen-disabled.php [ Pass ]
 crbug.com/591099 http/tests/feature-policy/payment-disabled.php [ Pass ]
 crbug.com/591099 http/tests/feature-policy/payment-enabledforall.php [ Pass ]
-crbug.com/591099 http/tests/filesystem/input-display.html [ Failure ]
-crbug.com/591099 http/tests/images/drag-image-to-desktop.html [ Timeout ]
-crbug.com/591099 http/tests/images/png-partial-load-as-document.html [ Failure ]
+crbug.com/591099 http/tests/filesystem/input-display.html [ Failure Timeout ]
+crbug.com/591099 http/tests/images/drag-image-to-desktop.html [ Pass Timeout ]
+crbug.com/591099 http/tests/images/png-partial-load-as-document.html [ Failure Pass ]
 crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure ]
 crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Pass Timeout ]
 crbug.com/591099 http/tests/incremental/slow-utf8-text.pl [ Pass Timeout ]
@@ -6293,8 +7575,17 @@
 crbug.com/591099 http/tests/local/file-url-sent-as-referer.html [ Failure ]
 crbug.com/591099 http/tests/local/fileapi/file-last-modified-after-delete.html [ Failure ]
 crbug.com/591099 http/tests/local/fileapi/file-last-modified.html [ Failure ]
+crbug.com/714962 http/tests/local/fileapi/select-dragged-file-input-utf-8.html [ Failure ]
 crbug.com/591099 http/tests/local/fileapi/send-dragged-file.html [ Failure ]
 crbug.com/591099 http/tests/local/fileapi/send-sliced-dragged-file.html [ Failure ]
+crbug.com/714962 http/tests/local/formdata/form-data-with-unknown-file-extension.html [ Failure ]
+crbug.com/714962 http/tests/local/formdata/send-form-data-constructed-from-form.html [ Timeout ]
+crbug.com/714962 http/tests/local/formdata/send-form-data-with-empty-file-filename.html [ Failure ]
+crbug.com/714962 http/tests/local/formdata/send-form-data-with-filename.html [ Failure ]
+crbug.com/714962 http/tests/local/formdata/send-form-data-with-sliced-file.html [ Failure ]
+crbug.com/714962 http/tests/local/formdata/send-form-data.html [ Failure ]
+crbug.com/714962 http/tests/local/formdata/upload-events.html [ Failure ]
+crbug.com/714962 http/tests/local/serviceworker/fetch-request-body-file.html [ Timeout ]
 crbug.com/591099 http/tests/media/progress-events-generated-correctly.html [ Failure ]
 crbug.com/591099 http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ]
 crbug.com/591099 http/tests/misc/acid2-pixel.html [ Failure ]
@@ -6320,14 +7611,22 @@
 crbug.com/591099 http/tests/navigation/form-targets-cross-site-frame-post.html [ Failure ]
 crbug.com/591099 http/tests/navigation/form-with-enctype-targets-cross-site-frame.html [ Failure ]
 crbug.com/591099 http/tests/navigation/history-back-across-form-submission-to-fragment.html [ Failure ]
-crbug.com/591099 http/tests/navigation/javascriptlink-basic.html [ Failure ]
-crbug.com/591099 http/tests/navigation/javascriptlink-goback.html [ Failure ]
+crbug.com/591099 http/tests/navigation/javascriptlink-basic.html [ Failure Timeout ]
+crbug.com/714962 http/tests/navigation/javascriptlink-frames.html [ Timeout ]
+crbug.com/591099 http/tests/navigation/javascriptlink-goback.html [ Failure Timeout ]
+crbug.com/714962 http/tests/navigation/javascriptlink-subframeload.html [ Timeout ]
 crbug.com/591099 http/tests/navigation/metaredirect-basic.html [ Failure ]
 crbug.com/591099 http/tests/navigation/metaredirect-goback.html [ Failure ]
 crbug.com/591099 http/tests/navigation/no-referrer-reset.html [ Failure ]
+crbug.com/714962 http/tests/navigation/no-referrer-subframe.html [ Timeout ]
 crbug.com/591099 http/tests/navigation/onload-navigation-iframe-2.html [ Failure ]
+crbug.com/714962 http/tests/navigation/ping-cookie.html [ Timeout ]
+crbug.com/714962 http/tests/navigation/ping-cross-origin-from-https.html [ Timeout ]
+crbug.com/714962 http/tests/navigation/ping-cross-origin.html [ Timeout ]
+crbug.com/714962 http/tests/navigation/ping-same-origin.html [ Timeout ]
 crbug.com/591099 http/tests/navigation/post-goback-same-url.html [ Failure ]
 crbug.com/591099 http/tests/navigation/post-goback2.html [ Failure ]
+crbug.com/714962 http/tests/navigation/post-with-modifier.html [ Timeout ]
 crbug.com/591099 http/tests/navigation/postredirect-basic.html [ Failure ]
 crbug.com/591099 http/tests/navigation/postredirect-frames.html [ Failure ]
 crbug.com/591099 http/tests/navigation/postredirect-goback1.html [ Failure ]
@@ -6350,6 +7649,10 @@
 crbug.com/591099 http/tests/permissions/test-api-surface.html [ Pass ]
 crbug.com/591099 http/tests/previews/client-lofi-sprite.html [ Failure ]
 crbug.com/591099 http/tests/security/XFrameOptions/x-frame-options-cached.html [ Failure ]
+crbug.com/714962 http/tests/security/anchor-download-allow-blob.html [ Failure ]
+crbug.com/714962 http/tests/security/anchor-download-allow-data.html [ Failure ]
+crbug.com/714962 http/tests/security/anchor-download-allow-sameorigin.html [ Failure ]
+crbug.com/714962 http/tests/security/anchor-download-block-crossorigin.html [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/1.1/form-action-blocked-when-target-blank.html [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/1.1/form-action-blocked-when-target-cross-site-window.html [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/1.1/form-action-src-blocked.html [ Failure ]
@@ -6363,24 +7666,25 @@
 crbug.com/591099 http/tests/security/contentSecurityPolicy/cached-frame-csp.html [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html [ Failure ]
-crbug.com/591099 http/tests/security/contentSecurityPolicy/frame-src-vs-shift-click.html [ Timeout ]
+crbug.com/591099 http/tests/security/contentSecurityPolicy/frame-src-vs-shift-click.html [ Pass Timeout ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/multiple-report-policies.php [ Failure ]
-crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-code-blocked.html [ Failure ]
-crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-movie-blocked.html [ Failure ]
-crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-src-blocked.html [ Failure ]
-crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-url-blocked.html [ Failure ]
+crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-code-blocked.html [ Failure Pass ]
+crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-movie-blocked.html [ Failure Pass ]
+crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-src-blocked.html [ Failure Pass ]
+crbug.com/591099 http/tests/security/contentSecurityPolicy/object-src-param-url-blocked.html [ Failure Pass ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/report-multiple-violations-01.php [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/script-src-none-inline-event.html [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Failure ]
 crbug.com/591099 http/tests/security/contentSecurityPolicy/xsl-img-blocked.php [ Failure ]
+crbug.com/714962 http/tests/security/cookies/third-party-cookie-blocking-user-action.html [ Timeout ]
 crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-appcache.html [ Crash Failure ]
 crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.html [ Crash Failure Pass ]
 crbug.com/591099 http/tests/security/cross-origin-indexeddb-allowed.html [ Failure ]
 crbug.com/591099 http/tests/security/cross-origin-worker-indexeddb-allowed.html [ Failure ]
-crbug.com/591099 http/tests/security/dataTransfer-set-data-file-url.html [ Timeout ]
+crbug.com/591099 http/tests/security/dataTransfer-set-data-file-url.html [ Failure Timeout ]
 crbug.com/591099 http/tests/security/dataURL/xss-DENIED-from-data-url-sub-frame-to-data-url-sub-frame.html [ Failure ]
-crbug.com/591099 http/tests/security/drag-drop-same-unique-origin.html [ Failure ]
-crbug.com/591099 http/tests/security/drag-over-remote-content-iframe.html [ Failure ]
+crbug.com/591099 http/tests/security/drag-drop-same-unique-origin.html [ Failure Pass ]
+crbug.com/591099 http/tests/security/drag-over-remote-content-iframe.html [ Failure Pass ]
 crbug.com/591099 http/tests/security/feed-urls-from-remote.html [ Failure ]
 crbug.com/591099 http/tests/security/filesystem-iframe-from-remote.html [ Failure ]
 crbug.com/591099 http/tests/security/frameNavigation/sandbox-ALLOWED-top-navigation-with-two-flags.html [ Timeout ]
@@ -6388,7 +7692,9 @@
 crbug.com/591099 http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change-async.html [ Timeout ]
 crbug.com/591099 http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change.html [ Timeout ]
 crbug.com/591099 http/tests/security/frameNavigation/xss-ALLOWED-targeted-subframe-navigation-change.html [ Failure ]
+crbug.com/714962 http/tests/security/frameNavigation/xss-ALLOWED-top-navigation-after-postMessage.html [ Timeout ]
 crbug.com/591099 http/tests/security/host-compare-case-insensitive.html [ Failure ]
+crbug.com/714962 http/tests/security/isolatedWorld/userGestureEvents.html [ Timeout ]
 crbug.com/591099 http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-to-javascript-url-sub-frame.html [ Failure ]
 crbug.com/591099 http/tests/security/listener/xss-JSTargetNode-onclick-addEventListener.html [ Failure ]
 crbug.com/591099 http/tests/security/listener/xss-JSTargetNode-onclick-shortcut.html [ Failure ]
@@ -6401,8 +7707,8 @@
 crbug.com/591099 http/tests/security/local-JavaScript-from-remote.html [ Failure ]
 crbug.com/591099 http/tests/security/local-iFrame-from-remote.html [ Failure ]
 crbug.com/591099 http/tests/security/local-image-from-remote.html [ Failure ]
-crbug.com/591099 http/tests/security/referrer-policy-redirect-link.html [ Timeout ]
-crbug.com/591099 http/tests/security/referrer-policy-rel-noreferrer.html [ Timeout ]
+crbug.com/591099 http/tests/security/referrer-policy-redirect-link.html [ Pass Timeout ]
+crbug.com/591099 http/tests/security/referrer-policy-rel-noreferrer.html [ Pass Timeout ]
 crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash Pass ]
 crbug.com/591099 http/tests/security/shape-image-cors-allow-origin.html [ Failure ]
 crbug.com/591099 http/tests/security/shape-image-cors-data-url.html [ Failure ]
@@ -6419,7 +7725,8 @@
 crbug.com/591099 http/tests/text-autosizing/narrow-iframe.html [ Failure ]
 crbug.com/591099 http/tests/text-autosizing/wide-iframe.html [ Failure ]
 crbug.com/591099 http/tests/uri/css-href.php [ Failure ]
-crbug.com/591099 http/tests/webaudio/autoplay-crossorigin.html [ Timeout ]
+crbug.com/591099 http/tests/webaudio/autoplay-crossorigin.html [ Pass Timeout ]
+crbug.com/714962 http/tests/webfont/font-display-intervention.html [ Failure ]
 crbug.com/591099 http/tests/websocket/invalid-subprotocol-characters.html [ Timeout ]
 crbug.com/591099 http/tests/workers/shared-worker-performance-timeline.html [ Pass ]
 crbug.com/591099 http/tests/xmlhttprequest/remember-bad-password.html [ Failure ]
@@ -6481,18 +7788,26 @@
 crbug.com/591099 ietestcenter/css3/bordersbackgrounds/color-behind-images.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/bordersbackgrounds/none-as-image-layer.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/bordersbackgrounds/order-of-images.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/flexbox/flexbox-layout-003.htm [ Failure Pass ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-block-formatting-context-001.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-containing-block-001.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-containing-block-002.htm [ Crash Failure Pass ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-containing-block-003.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/multicolumn/column-width-applies-to-001.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/multicolumn/column-width-applies-to-002.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/multicolumn/column-width-applies-to-003.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/multicolumn/column-width-applies-to-004.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-width-applies-to-007.htm [ Failure Pass ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-width-applies-to-008.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-width-applies-to-009.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-width-applies-to-010.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-width-applies-to-012.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/multicolumn/column-width-applies-to-013.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/multicolumn/column-width-applies-to-014.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/multicolumn/column-width-applies-to-015.htm [ Failure ]
 crbug.com/591099 ietestcenter/css3/text/textshadow-002.htm [ Failure ]
-crbug.com/591099 ietestcenter/css3/text/textshadow-009.htm [ Failure ]
+crbug.com/714962 ietestcenter/css3/text/textshadow-003.htm [ Failure ]
+crbug.com/591099 ietestcenter/css3/text/textshadow-009.htm [ Failure Pass ]
 crbug.com/591099 ietestcenter/css3/text/textshadow-010.htm [ Failure ]
 crbug.com/591099 imagecapture/MediaStreamTrack-getCapabilities.html [ Failure Pass ]
 crbug.com/591099 images/12-55.html [ Failure ]
@@ -6502,12 +7817,14 @@
 crbug.com/591099 images/55.html [ Failure ]
 crbug.com/591099 images/alt-text-wrapping.html [ Failure ]
 crbug.com/591099 images/color-jpeg-with-color-profile.html [ Failure ]
+crbug.com/714962 images/color-profile-background-clip-text.html [ Failure ]
+crbug.com/714962 images/color-profile-border-fade.html [ Failure ]
 crbug.com/591099 images/color-profile-border-image-source.html [ Failure ]
 crbug.com/591099 images/color-profile-border-radius.html [ Failure ]
-crbug.com/591099 images/color-profile-drag-image.html [ Failure ]
+crbug.com/591099 images/color-profile-drag-image.html [ Failure Pass ]
 crbug.com/591099 images/color-profile-filter.html [ Failure ]
 crbug.com/591099 images/color-profile-group.html [ Failure ]
-crbug.com/591099 images/color-profile-iframe.html [ Failure ]
+crbug.com/591099 images/color-profile-iframe.html [ Failure Pass ]
 crbug.com/591099 images/color-profile-image-filter-all.html [ Failure ]
 crbug.com/591099 images/color-profile-image-object-fit.html [ Failure ]
 crbug.com/591099 images/color-profile-image-profile-match.html [ Failure ]
@@ -6527,7 +7844,8 @@
 crbug.com/591099 images/cross-fade-svg-size-diff.html [ Failure ]
 crbug.com/591099 images/cross-fade-svg-size.html [ Failure ]
 crbug.com/591099 images/cross-fade-tiled.html [ Failure ]
-crbug.com/591099 images/drag-svg-image.html [ Failure ]
+crbug.com/714962 images/drag-image-transformed-parent.html [ Failure ]
+crbug.com/591099 images/drag-svg-image.html [ Failure Pass ]
 crbug.com/591099 images/embed-does-not-propagate-dimensions-to-object-ancestor.html [ Failure ]
 crbug.com/591099 images/exif-orientation-css.html [ Failure ]
 crbug.com/591099 images/exif-orientation-height-image-document.html [ Failure ]
@@ -6551,6 +7869,7 @@
 crbug.com/591099 images/image-map-zoom.html [ Failure ]
 crbug.com/591099 images/image-zoom-to-25.html [ Failure ]
 crbug.com/591099 images/imagemap-circle-focus-ring.html [ Failure ]
+crbug.com/714962 images/imagemap-duplicate-outlines-crash.html [ Failure ]
 crbug.com/591099 images/imagemap-focus-ring-in-positioned-container.html [ Failure ]
 crbug.com/591099 images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map.html [ Failure ]
 crbug.com/591099 images/imagemap-focus-ring-outline-color-not-inherited-from-map.html [ Failure ]
@@ -6582,9 +7901,11 @@
 crbug.com/591099 images/sprite-no-bleed.html [ Failure ]
 crbug.com/591099 images/webp-flip.html [ Failure ]
 crbug.com/591099 images/width-on-broken-data-src.html [ Failure ]
-crbug.com/591099 images/zoomed-img-size.html [ Crash ]
+crbug.com/591099 images/zoomed-img-size.html [ Crash Pass ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-ignoredNodes.js [ Failure Timeout ]
+crbug.com/714962 inspector-protocol/accessibility/accessibility-ignoredNodesModal.js [ Failure ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-modal.js [ Crash ]
+crbug.com/714962 inspector-protocol/accessibility/accessibility-nameSources-buttons.js [ Failure ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-img-figure.js [ Pass Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-input-buttons.js [ Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-input.js [ Timeout ]
@@ -6592,15 +7913,26 @@
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-summary.js [ Crash ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-visiblity.js [ Timeout ]
 crbug.com/591099 inspector-protocol/css/css-add-rule.js [ Pass Timeout ]
+crbug.com/714962 inspector-protocol/css/css-get-platform-fonts.js [ Failure ]
 crbug.com/591099 inspector-protocol/css/css-set-style-text.js [ Pass Timeout ]
+crbug.com/714962 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport.js [ Failure ]
 crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Timeout ]
 crbug.com/591099 inspector-protocol/emulation/device-emulation-small-dw.js [ Failure ]
 crbug.com/591099 inspector-protocol/emulation/device-emulation-small.js [ Failure ]
 crbug.com/591099 inspector-protocol/input/dispatchTouchEvent.js [ Pass Timeout ]
+crbug.com/714962 inspector-protocol/layers/paint-profiler.js [ Failure ]
+crbug.com/714962 inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang.js [ Failure ]
+crbug.com/714962 inspector-protocol/layout-fonts/generic-system-ui.js [ Failure ]
+crbug.com/714962 inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.js [ Failure ]
+crbug.com/714962 inspector-protocol/layout-fonts/ogham.js [ Failure ]
+crbug.com/714962 inspector-protocol/layout-fonts/prefix-fallback-multi-character-grapheme.js [ Failure ]
+crbug.com/714962 inspector-protocol/layout-fonts/tifinagh.js [ Failure ]
 crbug.com/591099 inspector-protocol/timeline/page-frames.js [ Failure Pass ]
 crbug.com/591099 intersection-observer/edge-inclusive-intersection.html [ Failure ]
 crbug.com/591099 intersection-observer/remove-element.html [ Failure ]
+crbug.com/714962 intersection-observer/root-margin.html [ Failure ]
 crbug.com/591099 intersection-observer/same-document-root.html [ Failure ]
+crbug.com/714962 jquery/offset.html [ Failure ]
 crbug.com/591099 media/autoplay/document-user-activation.html [ Failure ]
 crbug.com/591099 media/controls-drag-timebar-rendering.html [ Failure Pass ]
 crbug.com/591099 media/controls-timeline.html [ Failure ]
@@ -6614,8 +7946,12 @@
 crbug.com/591099 media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout ]
 crbug.com/591099 media/controls/video-overlay-cast-dark-rendering.html [ Failure ]
 crbug.com/591099 media/controls/video-overlay-cast-light-rendering.html [ Failure ]
+crbug.com/714962 media/controls/volumechange-stopimmediatepropagation.html [ Failure ]
 crbug.com/591099 media/media-document-audio-repaint.html [ Failure ]
 crbug.com/591099 media/track/track-cue-rendering-horizontal.html [ Failure ]
+crbug.com/714962 media/track/track-cue-rendering-position-auto-rtl.html [ Failure ]
+crbug.com/714962 media/track/track-cue-rendering-position-auto.html [ Failure ]
+crbug.com/714962 media/track/track-cue-rendering-transformed-video.html [ Failure ]
 crbug.com/591099 media/track/track-cue-rendering-vertical.html [ Failure ]
 crbug.com/591099 media/track/track-webvtt-non-snap-to-lines.html [ Failure ]
 crbug.com/591099 media/video-aspect-ratio.html [ Failure ]
@@ -6629,6 +7965,7 @@
 crbug.com/591099 media/video-poster-scale.html [ Failure ]
 crbug.com/591099 media/video-remove-insert-repaints.html [ Failure ]
 crbug.com/591099 media/video-replaces-poster.html [ Failure ]
+crbug.com/714962 media/video-src-blob.html [ Timeout ]
 crbug.com/591099 media/video-transformed.html [ Failure ]
 crbug.com/591099 media/video-zoom-controls.html [ Failure ]
 crbug.com/591099 media/video-zoom.html [ Failure ]
@@ -6636,17 +7973,22 @@
 crbug.com/591099 mhtml/image_document.mht [ Failure ]
 crbug.com/591099 mhtml/invalid-bad-boundary2.mht [ Failure ]
 crbug.com/591099 mhtml/malformed_mhtml_no_footer.mht [ Failure ]
+crbug.com/714962 mhtml/shared_buffer_bug.mht [ Failure ]
 crbug.com/591099 overflow/overflow-basic-002.html [ Pass ]
 crbug.com/591099 overflow/overflow-position-003.html [ Failure ]
 crbug.com/591099 overflow/overflow-transform-perspective.html [ Failure ]
 crbug.com/591099 paint/background/fieldset-legend-background-shadow-border-radius.html [ Failure ]
 crbug.com/591099 paint/background/rounded-clip-fractional-offset.html [ Failure ]
+crbug.com/714962 paint/clipath/clip-path-bigger-than-border-box-visual-rect.html [ Failure ]
+crbug.com/714962 paint/clipath/clip-path-bigger-than-visual-overflow.html [ Failure ]
 crbug.com/591099 paint/clipath/clip-path-with-background-and-box-behind.html [ Failure ]
 crbug.com/591099 paint/filters/clip-filter-overflow-clip.html [ Failure ]
 crbug.com/591099 paint/filters/clip-under-filter.html [ Failure ]
+crbug.com/714962 paint/float/float-text-clip.html [ Crash ]
 crbug.com/591099 paint/frames/frameset-with-stacking-context-and-not-stacking-context-children.html [ Failure ]
 crbug.com/591099 paint/frames/frameset-with-stacking-contexts.html [ Failure ]
 crbug.com/591099 paint/high-contrast-mode/image-filter-all/text-on-backgrounds.html [ Failure ]
+crbug.com/714962 paint/inline/floating-inline.html [ Crash ]
 crbug.com/591099 paint/inline/focus-ring-under-absolute-with-relative-continuation.html [ Failure ]
 crbug.com/591099 paint/inline/outline-offset.html [ Failure ]
 crbug.com/591099 paint/input/textarea-crash.html [ Crash ]
@@ -6666,6 +8008,7 @@
 crbug.com/591099 paint/invalidation/background/background-size-auto-with-gradient-and-height-changes.html [ Failure ]
 crbug.com/591099 paint/invalidation/background/backgroundSizeRepaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/background/body-background-image.html [ Failure ]
+crbug.com/714962 paint/invalidation/background/change-text-content-and-background-color.html [ Failure ]
 crbug.com/591099 paint/invalidation/background/multiple-backgrounds-style-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/background/view-background-from-body-2.html [ Failure ]
 crbug.com/591099 paint/invalidation/background/viewport-gradient-background-html-move-overflow.html [ Failure ]
@@ -6681,7 +8024,7 @@
 crbug.com/591099 paint/invalidation/box/border-radius-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/border-radius-without-border.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/border-repaint-glitch.html [ Failure ]
-crbug.com/591099 paint/invalidation/box/box-inline-resize.html [ Failure ]
+crbug.com/591099 paint/invalidation/box/box-inline-resize.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/box/box-shadow-add-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/box-shadow-change-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/box/box-shadow-dynamic.html [ Failure ]
@@ -6707,7 +8050,10 @@
 crbug.com/591099 paint/invalidation/bugzilla-6388.html [ Failure ]
 crbug.com/591099 paint/invalidation/bugzilla-6473.html [ Failure ]
 crbug.com/591099 paint/invalidation/bugzilla-7235.html [ Crash ]
-crbug.com/591099 paint/invalidation/button-inner-no-repaint.html [ Failure ]
+crbug.com/591099 paint/invalidation/button-inner-no-repaint.html [ Failure Pass ]
+crbug.com/714962 paint/invalidation/canvas-resize-no-full-invalidation.html [ Failure ]
+crbug.com/714962 paint/invalidation/caret-outside-block.html [ Failure ]
+crbug.com/714962 paint/invalidation/caret-subpixel.html [ Failure ]
 crbug.com/591099 paint/invalidation/clip/caret-ancestor-clip-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/clip/clip-path-constant-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/clip/clip-path-resize.html [ Failure ]
@@ -6719,6 +8065,7 @@
 crbug.com/591099 paint/invalidation/clip/intermediate-layout-position-clip.html [ Failure ]
 crbug.com/591099 paint/invalidation/clip/mask-clip-change-stacking-child.html [ Failure ]
 crbug.com/591099 paint/invalidation/clip/outline-clip-change.html [ Failure ]
+crbug.com/714962 paint/invalidation/clip/repaint-subsequence-on-ancestor-clip-change-complex.html [ Failure ]
 crbug.com/591099 paint/invalidation/clip/repaint-tile-clipped.html [ Crash ]
 crbug.com/591099 paint/invalidation/clip/replaced-clipped-positioned-not-wrong-incremental-repainting.html [ Failure ]
 crbug.com/591099 paint/invalidation/clip/resize-with-border-clipped.html [ Failure ]
@@ -6735,6 +8082,8 @@
 crbug.com/591099 paint/invalidation/compositing/composited-document-element.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/composited-float-under-composited-inline-individual.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/composited-float-under-composited-inline.html [ Failure ]
+crbug.com/714962 paint/invalidation/compositing/composited-inline-change-text-data-keep-geometry.html [ Crash ]
+crbug.com/714962 paint/invalidation/compositing/composited-non-stacking-context-not-invalidation-container.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/compositing-reason-removed.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/containing-block-added-individual.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/containing-block-added.html [ Failure ]
@@ -6807,6 +8156,7 @@
 crbug.com/591099 paint/invalidation/css-grid-layout/grid-item-z-index-change-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/delete-into-nested-block.html [ Failure ]
 crbug.com/591099 paint/invalidation/details-open-repaint.html [ Crash ]
+crbug.com/714962 paint/invalidation/empty-object-move-and-resize.html [ Failure ]
 crbug.com/591099 paint/invalidation/filters/effect-reference-repaint-composite-1.html [ Failure ]
 crbug.com/591099 paint/invalidation/filters/effect-reference-repaint-composite-2.html [ Failure ]
 crbug.com/591099 paint/invalidation/filters/effect-reference-repaint-composite-3.html [ Failure ]
@@ -6833,15 +8183,16 @@
 crbug.com/591099 paint/invalidation/filters/filter-repaint-accelerated-child-with-filter-child.html [ Failure ]
 crbug.com/591099 paint/invalidation/filters/filter-repaint-accelerated-on-accelerated-filter.html [ Failure ]
 crbug.com/591099 paint/invalidation/filters/filter-repaint-on-accelerated-layer.html [ Failure ]
+crbug.com/714962 paint/invalidation/first-line-inline-child.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-content-change-keeping-geometry.html [ Failure ]
-crbug.com/591099 paint/invalidation/flexbox/align-content-change-no-flex.html [ Failure ]
+crbug.com/591099 paint/invalidation/flexbox/align-content-change-no-flex.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/flexbox/align-content-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-content-distribution-change-grid.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-items-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-self-change-grid.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-self-change-keeping-geometry-grid.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-self-change-keeping-geometry.html [ Failure ]
-crbug.com/591099 paint/invalidation/flexbox/align-self-change-no-flex.html [ Failure ]
+crbug.com/591099 paint/invalidation/flexbox/align-self-change-no-flex.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/flexbox/align-self-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/justify-content-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/justify-content-distribution-change-grid.html [ Failure ]
@@ -6870,16 +8221,23 @@
 crbug.com/591099 paint/invalidation/forms/slider-thumb-drag-release.html [ Crash ]
 crbug.com/591099 paint/invalidation/forms/slider-thumb-float.html [ Crash ]
 crbug.com/591099 paint/invalidation/forms/submit-focus-by-mouse-then-keydown.html [ Failure ]
+crbug.com/714962 paint/invalidation/forms/textarea-appearance-none-resize-handle.html [ Failure ]
+crbug.com/714962 paint/invalidation/forms/textarea-caret.html [ Failure ]
+crbug.com/714962 paint/invalidation/forms/textarea-resize-property-change.html [ Failure ]
+crbug.com/714962 paint/invalidation/forms/textarea-set-disabled.html [ Failure ]
 crbug.com/591099 paint/invalidation/gradients-em-stops-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/iframe-display-block-to-display-none.html [ Failure ]
 crbug.com/591099 paint/invalidation/iframe-display-none-to-display-block.html [ Failure ]
 crbug.com/591099 paint/invalidation/iframe-rounding.html [ Failure ]
 crbug.com/591099 paint/invalidation/image/animated-gif-transformed-offscreen.html [ Failure ]
+crbug.com/714962 paint/invalidation/image/canvas-composite-repaint-by-all-imagesource.html [ Failure ]
+crbug.com/714962 paint/invalidation/image/percent-size-image-resize-container.html [ Failure ]
 crbug.com/591099 paint/invalidation/in-scaled-iframe.html [ Failure ]
 crbug.com/591099 paint/invalidation/inline-block-resize.html [ Failure ]
 crbug.com/591099 paint/invalidation/inline-color-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/inline-reflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/insert-frame.html [ Failure ]
+crbug.com/714962 paint/invalidation/invalidate-caret-before-text-node-update.html [ Failure ]
 crbug.com/591099 paint/invalidation/invalidate-descendants-when-receiving-paint-layer.html [ Failure ]
 crbug.com/591099 paint/invalidation/invalidate-invisible-element.html [ Failure ]
 crbug.com/591099 paint/invalidation/invalidation-after-opacity-change-subtree.html [ Failure ]
@@ -6904,6 +8262,7 @@
 crbug.com/591099 paint/invalidation/list-marker.html [ Failure ]
 crbug.com/591099 paint/invalidation/make-children-non-inline.html [ Failure ]
 crbug.com/591099 paint/invalidation/mix-blend-mode-separate-stacking-context.html [ Failure ]
+crbug.com/714962 paint/invalidation/multi-layout-one-frame.html [ Failure ]
 crbug.com/591099 paint/invalidation/multicol/column-float-under-stacked-inline.html [ Failure ]
 crbug.com/591099 paint/invalidation/multicol/column-rules-fixed-height.html [ Failure ]
 crbug.com/591099 paint/invalidation/multicol/multicol-as-paint-container.html [ Failure ]
@@ -6965,9 +8324,14 @@
 crbug.com/591099 paint/invalidation/overflow/fixed-position-transparency-with-overflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/flexible-box-overflow-horizontal.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/flexible-box-overflow.html [ Failure ]
-crbug.com/591099 paint/invalidation/overflow/float-overflow-right.html [ Failure ]
-crbug.com/591099 paint/invalidation/overflow/float-overflow.html [ Failure ]
+crbug.com/591099 paint/invalidation/overflow/float-overflow-right.html [ Crash Failure ]
+crbug.com/591099 paint/invalidation/overflow/float-overflow.html [ Crash Failure ]
+crbug.com/714962 paint/invalidation/overflow/inline-block-overflow-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/inline-block-overflow.html [ Failure ]
+crbug.com/714962 paint/invalidation/overflow/inline-box-overflow-repaint.html [ Failure ]
+crbug.com/714962 paint/invalidation/overflow/inline-overflow.html [ Failure ]
+crbug.com/714962 paint/invalidation/overflow/inline-vertical-lr-overflow.html [ Failure ]
+crbug.com/714962 paint/invalidation/overflow/inline-vertical-rl-overflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/justify-items-overflow-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/justify-self-overflow-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/line-overflow.html [ Failure ]
@@ -6975,9 +8339,11 @@
 crbug.com/591099 paint/invalidation/overflow/opacity-change-on-overflow-float.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/overflow-changed-on-child-of-composited-layer.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/overflow-clip-subtree-layout.html [ Failure ]
+crbug.com/714962 paint/invalidation/overflow/overflow-delete-line.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/overflow-hidden-to-visible.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/overflow-hide.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/overflow-into-content.html [ Failure ]
+crbug.com/714962 paint/invalidation/overflow/overflow-outline-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/overflow-show.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/paged-with-overflowing-block-rl.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/rel-positioned-inline-with-overflow.html [ Failure ]
@@ -6989,6 +8355,7 @@
 crbug.com/591099 paint/invalidation/overflow/vertical-overflow-same.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/vertical-rl-overflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/overhanging-float-detach-repaint.html [ Failure ]
+crbug.com/714962 paint/invalidation/paint-caret-in-div-with-negative-indent.html [ Failure ]
 crbug.com/591099 paint/invalidation/paint-invalidation-with-opacity.html [ Failure ]
 crbug.com/591099 paint/invalidation/paint-invalidation-with-reparent-across-frame-boundaries.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/absolute-display-block-to-none.html [ Failure ]
@@ -7020,16 +8387,16 @@
 crbug.com/591099 paint/invalidation/position/positioned-document-element.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/positioned-great-grandparent-change-location.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/positioned-list-offset-change-repaint.html [ Failure ]
-crbug.com/591099 paint/invalidation/position/relative-inline-positioned-movement-repaint.html [ Failure ]
+crbug.com/591099 paint/invalidation/position/relative-inline-positioned-movement-repaint.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/position/relative-margin-change-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/relative-positioned-movement-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/relayout-fixed-position-after-scale.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/shift-relative-positioned-container-with-image-addition.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/shift-relative-positioned-container-with-image-removal.html [ Failure ]
 crbug.com/591099 paint/invalidation/position/static-to-positioned.html [ Failure ]
-crbug.com/591099 paint/invalidation/position/text-in-relative-positioned-inline.html [ Failure ]
+crbug.com/591099 paint/invalidation/position/text-in-relative-positioned-inline.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/position/transform-absolute-child.html [ Failure ]
-crbug.com/591099 paint/invalidation/position/transform-absolute-in-positioned-container.html [ Failure ]
+crbug.com/591099 paint/invalidation/position/transform-absolute-in-positioned-container.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/position/transform-relative-position.html [ Failure ]
 crbug.com/591099 paint/invalidation/push-block-with-first-line.html [ Failure ]
 crbug.com/591099 paint/invalidation/quotes.html [ Failure ]
@@ -7045,6 +8412,7 @@
 crbug.com/591099 paint/invalidation/remove-inline-after-layout.html [ Failure ]
 crbug.com/591099 paint/invalidation/remove-inline-layer-after-layout.html [ Failure ]
 crbug.com/591099 paint/invalidation/renderer-destruction-by-invalidateSelection-crash.html [ Failure ]
+crbug.com/714962 paint/invalidation/repaint-across-writing-mode-boundary.html [ Failure ]
 crbug.com/591099 paint/invalidation/repaint-descandant-on-ancestor-layer-move.html [ Failure ]
 crbug.com/591099 paint/invalidation/repaint-in-iframe.html [ Failure ]
 crbug.com/591099 paint/invalidation/repaint-on-style-change.html [ Failure ]
@@ -7054,6 +8422,7 @@
 crbug.com/591099 paint/invalidation/requestAnimation-translation-leave-traces.html [ Failure ]
 crbug.com/591099 paint/invalidation/resize-iframe-text.html [ Failure ]
 crbug.com/591099 paint/invalidation/ruby-flipped-blocks.html [ Failure ]
+crbug.com/714962 paint/invalidation/scroll/caret-invalidation-in-overflow-scroll.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/caret-with-composited-scroll.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/composited-add-resizer.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/composited-iframe-scroll-repaint.html [ Failure ]
@@ -7067,6 +8436,7 @@
 crbug.com/591099 paint/invalidation/scroll/fixed-child-of-transformed-move-after-scroll.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/fixed-child-of-transformed-scrolled.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/fixed-descendant-of-transformed-scrolled.html [ Failure ]
+crbug.com/714962 paint/invalidation/scroll/fixed-img-src-change-after-scroll.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/fixed-move-after-scroll.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/fixed-scroll-simple.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/fixed-under-composited-absolute-scrolled.html [ Crash ]
@@ -7074,9 +8444,12 @@
 crbug.com/591099 paint/invalidation/scroll/fixed-with-border-under-composited-absolute-scrolled.html [ Crash ]
 crbug.com/591099 paint/invalidation/scroll/flipped-blocks-writing-mode-scroll.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/iframe-scroll-repaint.html [ Failure ]
+crbug.com/714962 paint/invalidation/scroll/iframe-scrollbar-hover.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/inline-style-change-in-scrolled-view.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/invalidate-after-composited-scroll-of-window.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/invalidate-after-composited-scroll.html [ Failure ]
+crbug.com/714962 paint/invalidation/scroll/invalidate-caret-in-composited-scrolling-container.html [ Failure ]
+crbug.com/714962 paint/invalidation/scroll/invalidate-caret-in-non-composited-scrolling-container.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/layout-state-scrolloffset.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/layout-state-scrolloffset2.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/layout-state-scrolloffset3.html [ Failure ]
@@ -7114,6 +8487,7 @@
 crbug.com/591099 paint/invalidation/scroll/scrollbar-invalidation-on-resize.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/scrollbar-parts.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/scrolled-iframe-scrollbar-change.html [ Failure ]
+crbug.com/714962 paint/invalidation/search-field-cancel.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/block-selection-gap-stale-cache-2.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/block-selection-gap-stale-cache.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline-for-rtl.html [ Failure ]
@@ -7123,36 +8497,98 @@
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-with-br-includes-newline.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/japanese-rl-selection-clear.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/japanese-rl-selection-repaint.html [ Failure ]
+crbug.com/714962 paint/invalidation/selection/repaint-rect-for-vertical-writing-mode-with-positioned-root.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/selected-replaced.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/selection-after-delete.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/selection-after-remove.html [ Failure ]
+crbug.com/714962 paint/invalidation/selection/selection-and-text-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/selection-change-in-iframe-with-relative-parent.html [ Failure ]
-crbug.com/591099 paint/invalidation/selection/selection-clear-after-move.html [ Failure ]
+crbug.com/591099 paint/invalidation/selection/selection-clear-after-move.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/selection/selection-clear.html [ Failure ]
+crbug.com/714962 paint/invalidation/selection/selection-in-composited-scrolling-container.html [ Failure ]
+crbug.com/714962 paint/invalidation/selection/selection-in-non-composited-scrolling-container.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/selection-partial-invalidation-between-blocks.html [ Failure Pass ]
+crbug.com/714962 paint/invalidation/selection/selection-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/selection-rl.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/selection-within-composited-scroller.html [ Failure ]
+crbug.com/714962 paint/invalidation/selection/text-selection-rect-in-overflow-2.html [ Failure ]
+crbug.com/714962 paint/invalidation/selection/text-selection-rect-in-overflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/shadow-multiple.html [ Failure ]
 crbug.com/591099 paint/invalidation/stacked-diacritics.html [ Failure ]
 crbug.com/591099 paint/invalidation/stacking-context-lost.html [ Failure ]
 crbug.com/591099 paint/invalidation/subtree-root-skipped.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/absolute-sized-content-with-resources.xhtml [ Failure ]
+crbug.com/714962 paint/invalidation/svg/absolute-sized-document-no-scrollbars.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/add-background-property-on-root.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/add-border-property-on-root.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/add-outline-property-on-root.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/animate-fill.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/animated-path-inside-transformed-html.xhtml [ Failure Pass ]
 crbug.com/591099 paint/invalidation/svg/animated-svg-as-image-transformed-offscreen.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/append-text-node-to-tspan.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/clip-path-child-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/clip-path-href-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/clip-path-id-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/clip-path-units-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/container-repaint.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/deep-dynamic-updates.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/deep-nested-embedded-svg-size-changes-no-layout-triggers-1.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/deep-nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/embedded-svg-size-changes-no-layout-triggers.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/ems-display-none.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/exs-display-none.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/feImage-remove-target.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/feImage-target-attribute-change-with-use-indirection.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/feImage-target-inline-style-change.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/feImage-target-reappend-to-document.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/feImage-target-remove-from-document.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/feImage-target-style-change.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/filter-child-repaint.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/filter-refresh.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/foreign-object-repaint.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/hairline-stroke-squarecap.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/hit-test-with-br.xhtml [ Failure ]
+crbug.com/714962 paint/invalidation/svg/image-with-clip-path.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/inner-svg-change-viewBox-contract.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/inner-svg-change-viewBox.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/inner-svg-change-viewPort-relative.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/invalidate-on-child-layout.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-clipPath-and-object-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-clipPath-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-gradient-and-object-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-gradient-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-marker-and-object-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-mask-and-object-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-mask-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-pattern-and-object-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-late-pattern-creation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-repaint-rect-on-path-with-stroke.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-update-bounce.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-update-container.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-update-image.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-update-style.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-update-transform-addition.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/js-update-transform-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/marker-strokeWidth-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/marker-viewBox-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/mask-child-changes.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/mask-clip-target-transform.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/mask-invalidation.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/modify-inserted-listitem.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/modify-text-node-in-tspan.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/modify-transferred-listitem-different-attr.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-1.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Crash Failure ]
-crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes.html [ Failure ]
+crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size.xhtml [ Failure ]
+crbug.com/714962 paint/invalidation/svg/outline-offset-text.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/overflow-repaint.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/paintorder-filtered.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/pending-resource-after-removal.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/relative-sized-content-with-resources.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/relative-sized-content.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/relative-sized-deep-shadow-tree-content.xhtml [ Failure ]
+crbug.com/714962 paint/invalidation/svg/relative-sized-document-scrollbars.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/relative-sized-image.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/relative-sized-inner-svg.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol.xhtml [ Failure ]
@@ -7160,21 +8596,53 @@
 crbug.com/591099 paint/invalidation/svg/relative-sized-use-on-symbol.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/relative-sized-use-without-attributes-on-symbol.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/remove-background-property-on-root.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/remove-border-property-on-root.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/remove-outline-property-on-root.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/remove-text-node-from-tspan.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/remove-tspan-from-text.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/repaint-moving-svg-and-div.xhtml [ Failure ]
+crbug.com/714962 paint/invalidation/svg/repaint-non-scaling-stroke-text-decoration.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/repaint-non-scaling-stroke-text.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/repaint-on-image-bounds-change.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/repaint-paintorder.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/repaint-svg-after-style-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/resize-svg-invalidate-children-2.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/resize-svg-invalidate-children.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/resource-client-removal.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/resource-invalidate-on-target-update.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/scroll-hit-test.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/shape-transform-change.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/stroke-opacity-update.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/svg-background-partial-redraw.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/svg-image-change-content-size.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/svg-layout-root-style-attr-update.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/svgsvgelement-repaint-children.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/tabgroup.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-dom-removal.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-mask-update.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-pattern-update-2.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-pattern-update.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-repaint-including-stroke.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/text-rescale.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-selection-text-05-t.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-viewbox-rescale.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/text-xy-updates-SVGList.xhtml [ Failure ]
+crbug.com/714962 paint/invalidation/svg/transform-changed-state.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/transform-focus-ring-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/transform-foreign-object.html [ Failure ]
-crbug.com/591099 paint/invalidation/svg/use-instanceRoot-event-bubbling.xhtml [ Timeout ]
+crbug.com/714962 paint/invalidation/svg/transform-text-element.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/tspan-dynamic-positioning.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/tspan-pattern-update.html [ Failure ]
+crbug.com/714962 paint/invalidation/svg/use-clipped-hit.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/use-detach.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/use-disappears-after-style-update.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/use-inherit-style.svg [ Failure ]
+crbug.com/591099 paint/invalidation/svg/use-instanceRoot-event-bubbling.xhtml [ Pass Timeout ]
 crbug.com/591099 paint/invalidation/svg/use-setAttribute-crash.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/window.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/zoom-coords-viewattr-01-b.svg [ Failure ]
+crbug.com/714962 paint/invalidation/svg/zoom-foreignObject.svg [ Failure ]
 crbug.com/591099 paint/invalidation/table/add-table-overpaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/block-selection-gap-in-table-cell.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/border-collapse-change-collapse-to-separate.html [ Failure Pass ]
@@ -7183,14 +8651,19 @@
 crbug.com/591099 paint/invalidation/table/cached-change-cell-border-color.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/table/cached-change-cell-border-width.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-cell-sl-border-color.html [ Failure ]
+crbug.com/714962 paint/invalidation/table/cached-change-col-border-color.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-col-border-width.html [ Failure ]
+crbug.com/714962 paint/invalidation/table/cached-change-colgroup-border-color.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-colgroup-border-width.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-row-border-width.html [ Failure ]
+crbug.com/714962 paint/invalidation/table/cached-change-table-border-color.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-table-border-width.html [ Failure Pass ]
+crbug.com/714962 paint/invalidation/table/cached-change-tbody-border-color.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-tbody-border-width.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/caret-contenteditable-content-after.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/collapsed-border-cell-resize.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/collapsed-border-change-rowspan.html [ Failure Pass ]
+crbug.com/714962 paint/invalidation/table/collapsed-border-current-color.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/composited-table-background-col-initial-empty.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/table/composited-table-background-col-span-initial-empty.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/table/composited-table-background-col-span.html [ Failure Pass ]
@@ -7212,17 +8685,22 @@
 crbug.com/591099 paint/invalidation/table/fixed-table-overflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/input-overflow-in-table.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/invalidate-cell-in-row-with-offset.html [ Failure Pass ]
+crbug.com/714962 paint/invalidation/table/invisible-col-visible-td.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/repaint-table-row-in-composited-document.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/resize-table-repaint-percent-size-cell.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/table/resize-table-repaint-vertical-align-cell.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/table/resize-table-row-repaint.html [ Failure ]
+crbug.com/714962 paint/invalidation/table/row-change-background-rowspan-cell.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/scroll-inside-table-cell.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/scroll-relative-table-inside-table-cell.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only.html [ Failure ]
+crbug.com/714962 paint/invalidation/table/table-cell-become-visible-using-row-background.html [ Crash ]
 crbug.com/591099 paint/invalidation/table/table-cell-collapsed-border.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/table/table-cell-move.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-cell-overflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-cell-vertical-overflow.html [ Failure ]
+crbug.com/714962 paint/invalidation/table/table-col-background-offset.html [ Failure ]
+crbug.com/714962 paint/invalidation/table/table-col-background.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-collapsed-border.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-extra-bottom-grow.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-outer-border.html [ Failure Pass ]
@@ -7231,16 +8709,21 @@
 crbug.com/591099 paint/invalidation/table/table-row.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-section-overflow.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-section-repaint.html [ Failure ]
-crbug.com/591099 paint/invalidation/table/table-shrink-row-repaint.html [ Failure ]
+crbug.com/591099 paint/invalidation/table/table-shrink-row-repaint.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/table/table-two-pass-layout-overpaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-writing-modes-h.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-writing-modes-v.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-append-dirty-lines.html [ Failure ]
+crbug.com/714962 paint/invalidation/text-decoration-invalidation.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-emphasis-h.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-emphasis-v.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-match-document-change.html [ Failure ]
+crbug.com/714962 paint/invalidation/text-match-pre-wrapped-text.html [ Failure ]
+crbug.com/714962 paint/invalidation/text-match-transparent-text.html [ Failure ]
+crbug.com/714962 paint/invalidation/text-match.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-shadow-horizontal.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-shadow.html [ Failure ]
+crbug.com/714962 paint/invalidation/transform/caret-with-transformation.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/change-transform.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/invalidation-with-scale-transform.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/resize-skewed.html [ Failure ]
@@ -7248,9 +8731,10 @@
 crbug.com/591099 paint/invalidation/transform/subpixel-offset-scaled-transform.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/subtree-layoutstate-transform.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/transform-disable-layoutstate.html [ Failure ]
-crbug.com/591099 paint/invalidation/transform/transform-inline-layered-child.html [ Failure ]
+crbug.com/591099 paint/invalidation/transform/transform-inline-layered-child.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/transform/transform-layout-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/transform-repaint-descendants.html [ Failure ]
+crbug.com/714962 paint/invalidation/transform/transform-replaced-shadows.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/transform-rotate-and-remove.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/transform-translate.html [ Failure ]
 crbug.com/591099 paint/invalidation/vertical-align-length1.html [ Failure ]
@@ -7260,8 +8744,13 @@
 crbug.com/591099 paint/invalidation/vertical-rl-as-paint-container.html [ Failure ]
 crbug.com/591099 paint/invalidation/video-mute-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/video-unmute-repaint.html [ Failure ]
+crbug.com/714962 paint/invalidation/window-resize/window-resize-background-image-fixed-centered-composited.html [ Failure ]
+crbug.com/714962 paint/invalidation/window-resize/window-resize-background-image-fixed-centered.html [ Failure ]
+crbug.com/714962 paint/invalidation/window-resize/window-resize-background-image-generated.html [ Failure ]
+crbug.com/714962 paint/invalidation/window-resize/window-resize-background-image-non-fixed.html [ Failure ]
 crbug.com/591099 paint/invalidation/window-resize/window-resize-centered-inline-under-fixed-pos.html [ Failure ]
 crbug.com/591099 paint/invalidation/window-resize/window-resize-frameset.html [ Failure ]
+crbug.com/714962 paint/invalidation/window-resize/window-resize-media-query.html [ Failure ]
 crbug.com/591099 paint/invalidation/window-resize/window-resize-percent-html.html [ Failure ]
 crbug.com/591099 paint/invalidation/window-resize/window-resize-percent-width-height.html [ Failure ]
 crbug.com/591099 paint/invalidation/window-resize/window-resize-positioned-bottom.html [ Failure ]
@@ -7302,6 +8791,8 @@
 crbug.com/591099 paint/printing/print-text-shadow.html [ Failure ]
 crbug.com/591099 paint/roundedrects/circle-with-shadow.html [ Failure ]
 crbug.com/591099 paint/roundedrects/input-with-rounded-rect-and-shadow.html [ Failure ]
+crbug.com/714962 paint/selection/text-selection-counter.html [ Failure ]
+crbug.com/714962 paint/selection/text-selection-drag.html [ Failure ]
 crbug.com/591099 paint/selection/text-selection-inline-block-rtl.html [ Failure ]
 crbug.com/591099 paint/selection/text-selection-inline-block.html [ Failure ]
 crbug.com/591099 paint/selection/text-selection-newline-across-blocks-line-beginning-end.html [ Failure ]
@@ -7316,25 +8807,27 @@
 crbug.com/591099 paint/selection/text-selection-newline-vertical-lr.html [ Failure ]
 crbug.com/591099 paint/selection/text-selection-newline-vertical-rl.html [ Failure ]
 crbug.com/591099 paint/selection/text-selection-newline.html [ Failure ]
+crbug.com/714962 paint/selection/text-selection-update-style.html [ Failure ]
 crbug.com/591099 paint/selection/text-selection-with-composition.html [ Failure ]
 crbug.com/591099 paint/subpixel/transform-inside-clip.html [ Failure ]
 crbug.com/591099 paint/tables/collapsed-border-corner-conflict.html [ Failure ]
 crbug.com/591099 paint/tables/composited-collapsed-table-borders.html [ Failure ]
 crbug.com/591099 paint/text/selection-no-clip-text.html [ Failure ]
+crbug.com/714962 paint/text/text-match-highlights-big-line-height.html [ Failure ]
 crbug.com/591099 paint/theme/adjust-progress-bar-size.html [ Failure ]
 crbug.com/591099 paint/transforms/percentage-transform-fractional-box-size.html [ Failure ]
 crbug.com/591099 paint/transparency/compositing-alpha-fold-crash.html [ Failure ]
 crbug.com/591099 payments/payment-request-in-iframe-nested-not-allowed.html [ Failure ]
 crbug.com/591099 payments/payment-request-in-iframe.html [ Failure ]
-crbug.com/591099 plugins/change-widget-and-click-crash.html [ Failure ]
+crbug.com/591099 plugins/change-widget-and-click-crash.html [ Failure Pass ]
 crbug.com/591099 plugins/embed-attributes-style.html [ Failure ]
 crbug.com/591099 plugins/focus.html [ Failure Timeout ]
 crbug.com/591099 plugins/iframe-plugin-bgcolor.html [ Failure ]
-crbug.com/591099 plugins/keyboard-events.html [ Failure ]
-crbug.com/591099 plugins/mouse-capture-inside-shadow.html [ Timeout ]
+crbug.com/591099 plugins/keyboard-events.html [ Failure Pass ]
+crbug.com/591099 plugins/mouse-capture-inside-shadow.html [ Pass Timeout ]
 crbug.com/591099 plugins/mouse-click-plugin-clears-selection.html [ Failure ]
-crbug.com/591099 plugins/mouse-events-fixedpos.html [ Failure ]
-crbug.com/591099 plugins/mouse-events.html [ Failure ]
+crbug.com/591099 plugins/mouse-events-fixedpos.html [ Failure Pass ]
+crbug.com/591099 plugins/mouse-events.html [ Failure Pass ]
 crbug.com/591099 plugins/plugin-initiate-popup-window.html [ Timeout ]
 crbug.com/591099 plugins/refcount-leaks.html [ Failure ]
 crbug.com/591099 plugins/tabindex.html [ Failure ]
@@ -7351,6 +8844,7 @@
 crbug.com/591099 printing/css2.1/page-break-after-003.html [ Failure ]
 crbug.com/591099 printing/css2.1/page-break-after-004.html [ Failure ]
 crbug.com/591099 printing/css2.1/page-break-before-000.html [ Failure ]
+crbug.com/714962 printing/css2.1/page-break-inside-000.html [ Failure ]
 crbug.com/591099 printing/ellipsis-printing-style.html [ Failure ]
 crbug.com/591099 printing/fixed-positioned-but-static-headers-and-footers.html [ Failure ]
 crbug.com/591099 printing/fixed-positioned-child-repeats-even-when-html-and-body-are-zero-height.html [ Crash ]
@@ -7360,6 +8854,7 @@
 crbug.com/591099 printing/fixed-positioned-headers-and-footers-inside-transform.html [ Crash ]
 crbug.com/591099 printing/fixed-positioned-headers-and-footers-larger-than-page.html [ Failure ]
 crbug.com/591099 printing/fixed-positioned-headers-and-footers.html [ Failure ]
+crbug.com/714962 printing/fixed-positioned-scrolled.html [ Failure ]
 crbug.com/591099 printing/forced-break-tree-dump-only.html [ Failure ]
 crbug.com/591099 printing/iframe-print.html [ Failure ]
 crbug.com/591099 printing/list-item-with-empty-first-line.html [ Failure ]
@@ -7376,7 +8871,9 @@
 crbug.com/591099 printing/page-break-orphans-and-widows.html [ Failure ]
 crbug.com/591099 printing/page-break-orphans.html [ Failure ]
 crbug.com/591099 printing/page-break-widows.html [ Crash Failure ]
+crbug.com/714962 printing/page-count-layout-overflow.html [ Failure ]
 crbug.com/591099 printing/page-count-relayout-shrink.html [ Failure ]
+crbug.com/714962 printing/page-height-zero.html [ Failure ]
 crbug.com/591099 printing/quirks-percentage-height-body.html [ Failure ]
 crbug.com/591099 printing/quirks-percentage-height.html [ Failure ]
 crbug.com/591099 printing/respect-layout-overflow-from-pagination.html [ Failure ]
@@ -7390,24 +8887,38 @@
 crbug.com/591099 printing/thead-repeats-at-top-of-each-page-multiple-tables.html [ Crash Failure ]
 crbug.com/591099 printing/thead-repeats-at-top-of-each-page.html [ Failure ]
 crbug.com/591099 scrollbars/auto-scrollbar-fit-content.html [ Failure ]
+crbug.com/714962 scrollbars/basic-scrollbar.html [ Failure ]
+crbug.com/714962 scrollbars/border-box-rect-clips-scrollbars.html [ Failure ]
 crbug.com/591099 scrollbars/custom-scrollbar-enable-changes-thickness-with-iframe.html [ Failure ]
 crbug.com/591099 scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure ]
-crbug.com/591099 scrollbars/scrollbar-added-during-drag.html [ Timeout ]
+crbug.com/714962 scrollbars/custom-scrollbars-paint-outside-iframe.html [ Failure ]
+crbug.com/714962 scrollbars/disabled-scrollbar.html [ Failure ]
+crbug.com/714962 scrollbars/overlay-scrollbars-within-overflow-scroll.html [ Failure ]
+crbug.com/714962 scrollbars/resize-scales-with-dpi-150.html [ Failure ]
+crbug.com/591099 scrollbars/scrollbar-added-during-drag.html [ Pass Timeout ]
+crbug.com/714962 scrollbars/scrollbar-buttons.html [ Failure ]
 crbug.com/591099 scrollbars/scrollbar-click-does-not-blur-content.html [ Failure ]
 crbug.com/591099 scrollbars/scrollbar-large-overflow-rectangle.html [ Crash ]
 crbug.com/591099 scrollbars/scrollbar-miss-mousemove-disabled.html [ Failure ]
+crbug.com/714962 scrollbars/scrollbar-orientation.html [ Failure ]
 crbug.com/591099 scrollbars/scrollbar-owning-renderer-crash.html [ Failure ]
+crbug.com/714962 scrollbars/scrollbar-pointer-events.html [ Failure ]
+crbug.com/714962 scrollbars/scrollbar-position-crash.html [ Failure ]
 crbug.com/591099 scrollbars/scrollbars-on-positioned-content.html [ Failure ]
 crbug.com/591099 security/autocomplete-cleared-on-back.html [ Failure ]
 crbug.com/591099 shadow-dom/event-composed-ua.html [ Timeout ]
 crbug.com/591099 shadow-dom/focus-navigation-with-delegatesFocus.html [ Pass Timeout ]
+crbug.com/714962 shadow-dom/host-pseudo-elements.html [ Failure ]
 crbug.com/591099 shadow-dom/range-caret-range-from-point-left-of-shadow.html [ Crash ]
+crbug.com/714962 shadow-dom/slotted-pseudo-element-dynamic-attribute-change.html [ Failure ]
 crbug.com/591099 shapedetection/detection-HTMLVideoElement.html [ Pass ]
+crbug.com/714962 storage/indexeddb/blob-basics-metadata.html [ Failure ]
 crbug.com/591099 storage/indexeddb/cursor-advance.html [ Pass Timeout ]
 crbug.com/591099 storage/indexeddb/cursor-continue-validity.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/cursor-key-order.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/cursor-update.html [ Pass Timeout ]
 crbug.com/591099 storage/indexeddb/deleted-objects.html [ Timeout ]
+crbug.com/714962 storage/indexeddb/empty-blob-file.html [ Failure ]
 crbug.com/591099 storage/indexeddb/exceptions.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/index-cursor.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/keypath-basics.html [ Pass Timeout ]
@@ -7416,117 +8927,181 @@
 crbug.com/591099 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/objectstore-cursor.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/objectstore-keycursor.html [ Timeout ]
-crbug.com/591099 storage/indexeddb/structured-clone.html [ Timeout ]
-crbug.com/591099 svg/animations/animVal-basics.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-calcMode-spline-by.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-calcMode-spline-from-by.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-calcMode-spline-from-to.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-calcMode-spline-to.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-calcMode-spline-values.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-color-calcMode-discrete.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-color-fill-currentColor.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-color-fill-from-by.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-color-rgba-calcMode-discrete.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-color-transparent.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-css-xml-attributeType.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-currentColor.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-dynamic-update-attributeName.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-end-attribute.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-endElement-beginElement.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-from-to-keyTimes.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-gradient-transform.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-inherit-css-property.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-keySplines.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-marker-orient-from-angle-to-angle.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-marker-orient-from-angle-to-auto.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-marker-orient-from-auto-to-angle.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-marker-orient-from-auto-to-auto-start-reverse.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-marker-orient-to-angle.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-mpath-insert.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-number-calcMode-discrete-keyTimes.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-number-calcMode-discrete.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-Cc-Ss.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-Ll-Vv-Hh.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-Mm-Aa-Z.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-Qq-Tt.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-cC-sS-inverse.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-lL-vV-hH-inverse.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-mM-aA-Z-inverse.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-animation-qQ-tT-inverse.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-nested-transforms.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-path-to-animation.html [ Timeout ]
-crbug.com/591099 svg/animations/animate-text-nested-transforms.html [ Timeout ]
-crbug.com/591099 svg/animations/animateTransform-pattern-transform.html [ Timeout ]
-crbug.com/591099 svg/animations/animateTransform-translate-attributetype-auto.html [ Timeout ]
-crbug.com/591099 svg/animations/animateTransform-translate-invalid-attributetype.html [ Timeout ]
-crbug.com/591099 svg/animations/animation-begin-change-js.html [ Timeout ]
-crbug.com/591099 svg/animations/deferred-insertion.html [ Timeout ]
-crbug.com/591099 svg/animations/svgPreserveAspectRatio-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgangle-animation-deg-to-grad.html [ Timeout ]
-crbug.com/591099 svg/animations/svgangle-animation-deg-to-rad.html [ Timeout ]
-crbug.com/591099 svg/animations/svgangle-animation-grad-to-deg.html [ Timeout ]
-crbug.com/591099 svg/animations/svgangle-animation-grad-to-rad.html [ Timeout ]
-crbug.com/591099 svg/animations/svgangle-animation-rad-to-deg.html [ Timeout ]
-crbug.com/591099 svg/animations/svgangle-animation-rad-to-grad.html [ Timeout ]
-crbug.com/591099 svg/animations/svgboolean-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-10.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-11.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-12.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-13.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-3.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-4.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-5.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-6.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-7.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-8.html [ Timeout ]
-crbug.com/591099 svg/animations/svgenum-animation-9.html [ Timeout ]
-crbug.com/591099 svg/animations/svginteger-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svginteger-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-LengthModeHeight.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-LengthModeOther.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-LengthModeWidth.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-invalid-value-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-invalid-value-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-invalid-value-3.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-number-to-number.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-cm.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-ems.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-exs.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-in.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-number.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-pc.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-percentage.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-pt.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-px-to-px.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-unitType.html [ Timeout ]
-crbug.com/591099 svg/animations/svglength-animation-values.html [ Timeout ]
-crbug.com/591099 svg/animations/svglengthlist-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svglengthlist-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svglengthlist-animation-3.html [ Timeout ]
-crbug.com/591099 svg/animations/svglengthlist-animation-4.html [ Timeout ]
-crbug.com/591099 svg/animations/svglengthlist-animation-5.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumber-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumber-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumber-animation-3.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumber-animation-4.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumberlist-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumberlist-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-3.html [ Timeout ]
-crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-4.html [ Timeout ]
-crbug.com/591099 svg/animations/svgpath-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgpointlist-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgpointlist-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svgrect-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgrect-animation-2.html [ Timeout ]
-crbug.com/591099 svg/animations/svgstring-animation-fallback-to-discrete.html [ Timeout ]
-crbug.com/591099 svg/animations/svgtransform-animation-1.html [ Timeout ]
-crbug.com/591099 svg/animations/svgtransform-animation-discrete.html [ Timeout ]
-crbug.com/591099 svg/animations/use-animate-transform-and-position.html [ Timeout ]
-crbug.com/591099 svg/animations/use-animate-width-and-height.html [ Timeout ]
+crbug.com/591099 storage/indexeddb/structured-clone.html [ Failure Timeout ]
+crbug.com/714962 svg/W3C-SVG-1.1-SE/filters-image-03-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1-SE/filters-image-05-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1-SE/painting-marker-05-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1-SE/types-dom-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-08-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-22-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-33-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-36-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-40-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-41-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-61-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-63-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-64-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-65-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-66-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-67-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-68-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-69-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-70-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-78-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-80-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-82-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/animate-elem-83-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/coords-units-02-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/coords-viewattr-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/coords-viewattr-02-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/coords-viewattr-03-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/filters-color-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/filters-gauss-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/filters-light-04-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/filters-turb-02-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/interact-events-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-intro-01-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-mask-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-opacity-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-path-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-path-02-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-path-03-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-path-04-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-path-05-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/painting-marker-02-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/painting-marker-03-f.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/painting-render-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/painting-stroke-07-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-04-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-05-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-06-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-07-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-08-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-09-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-14-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/paths-data-15-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/pservers-grad-12-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/pservers-grad-13-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/render-elems-03-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/render-groups-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/render-groups-03-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/struct-group-03-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/struct-image-06-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/struct-symbol-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/text-align-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/text-align-05-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/text-text-05-t.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/text-text-06-t.svg [ Failure ]
+crbug.com/591099 svg/animations/animVal-basics.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-calcMode-spline-by.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-calcMode-spline-from-by.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-calcMode-spline-from-to.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-calcMode-spline-to.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-calcMode-spline-values.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-color-calcMode-discrete.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-color-fill-currentColor.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-color-fill-from-by.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-color-rgba-calcMode-discrete.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-color-transparent.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-css-xml-attributeType.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-currentColor.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-dynamic-update-attributeName.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-end-attribute.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-endElement-beginElement.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-from-to-keyTimes.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-gradient-transform.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-inherit-css-property.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-keySplines.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-marker-orient-from-angle-to-angle.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-marker-orient-from-angle-to-auto.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-marker-orient-from-auto-to-angle.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-marker-orient-from-auto-to-auto-start-reverse.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-marker-orient-to-angle.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-mpath-insert.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-number-calcMode-discrete-keyTimes.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-number-calcMode-discrete.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-Cc-Ss.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-Ll-Vv-Hh.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-Mm-Aa-Z.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-Qq-Tt.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-cC-sS-inverse.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-lL-vV-hH-inverse.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-mM-aA-Z-inverse.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-animation-qQ-tT-inverse.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-nested-transforms.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-path-to-animation.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animate-text-nested-transforms.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animateTransform-pattern-transform.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animateTransform-translate-attributetype-auto.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animateTransform-translate-invalid-attributetype.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/animation-begin-change-js.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/deferred-insertion.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgPreserveAspectRatio-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgangle-animation-deg-to-grad.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgangle-animation-deg-to-rad.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgangle-animation-grad-to-deg.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgangle-animation-grad-to-rad.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgangle-animation-rad-to-deg.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgangle-animation-rad-to-grad.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgboolean-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-10.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-11.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-12.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-13.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-3.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-4.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-5.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-6.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-7.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-8.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgenum-animation-9.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svginteger-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svginteger-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-LengthModeHeight.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-LengthModeOther.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-LengthModeWidth.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-invalid-value-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-invalid-value-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-invalid-value-3.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-number-to-number.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-cm.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-ems.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-exs.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-in.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-number.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-pc.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-percentage.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-pt.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-px-to-px.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-unitType.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglength-animation-values.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglengthlist-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglengthlist-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglengthlist-animation-3.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglengthlist-animation-4.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svglengthlist-animation-5.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumber-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumber-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumber-animation-3.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumber-animation-4.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumberlist-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumberlist-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-3.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgnumberoptionalnumber-animation-4.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgpath-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgpointlist-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgpointlist-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgrect-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgrect-animation-2.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgstring-animation-fallback-to-discrete.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgtransform-animation-1.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/svgtransform-animation-discrete.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/use-animate-transform-and-position.html [ Pass Timeout ]
+crbug.com/591099 svg/animations/use-animate-width-and-height.html [ Pass Timeout ]
 crbug.com/591099 svg/as-background-image/animated-svg-as-background.html [ Failure ]
 crbug.com/591099 svg/as-background-image/background-image-preserveaspectRatio-support.html [ Failure ]
 crbug.com/591099 svg/as-background-image/background-image-tiled.html [ Failure ]
@@ -7537,6 +9112,7 @@
 crbug.com/591099 svg/as-background-image/svg-as-background-3.html [ Failure ]
 crbug.com/591099 svg/as-background-image/svg-as-background-5.html [ Failure ]
 crbug.com/591099 svg/as-background-image/svg-as-background-6.html [ Failure ]
+crbug.com/714962 svg/as-background-image/svg-as-background-body.html [ Failure ]
 crbug.com/591099 svg/as-background-image/svg-as-background-with-relative-size.html [ Failure ]
 crbug.com/591099 svg/as-background-image/svg-as-background-with-viewBox.html [ Failure ]
 crbug.com/591099 svg/as-background-image/svg-as-background.html [ Failure ]
@@ -7553,13 +9129,106 @@
 crbug.com/591099 svg/as-image/svg-as-relative-image-with-explicit-size.html [ Failure ]
 crbug.com/591099 svg/as-image/svg-as-relative-image.html [ Failure ]
 crbug.com/591099 svg/as-image/svg-image-leak-loader.html [ Failure ]
+crbug.com/714962 svg/as-image/svg-image-with-css-animation.html [ Failure ]
+crbug.com/714962 svg/as-image/svg-intrinsic-size-rectangular-vertical.html [ Failure ]
+crbug.com/714962 svg/as-image/svg-intrinsic-size-rectangular.html [ Failure ]
 crbug.com/591099 svg/as-image/svg-non-integer-scaled-image.html [ Failure ]
 crbug.com/591099 svg/as-image/svg-object-intrinsic-size.html [ Failure ]
 crbug.com/591099 svg/as-image/svgview-references-use-counters.html [ Failure ]
 crbug.com/591099 svg/as-object/object-box-sizing-no-width-height.html [ Failure ]
 crbug.com/591099 svg/as-object/svg-embedded-in-html-in-iframe.html [ Failure ]
+crbug.com/714962 svg/batik/filters/feTile.svg [ Failure ]
+crbug.com/714962 svg/batik/filters/filterRegions.svg [ Failure ]
+crbug.com/714962 svg/batik/masking/maskRegions.svg [ Failure ]
+crbug.com/714962 svg/batik/paints/gradientLimit.svg [ Failure ]
+crbug.com/714962 svg/batik/paints/patternPreserveAspectRatioA.svg [ Failure ]
+crbug.com/714962 svg/batik/paints/patternRegionA.svg [ Failure ]
+crbug.com/714962 svg/batik/paints/patternRegions-positioned-objects.svg [ Failure ]
+crbug.com/714962 svg/batik/paints/patternRegions.svg [ Failure ]
+crbug.com/714962 svg/batik/text/longTextOnPath.svg [ Failure ]
+crbug.com/714962 svg/batik/text/smallFonts.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textAnchor.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textDecoration.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textEffect.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textEffect2.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textEffect3.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textFeatures.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textLayout.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textLayout2.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textLength.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textOnPath.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textOnPathSpaces.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textPosition.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textPosition2.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textProperties.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textProperties2.svg [ Failure ]
+crbug.com/714962 svg/batik/text/textStyles.svg [ Failure ]
+crbug.com/714962 svg/batik/text/verticalText.svg [ Failure ]
+crbug.com/714962 svg/batik/text/verticalTextOnPath.svg [ Failure ]
 crbug.com/591099 svg/canvas/canvas-default-object-sizing.html [ Failure ]
 crbug.com/591099 svg/canvas/canvas-draw-image-globalalpha.html [ Failure ]
+crbug.com/714962 svg/canvas/canvas-pattern-svg.html [ Failure ]
+crbug.com/714962 svg/carto.net/scrollbar.svg [ Failure ]
+crbug.com/714962 svg/carto.net/textbox.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-in-clip.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-in-mask-objectBoundingBox.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-in-mask-userSpaceOnUse.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-in-mask.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-child-clipped.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-childs-clipped.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-clipped-evenodd-twice.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-clipped-no-content.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-clipped-nonzero.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-clipped-shape.html [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-clipped.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-css-transform-1.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-css-transform-2.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-evenodd-nonzero.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-evenodd.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-nonzero-evenodd.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-nonzero.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-objectBoundingBox.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-on-clipped-use.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-on-g-and-child.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-on-g.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-on-lazy-root.html [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-on-svg-and-child.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-on-svg.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-pixelation.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-prefixed-vs-not.html [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-shape-ellipse-2.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-text-and-shape.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-text-and-stroke.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-text.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-transform-1.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-transform-2.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-tspan-and-stroke.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-use-as-child.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-use-as-child2.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-use-as-child3.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-use-as-child4.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-use-referencing-clipped-text.html [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-use-referencing-text.html [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-userSpaceOnUse.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-visible-element-as-visible-shape-element.html [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-w-broken-filter-on-shape.html [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-with-different-unittypes.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-with-different-unittypes2.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clip-path-with-text-clipped.svg [ Failure ]
+crbug.com/714962 svg/clip-path/clipper-placement-issue.svg [ Failure ]
+crbug.com/714962 svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg [ Failure ]
+crbug.com/714962 svg/clip-path/deep-nested-clip-in-mask-panning.svg [ Failure ]
+crbug.com/714962 svg/clip-path/deep-nested-clip-in-mask.svg [ Failure ]
+crbug.com/714962 svg/clip-path/display-none-children.html [ Failure ]
+crbug.com/714962 svg/clip-path/multiple-nested-clip-paths-crash.html [ Failure ]
+crbug.com/714962 svg/clip-path/nested-clip-in-mask-image-based-clipping.svg [ Failure ]
+crbug.com/714962 svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg [ Failure ]
+crbug.com/714962 svg/clip-path/nested-clip-in-mask-path-based-clipping.svg [ Failure ]
+crbug.com/714962 svg/clip-path/nested-empty-clip.html [ Failure ]
+crbug.com/714962 svg/clip-path/opacity-assertion.svg [ Failure ]
+crbug.com/714962 svg/clip-path/transformed-clip.svg [ Failure ]
+crbug.com/714962 svg/clip-path/visible-clip-path-as-hidden-use-element.html [ Failure ]
+crbug.com/714962 svg/clip-path/visible-nested-clip-path-as-hidden-use-element.html [ Failure ]
 crbug.com/591099 svg/css/background-image-svg.html [ Failure ]
 crbug.com/591099 svg/css/css-box-min-width.html [ Failure ]
 crbug.com/591099 svg/css/max-height.html [ Failure ]
@@ -7569,15 +9238,23 @@
 crbug.com/591099 svg/custom/absolute-sized-svg-in-xhtml.xhtml [ Failure ]
 crbug.com/591099 svg/custom/anchor-on-use.svg [ Failure ]
 crbug.com/591099 svg/custom/bug45331.svg [ Failure ]
-crbug.com/591099 svg/custom/click-overflowing-element.html [ Failure ]
+crbug.com/714962 svg/custom/clamped-masking-clipping.svg [ Failure ]
+crbug.com/591099 svg/custom/click-overflowing-element.html [ Failure Pass ]
+crbug.com/714962 svg/custom/clip-mask-negative-scale.svg [ Failure ]
+crbug.com/714962 svg/custom/clip-path-referencing-use.svg [ Failure ]
+crbug.com/714962 svg/custom/clip-path-with-css-transform-1.svg [ Failure ]
+crbug.com/714962 svg/custom/clip-path-with-css-transform-2.svg [ Failure ]
+crbug.com/714962 svg/custom/clip-path-with-transform.svg [ Failure ]
 crbug.com/591099 svg/custom/clone-element-with-animated-svg-properties.html [ Failure ]
+crbug.com/714962 svg/custom/container-opacity-clip-viewBox.svg [ Failure ]
 crbug.com/591099 svg/custom/createImageElement2.xhtml [ Crash Failure ]
 crbug.com/591099 svg/custom/dominant-baseline-hanging.svg [ Failure ]
 crbug.com/591099 svg/custom/elementTimeControl-nan-crash.html [ Failure ]
 crbug.com/591099 svg/custom/embedding-external-svgs.xhtml [ Failure ]
 crbug.com/591099 svg/custom/external-paintserver-reference.svg [ Failure ]
 crbug.com/591099 svg/custom/filter-css-transform-resolution.html [ Failure ]
-crbug.com/591099 svg/custom/focus-event-handling.xhtml [ Failure ]
+crbug.com/591099 svg/custom/focus-event-handling.xhtml [ Failure Pass ]
+crbug.com/714962 svg/custom/focus-ring.svg [ Failure ]
 crbug.com/591099 svg/custom/foreign-object-skew.svg [ Failure ]
 crbug.com/591099 svg/custom/getscreenctm-in-mixed-content.xhtml [ Failure ]
 crbug.com/591099 svg/custom/getscreenctm-in-mixed-content2.xhtml [ Failure ]
@@ -7585,17 +9262,23 @@
 crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area.xhtml [ Failure ]
 crbug.com/591099 svg/custom/getscreenctm-in-scrollable-svg-area.xhtml [ Failure ]
 crbug.com/591099 svg/custom/getsvgdocument.html [ Failure ]
+crbug.com/714962 svg/custom/group-opacity.svg [ Failure ]
 crbug.com/591099 svg/custom/hit-test-path-stroke.svg [ Failure ]
 crbug.com/591099 svg/custom/hit-test-path.svg [ Failure ]
 crbug.com/591099 svg/custom/image-parent-translation.xhtml [ Failure ]
 crbug.com/591099 svg/custom/image-rescale-clip.html [ Failure ]
 crbug.com/591099 svg/custom/image-rescale-scroll.html [ Failure ]
+crbug.com/714962 svg/custom/image-with-preserveAspectRatio-none.html [ Failure ]
+crbug.com/714962 svg/custom/image-with-transform-clip-filter.svg [ Failure ]
 crbug.com/591099 svg/custom/inline-svg-in-xhtml.xml [ Failure ]
 crbug.com/591099 svg/custom/inline-svg-use-available-width-in-stf.html [ Failure ]
 crbug.com/591099 svg/custom/invisible-text-after-scrolling.xhtml [ Failure ]
 crbug.com/591099 svg/custom/junk-data.svg [ Failure ]
 crbug.com/591099 svg/custom/load-non-wellformed.svg [ Crash Failure ]
+crbug.com/714962 svg/custom/local-url-references.html [ Failure ]
 crbug.com/591099 svg/custom/marker-orient-auto.html [ Failure ]
+crbug.com/714962 svg/custom/marker-zero-length-linecaps.svg [ Failure ]
+crbug.com/714962 svg/custom/masking-clipping-hidpi.svg [ Failure ]
 crbug.com/591099 svg/custom/missing-xlink.svg [ Failure ]
 crbug.com/591099 svg/custom/mouse-move-on-svg-container.xhtml [ Timeout ]
 crbug.com/591099 svg/custom/mouse-move-on-svg-root.xhtml [ Timeout ]
@@ -7609,46 +9292,81 @@
 crbug.com/591099 svg/custom/path-bad-data.svg [ Failure ]
 crbug.com/591099 svg/custom/pattern-userSpaceOnUse-userToBaseTransform.xhtml [ Failure ]
 crbug.com/591099 svg/custom/percentage-of-html-parent.xhtml [ Failure ]
+crbug.com/714962 svg/custom/preserve-aspect-ratio-syntax.svg [ Failure ]
+crbug.com/714962 svg/custom/recursive-clippath.svg [ Failure ]
 crbug.com/591099 svg/custom/rootmost-svg-xy-attrs.xhtml [ Failure ]
 crbug.com/591099 svg/custom/second-inline-text.xhtml [ Failure ]
 crbug.com/591099 svg/custom/simpleCDF.xml [ Failure ]
-crbug.com/591099 svg/custom/size-follows-container-size.html [ Failure ]
+crbug.com/591099 svg/custom/size-follows-container-size.html [ Failure Pass ]
 crbug.com/591099 svg/custom/svg-allowed-in-dashboard-object.html [ Failure ]
 crbug.com/591099 svg/custom/svg-float-border-padding.xml [ Failure ]
 crbug.com/591099 svg/custom/svg-fonts-in-html.html [ Failure ]
+crbug.com/714962 svg/custom/svg-fonts-no-latin-glyph.html [ Failure ]
 crbug.com/591099 svg/custom/svg-fonts-with-no-element-reference.html [ Failure ]
 crbug.com/591099 svg/custom/svg-fonts-word-spacing.html [ Failure ]
+crbug.com/714962 svg/custom/svg-overflow-types.svg [ Failure ]
+crbug.com/714962 svg/custom/svg-root-with-opacity.html [ Failure ]
 crbug.com/591099 svg/custom/tabindex-order.html [ Failure ]
+crbug.com/714962 svg/custom/text-clip.svg [ Failure ]
 crbug.com/591099 svg/custom/text-match-highlight.html [ Failure ]
 crbug.com/591099 svg/custom/text-zoom.xhtml [ Failure ]
-crbug.com/591099 svg/custom/touch-events.html [ Failure ]
+crbug.com/591099 svg/custom/touch-events.html [ Failure Pass ]
+crbug.com/714962 svg/custom/transformed-outlines.svg [ Failure ]
 crbug.com/591099 svg/custom/transformed-text-pattern.html [ Failure ]
 crbug.com/591099 svg/custom/tref-with-progress-tag-setpseudo-assert.html [ Failure ]
+crbug.com/714962 svg/custom/use-clipped-transform.svg [ Failure ]
 crbug.com/591099 svg/custom/use-event-retargeting.html [ Failure ]
 crbug.com/591099 svg/custom/use-font-face-crash.svg [ Failure ]
+crbug.com/714962 svg/custom/use-modify-container-in-target.svg [ Failure ]
+crbug.com/714962 svg/custom/use-modify-target-container.svg [ Failure ]
+crbug.com/714962 svg/custom/use-on-clip-path-with-transformation.svg [ Failure ]
 crbug.com/591099 svg/custom/use-on-disallowed-foreign-object-1.svg [ Failure ]
 crbug.com/591099 svg/custom/use-on-disallowed-foreign-object-2.svg [ Failure ]
 crbug.com/591099 svg/custom/use-on-disallowed-foreign-object-3.svg [ Failure ]
 crbug.com/591099 svg/custom/use-on-disallowed-foreign-object-4.svg [ Failure ]
 crbug.com/591099 svg/custom/use-on-disallowed-foreign-object-5.svg [ Failure ]
 crbug.com/591099 svg/custom/use-on-disallowed-foreign-object-6.svg [ Failure ]
+crbug.com/714962 svg/custom/use-on-g-containing-use.svg [ Failure ]
+crbug.com/714962 svg/custom/use-on-g.svg [ Failure ]
 crbug.com/591099 svg/custom/use-on-non-svg-namespaced-element.svg [ Failure ]
+crbug.com/714962 svg/custom/use-on-use.svg [ Failure ]
+crbug.com/714962 svg/custom/use-transform.svg [ Failure ]
+crbug.com/714962 svg/custom/viewbox-syntax.svg [ Failure ]
+crbug.com/714962 svg/custom/viewport-clippath-invalidation.html [ Failure ]
 crbug.com/591099 svg/custom/viewport-em.svg [ Failure ]
+crbug.com/714962 svg/custom/visibility-override-clip.svg [ Failure ]
+crbug.com/714962 svg/custom/width-full-percentage.svg [ Failure ]
 crbug.com/591099 svg/custom/xhtml-no-svg-renderer.xhtml [ Failure ]
+crbug.com/714962 svg/dom/SVGStringList-basics.xhtml [ Failure ]
 crbug.com/591099 svg/dom/svg-root-lengths.html [ Failure ]
-crbug.com/591099 svg/dom/title-in-shadow-tree.html [ Failure ]
-crbug.com/591099 svg/dom/tooltip-title-external-svg.html [ Failure ]
+crbug.com/591099 svg/dom/title-in-shadow-tree.html [ Failure Pass ]
+crbug.com/591099 svg/dom/tooltip-title-external-svg.html [ Failure Pass ]
 crbug.com/591099 svg/dom/tooltip-title-inline-svg.html [ Failure ]
-crbug.com/591099 svg/dom/tooltip-title-with-use.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGAElement-dom-href-attr.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGAElement-dom-target-attr.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGAElement-svgdom-href-prop.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGAElement-svgdom-target-prop.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGClipPath-influences-hitTesting.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-css-transform-influences-hitTesting.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html [ Crash Failure ]
+crbug.com/591099 svg/dom/tooltip-title-with-use.html [ Failure Pass ]
+crbug.com/714962 svg/dynamic-updates/SVG-dynamic-css-transform.html [ Failure ]
+crbug.com/591099 svg/dynamic-updates/SVGAElement-dom-href-attr.html [ Failure Pass ]
+crbug.com/591099 svg/dynamic-updates/SVGAElement-dom-target-attr.html [ Failure Pass ]
+crbug.com/591099 svg/dynamic-updates/SVGAElement-svgdom-href-prop.html [ Failure Pass ]
+crbug.com/591099 svg/dynamic-updates/SVGAElement-svgdom-target-prop.html [ Failure Pass ]
+crbug.com/591099 svg/dynamic-updates/SVGClipPath-influences-hitTesting.html [ Failure Pass ]
+crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-css-transform-influences-hitTesting.html [ Failure Pass ]
+crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html [ Crash Failure Pass ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-height-attr.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-width-attr.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-x-attr.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-y-attr.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-height-prop.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-width-prop.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-x-prop.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-y-prop.html [ Failure ]
 crbug.com/591099 svg/filters/feBlend-all-modes.html [ Failure ]
 crbug.com/591099 svg/filters/feTurbulence-bad-seeds.html [ Crash Failure ]
+crbug.com/714962 svg/filters/filter-clip.svg [ Failure ]
+crbug.com/714962 svg/filters/filter-huge-clamping.svg [ Failure ]
 crbug.com/591099 svg/foreign-object-under-shadow-root-under-hidden.html [ Failure ]
 crbug.com/591099 svg/foreignObject/background-render-phase.html [ Failure ]
 crbug.com/591099 svg/foreignObject/body-background.svg [ Failure ]
@@ -7659,22 +9377,24 @@
 crbug.com/591099 svg/foreignObject/multiple-foreign-objects.html [ Failure ]
 crbug.com/591099 svg/foreignObject/no-crash-with-svg-content-in-html-document.svg [ Failure ]
 crbug.com/591099 svg/foreignObject/svg-document-in-html-document.svg [ Failure ]
+crbug.com/714962 svg/foreignObject/vertical-foreignObject.html [ Failure ]
 crbug.com/591099 svg/hittest/clip-path-shape.html [ Failure ]
 crbug.com/591099 svg/hittest/ellipse-hittest.html [ Crash Failure ]
 crbug.com/591099 svg/hittest/empty-container.html [ Failure ]
 crbug.com/591099 svg/hittest/pointer-events-all.html [ Failure ]
 crbug.com/591099 svg/hittest/pointer-events-all2.html [ Failure ]
 crbug.com/591099 svg/hittest/rect-hittest.html [ Failure ]
-crbug.com/591099 svg/hittest/singular-transform-6.html [ Failure ]
+crbug.com/714962 svg/hittest/rect-miterlimit.html [ Failure ]
+crbug.com/591099 svg/hittest/singular-transform-6.html [ Failure Pass ]
 crbug.com/591099 svg/hittest/svg-inside-table.xhtml [ Failure Pass ]
 crbug.com/591099 svg/hittest/svg-padding.xhtml [ Failure Pass ]
 crbug.com/591099 svg/hittest/text-small-font-size.html [ Failure ]
-crbug.com/591099 svg/hittest/text-vertical.html [ Failure ]
+crbug.com/591099 svg/hittest/text-vertical.html [ Failure Pass ]
 crbug.com/591099 svg/hittest/update-ellipse.html [ Failure ]
 crbug.com/591099 svg/hittest/update-rect.html [ Failure ]
 crbug.com/591099 svg/hittest/zero-length-butt-cap-path.xhtml [ Failure ]
 crbug.com/591099 svg/hittest/zero-length-round-cap-path.xhtml [ Failure ]
-crbug.com/591099 svg/hittest/zero-length-square-cap-path.xhtml [ Failure ]
+crbug.com/591099 svg/hittest/zero-length-square-cap-path.xhtml [ Failure Pass ]
 crbug.com/591099 svg/hittest/zero-stroke-width.html [ Failure ]
 crbug.com/591099 svg/hixie/data-types/002.xhtml [ Failure ]
 crbug.com/591099 svg/hixie/error/012.xml [ Failure ]
@@ -7689,14 +9409,19 @@
 crbug.com/591099 svg/hixie/mixed/009.xml [ Failure ]
 crbug.com/591099 svg/hixie/mixed/010.xml [ Failure ]
 crbug.com/591099 svg/hixie/mixed/011.xml [ Failure ]
+crbug.com/714962 svg/hixie/perf/007.xml [ Failure ]
 crbug.com/591099 svg/hixie/processing-model/003.xml [ Failure ]
 crbug.com/591099 svg/hixie/processing-model/004.xml [ Failure ]
 crbug.com/591099 svg/hixie/rendering-model/003.xhtml [ Failure ]
 crbug.com/591099 svg/hixie/rendering-model/004.xhtml [ Failure ]
+crbug.com/714962 svg/hixie/viewbox/preserveAspectRatio/001.xml [ Failure ]
 crbug.com/591099 svg/in-html/by-reference.html [ Failure ]
 crbug.com/591099 svg/in-html/circle.html [ Failure ]
 crbug.com/591099 svg/in-html/sizing/svg-inline.html [ Timeout ]
 crbug.com/591099 svg/overflow/overflow-on-foreignObject.svg [ Failure ]
+crbug.com/714962 svg/overflow/overflow-on-inner-svg-element-defaults.svg [ Failure ]
+crbug.com/714962 svg/overflow/overflow-on-inner-svg-element.svg [ Failure ]
+crbug.com/714962 svg/overflow/overflow-on-outermost-svg-element-horizontal-auto.svg [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-auto.xhtml [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-defaults.xhtml [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-hidden.xhtml [ Failure ]
@@ -7711,12 +9436,15 @@
 crbug.com/591099 svg/text/bbox-with-glyph-overflow-on-path.html [ Failure ]
 crbug.com/591099 svg/text/bbox-with-glyph-overflow-zoomed.html [ Failure ]
 crbug.com/591099 svg/text/bbox-with-glyph-overflow.html [ Failure ]
+crbug.com/714962 svg/text/columns-do-not-apply.html [ Failure ]
 crbug.com/591099 svg/text/combining-character-queries.html [ Failure ]
 crbug.com/591099 svg/text/foreignObject-repaint.xml [ Failure ]
 crbug.com/591099 svg/text/foreignObject-text-clipping-bug.xml [ Failure ]
+crbug.com/714962 svg/text/layout-inline-children-assert.html [ Failure ]
 crbug.com/591099 svg/text/ligature-queries.html [ Failure ]
 crbug.com/591099 svg/text/scaling-font-with-geometric-precision.html [ Failure ]
-crbug.com/591099 svg/text/select-svg-text-with-collapsed-whitespace.html [ Failure ]
+crbug.com/591099 svg/text/select-svg-text-with-collapsed-whitespace.html [ Failure Pass ]
+crbug.com/714962 svg/text/select-text-svgfont.html [ Failure ]
 crbug.com/591099 svg/text/selection-background-color.xhtml [ Failure ]
 crbug.com/591099 svg/text/selection-dragging-outside-1.html [ Failure ]
 crbug.com/591099 svg/text/selection-dragging-outside-2.html [ Failure ]
@@ -7724,28 +9452,37 @@
 crbug.com/591099 svg/text/selection-styles.xhtml [ Failure ]
 crbug.com/591099 svg/text/small-fonts-in-html5.html [ Failure ]
 crbug.com/591099 svg/text/surrogate-pair-queries.html [ Failure ]
+crbug.com/714962 svg/text/text-outline-2.html [ Failure ]
 crbug.com/591099 svg/text/text-repaint-rects.xhtml [ Failure ]
+crbug.com/714962 svg/text/text-selection-align-01-b.svg [ Failure ]
+crbug.com/714962 svg/text/text-selection-align-05-b.svg [ Failure ]
+crbug.com/714962 svg/text/text-selection-text-06-t.svg [ Failure ]
+crbug.com/714962 svg/text/tspan-multiple-outline.svg [ Failure ]
 crbug.com/591099 svg/transforms/svg-css-transforms-clip-path.xhtml [ Failure ]
 crbug.com/591099 svg/transforms/svg-css-transforms.xhtml [ Failure ]
+crbug.com/714962 svg/transforms/text-with-mask-with-svg-transform.svg [ Failure ]
 crbug.com/591099 svg/transforms/text-with-pattern-inside-transformed-html.xhtml [ Failure ]
+crbug.com/714962 svg/transforms/text-with-pattern-with-svg-transform.svg [ Failure ]
 crbug.com/591099 svg/transforms/transformed-text-fill-pattern.html [ Failure ]
 crbug.com/591099 svg/wicd/rightsizing-grid.html [ Failure ]
 crbug.com/591099 svg/wicd/test-rightsizing-a.xhtml [ Failure ]
 crbug.com/591099 svg/wicd/test-rightsizing-b.xhtml [ Failure ]
-crbug.com/591099 svg/wicd/test-scalable-background-image1.xhtml [ Failure ]
+crbug.com/591099 svg/wicd/test-scalable-background-image1.xhtml [ Crash Failure ]
 crbug.com/591099 svg/wicd/test-scalable-background-image2.xhtml [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-background-image-tiled.html [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-background-images.html [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-clip-path.html [ Failure ]
+crbug.com/714962 svg/zoom/page/zoom-coords-viewattr-01-b.svg [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-foreign-content.svg [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-foreignObject.svg [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-hixie-mixed-008.xml [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-hixie-mixed-009.xml [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-hixie-rendering-model-004.xhtml [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html [ Failure ]
+crbug.com/714962 svg/zoom/page/zoom-mask-with-percentages.svg [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-replaced-intrinsic-ratio-001.htm [ Failure ]
-crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size-and-viewBox.html [ Failure ]
-crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size.html [ Failure ]
+crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size-and-viewBox.html [ Crash Failure ]
+crbug.com/591099 svg/zoom/page/zoom-svg-as-background-with-relative-size.html [ Crash Failure ]
 crbug.com/591099 svg/zoom/page/zoom-svg-as-image.html [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-svg-as-object.html [ Failure ]
 crbug.com/591099 svg/zoom/page/zoom-svg-as-relative-image.html [ Failure ]
@@ -7763,46 +9500,99 @@
 crbug.com/591099 tables/layering/paint-test-layering-1.html [ Failure ]
 crbug.com/591099 tables/layering/paint-test-layering-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug101674.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug103533.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug106158-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug106158-2.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug106816.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug109043.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug110566.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug113235-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug11384q.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug11384s.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug1188.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug11944.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug12008.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug12268.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug126742.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug1271.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug1302.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug131020-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug131020.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug131020_iframe.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug13118.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug1318.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug13196.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug133948.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug137388-1.html [ Failure Pass ]
 crbug.com/591099 tables/mozilla/bugs/bug137388-2.html [ Failure Pass ]
 crbug.com/591099 tables/mozilla/bugs/bug137388-3.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug139524-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug14159-1.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug1430.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug149275-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug149275-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug16252.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug17130-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug17587.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug18359.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug18440.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug18664.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug18955.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug19599.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug20579.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug215629.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug219693-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug219693-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug221784-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug2267.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug23235.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug24200.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug2479-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug2479-3.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug2479-4.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug2509.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug26553.html [ Failure Pass ]
 crbug.com/591099 tables/mozilla/bugs/bug27038-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug27038-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug2757.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug2947.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug2962.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug2973.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug2981-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug2981-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug2997.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug30692.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug3191.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug32205-3.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug3454.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug38916.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug3977.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug43039.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug43854-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug4427.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug44523.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug4501.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug4527.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug4576.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46268-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46268-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46268-5.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46268.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46368-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46368-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46480-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46480-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug46623-1.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/bugs/bug46623-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug46924.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug48028-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug4803.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug4849-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug48827.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug50695-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug50695-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug51140.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug5188.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug53690-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug5538.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug55694.html [ Failure ]
@@ -7813,34 +9603,181 @@
 crbug.com/591099 tables/mozilla/bugs/bug59354.html [ Failure Pass ]
 crbug.com/591099 tables/mozilla/bugs/bug6304.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug641-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug650.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug69382-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug7112-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug7112-2.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug727.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug7342.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug78162.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug80762-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug82946-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug82946-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug8381.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug88035-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug88035-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug88524.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug9123-1.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug93363.html [ Failure ]
+crbug.com/714962 tables/mozilla/bugs/bug96334.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug98196.html [ Failure ]
+crbug.com/714962 tables/mozilla/collapsing_borders/bug127040.html [ Failure ]
 crbug.com/591099 tables/mozilla/collapsing_borders/bug41262-3.html [ Failure ]
+crbug.com/714962 tables/mozilla/collapsing_borders/bug41262-4.html [ Failure ]
 crbug.com/591099 tables/mozilla/core/bloomberg.html [ Crash Failure ]
 crbug.com/591099 tables/mozilla/core/captions.html [ Failure ]
 crbug.com/591099 tables/mozilla/core/cell_heights.html [ Failure ]
+crbug.com/714962 tables/mozilla/core/row_span.html [ Failure ]
 crbug.com/591099 tables/mozilla/core/table_heights.html [ Failure ]
+crbug.com/714962 tables/mozilla/core/table_rules.html [ Failure ]
+crbug.com/714962 tables/mozilla/dom/insertCellsRebuild1.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/col_span.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_align_center.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_align_justify.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_align_left.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_align_right.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_span.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_valign_baseline.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_valign_bottom.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_valign_middle.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_valign_top.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_width_pct.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/colgroup_width_px.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/table_rules_all.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_cellpadding.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_cellpadding_pct.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_cellspacing.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_class.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_style.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_td_align_center.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_td_align_left.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_td_align_right.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_td_colspan.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_td_height.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_td_rowspan.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_td_width.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_th_align_center.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_th_align_left.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_th_align_right.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_th_colspan.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_th_height.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_th_rowspan.html [ Failure ]
 crbug.com/591099 tables/mozilla/marvin/tables_th_width.html [ Failure Pass ]
+crbug.com/714962 tables/mozilla/marvin/tables_width_percent.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tables_width_px.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_align_center.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_align_char.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_align_justify.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_align_left.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_align_right.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_char.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_valign_baseline.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_valign_bottom.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_valign_middle.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tbody_valign_top.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/td_valign_bottom.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/td_valign_top.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_align_center.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_align_char.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_align_justify.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_align_left.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_align_right.html [ Failure ]
 crbug.com/591099 tables/mozilla/marvin/tfoot_char.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_valign_baseline.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_valign_bottom.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_valign_middle.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tfoot_valign_top.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/th_valign_bottom.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/th_valign_top.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_align_center.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_align_char.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_align_justify.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_align_left.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_align_right.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_char.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_valign_bottom.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/thead_valign_top.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tr_valign_bottom.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/tr_valign_top.html [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_col_valign_baseline.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_col_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_col_valign_middle.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_col_valign_top.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_col_width_pct.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_col_width_px.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_col_width_rel.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_colgroup_valign_baseline.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_colgroup_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_colgroup_valign_middle.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_colgroup_valign_top.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_colgroup_width_pct.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_colgroup_width_rel.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_table.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_table_style.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_align_center.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_align_char.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_align_justify.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_align_left.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_align_right.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_valign_baseline.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_valign_middle.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tbody_valign_top.xml [ Failure ]
 crbug.com/591099 tables/mozilla/marvin/x_td_align_justify.xml [ Failure Pass ]
+crbug.com/714962 tables/mozilla/marvin/x_td_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_td_valign_top.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_align_center.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_align_char.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_align_justify.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_align_left.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_align_right.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_valign_baseline.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_valign_middle.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tfoot_valign_top.xml [ Failure ]
 crbug.com/591099 tables/mozilla/marvin/x_th_align_justify.xml [ Failure Pass ]
+crbug.com/714962 tables/mozilla/marvin/x_th_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_th_valign_top.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_thead_align_justify.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_thead_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_thead_valign_top.xml [ Failure ]
 crbug.com/591099 tables/mozilla/marvin/x_tr_align_justify.xml [ Failure Pass ]
+crbug.com/714962 tables/mozilla/marvin/x_tr_valign_bottom.xml [ Failure ]
+crbug.com/714962 tables/mozilla/marvin/x_tr_valign_top.xml [ Failure ]
+crbug.com/714962 tables/mozilla/other/cellspacing.html [ Failure ]
+crbug.com/714962 tables/mozilla/other/test3.html [ Failure ]
+crbug.com/714962 tables/mozilla/other/test6.html [ Failure ]
 crbug.com/591099 tables/mozilla/other/wa_table_thtd_rowspan.html [ Failure ]
 crbug.com/591099 tables/mozilla/other/wa_table_tr_align.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/bugs/bug1010.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/bugs/bug10140.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug1055-2.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug1128.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug14007-1.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/bugs/bug14489.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/bugs/bug19526.html [ Failure ]
-crbug.com/591099 tables/mozilla_expected_failures/bugs/bug61042-1.html [ Failure ]
-crbug.com/591099 tables/mozilla_expected_failures/bugs/bug61042-2.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug21518.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug22122.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug23847.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug25707.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug32205-4.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug42043.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug4294.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug51000.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug56024.html [ Failure ]
+crbug.com/591099 tables/mozilla_expected_failures/bugs/bug61042-1.html [ Failure Pass ]
+crbug.com/591099 tables/mozilla_expected_failures/bugs/bug61042-2.html [ Failure Pass ]
 crbug.com/591099 tables/mozilla_expected_failures/bugs/bug7113.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug72393.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug80762-2.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/bugs/bug85016.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug89315.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/bugs/bug91057.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/collapsing_borders/bug41262-1.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/collapsing_borders/bug41262-5.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/collapsing_borders/bug41262-6.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/core/standards1.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/marvin/backgr_fixed-bg.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_bottom.html [ Failure ]
@@ -7849,8 +9786,31 @@
 crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_left.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_right.html [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/marvin/table_overflow_caption_top.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/marvin/table_rules_cols.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/marvin/table_rules_rows.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/marvin/tables_cellspacing_pct.html [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/marvin/x_colgroup_width_px.xml [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/marvin/x_table_rules_all.xml [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/marvin/x_table_rules_cols.xml [ Failure ]
+crbug.com/714962 tables/mozilla_expected_failures/marvin/x_table_rules_rows.xml [ Failure ]
 crbug.com/591099 tables/mozilla_expected_failures/other/test4.html [ Crash Pass ]
-crbug.com/591099 touchadjustment/editable-content.html [ Failure ]
+crbug.com/714962 tables/table-transform-absolute-position-child.html [ Failure ]
+crbug.com/714962 touchadjustment/context-menu-select-text.html [ Failure ]
+crbug.com/714962 touchadjustment/context-menu-text-subtargets.html [ Failure ]
+crbug.com/714962 touchadjustment/context-menu.html [ Failure ]
+crbug.com/714962 touchadjustment/disabled-formelements.html [ Failure ]
+crbug.com/591099 touchadjustment/editable-content.html [ Failure Pass ]
+crbug.com/714962 touchadjustment/event-triggered-widgets.html [ Failure ]
+crbug.com/714962 touchadjustment/html-label.html [ Failure ]
+crbug.com/714962 touchadjustment/iframe.html [ Failure ]
+crbug.com/714962 touchadjustment/nested-touch.html [ Failure ]
+crbug.com/714962 touchadjustment/plugin.html [ Failure ]
+crbug.com/714962 touchadjustment/scroll-offset.html [ Failure ]
+crbug.com/714962 touchadjustment/stylus-generated-gesture-tap.html [ Failure ]
+crbug.com/714962 touchadjustment/touch-inlines.html [ Failure ]
+crbug.com/714962 touchadjustment/touch-links-active.html [ Failure ]
+crbug.com/714962 touchadjustment/touch-links-longpress.html [ Failure ]
+crbug.com/714962 touchadjustment/touch-links-two-finger-tap.html [ Failure ]
 crbug.com/591099 transforms/2d/compound-transforms-vs-containers.html [ Failure ]
 crbug.com/591099 transforms/2d/cssmatrix-2d-zoom.html [ Failure ]
 crbug.com/591099 transforms/2d/hindi-rotated.html [ Failure ]
@@ -7878,6 +9838,7 @@
 crbug.com/591099 transforms/bounding-rect-zoom.html [ Failure ]
 crbug.com/591099 transforms/diamond.html [ Failure ]
 crbug.com/591099 transforms/identity-matrix.html [ Failure ]
+crbug.com/714962 transforms/inline-in-transformed-multicol.html [ Failure ]
 crbug.com/591099 transforms/matrix-01.html [ Failure ]
 crbug.com/591099 transforms/matrix-02.html [ Failure ]
 crbug.com/591099 transforms/matrix-with-zoom.html [ Failure ]
@@ -7886,6 +9847,7 @@
 crbug.com/591099 transforms/rotated-transform-affects-scrolling-1.html [ Failure ]
 crbug.com/591099 transforms/rotated-transform-affects-scrolling-2.html [ Failure ]
 crbug.com/591099 transforms/scrollIntoView-transformed.html [ Failure ]
+crbug.com/714962 transforms/selection-bounds-in-transformed-view.html [ Failure ]
 crbug.com/591099 transforms/shadows.html [ Failure ]
 crbug.com/591099 transforms/skew-with-unitless-zero.html [ Failure ]
 crbug.com/591099 transforms/svg-vs-css.xhtml [ Failure ]
@@ -7925,12 +9887,13 @@
 crbug.com/591099 virtual/gpu-rasterization/images/alt-text-wrapping.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-jpeg-with-color-profile.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-background-clip-text.html [ Failure ]
+crbug.com/714962 virtual/gpu-rasterization/images/color-profile-border-fade.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-border-image-source.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-border-radius.html [ Failure ]
-crbug.com/591099 virtual/gpu-rasterization/images/color-profile-drag-image.html [ Failure ]
+crbug.com/591099 virtual/gpu-rasterization/images/color-profile-drag-image.html [ Failure Pass ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-filter.html [ Failure Timeout ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-group.html [ Failure ]
-crbug.com/591099 virtual/gpu-rasterization/images/color-profile-iframe.html [ Failure ]
+crbug.com/591099 virtual/gpu-rasterization/images/color-profile-iframe.html [ Failure Pass ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-object-fit.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-profile-match.html [ Failure ]
@@ -7949,7 +9912,8 @@
 crbug.com/591099 virtual/gpu-rasterization/images/cross-fade-simple.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/cross-fade-sizing.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/cross-fade-tiled.html [ Failure ]
-crbug.com/591099 virtual/gpu-rasterization/images/drag-svg-image.html [ Failure ]
+crbug.com/714962 virtual/gpu-rasterization/images/drag-image-transformed-parent.html [ Failure ]
+crbug.com/591099 virtual/gpu-rasterization/images/drag-svg-image.html [ Failure Pass ]
 crbug.com/591099 virtual/gpu-rasterization/images/embed-does-not-propagate-dimensions-to-object-ancestor.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/exif-orientation-css.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/exif-orientation-height-image-document.html [ Failure ]
@@ -7973,6 +9937,7 @@
 crbug.com/591099 virtual/gpu-rasterization/images/image-map-zoom.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/image-zoom-to-25.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/imagemap-circle-focus-ring.html [ Failure ]
+crbug.com/714962 virtual/gpu-rasterization/images/imagemap-duplicate-outlines-crash.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/imagemap-focus-ring-in-positioned-container.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/imagemap-focus-ring-outline-color-not-inherited-from-map.html [ Failure ]
@@ -8004,10 +9969,11 @@
 crbug.com/591099 virtual/gpu-rasterization/images/sprite-no-bleed.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/webp-flip.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/width-on-broken-data-src.html [ Failure ]
-crbug.com/591099 virtual/gpu-rasterization/images/zoomed-img-size.html [ Crash ]
+crbug.com/591099 virtual/gpu-rasterization/images/zoomed-img-size.html [ Crash Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Pass Timeout ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-colorClamping.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-drawImage.html [ Timeout ]
+crbug.com/714962 virtual/gpu/fast/canvas/canvas-css-clip-path.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-animated-images.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-video-imageSmoothingEnabled.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-ellipse-connecting-line.html [ Failure ]
@@ -8015,20 +9981,36 @@
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-measure-bidi-text.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-render-layer.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-shadow-source-in.html [ Crash Failure Timeout ]
+crbug.com/714962 virtual/gpu/fast/canvas/canvas-text-ideographic-space.html [ Failure ]
+crbug.com/714962 virtual/gpu/fast/canvas/canvas-textMetrics-width.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-transforms-during-path.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/fill-stroke-clip-reset-path.html [ Failure ]
-crbug.com/591099 virtual/gpu/fast/canvas/fillrect_gradient.html [ Failure ]
+crbug.com/591099 virtual/gpu/fast/canvas/fillrect_gradient.html [ Failure Pass ]
+crbug.com/714962 virtual/gpu/fast/canvas/image-object-in-canvas.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/patternfill-repeat.html [ Failure Timeout ]
+crbug.com/714962 virtual/gpu/fast/canvas/setWidthResetAfterForcedRender.html [ Failure ]
 crbug.com/591099 virtual/high-contrast-mode/paint/high-contrast-mode/image-filter-all/text-on-backgrounds.html [ Failure ]
-crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/MouseEvent-prototype-offsetX-offsetY.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/MouseEvent-prototype-offsetX-offsetY.html [ Failure Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/shadow-trees/shadow-root-002.html [ Pass ]
+crbug.com/714962 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/styles/test-008.html [ Failure ]
 crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html [ Pass ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/content-pseudo-element-dynamic-attribute-change.html [ Failure ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/cppevent-input-in-shadow.html [ Failure ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/drop-event-for-input-in-shadow.html [ Crash ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/focus-navigation-with-distributed-nodes.html [ Crash ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/form-in-shadow.html [ Crash ]
-crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/selection-in-nested-shadow.html [ Failure ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/hover-active-drag-distributed-nodes.html [ Failure ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/import-rule-in-shadow-tree-needs-document-style-recalc.html [ Failure ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/input-color-in-content.html [ Timeout ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/scrollbar.html [ Crash ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/select-in-shadowdom.html [ Failure ]
+crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/selection-in-nested-shadow.html [ Failure Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/selections-in-shadow.html [ Timeout ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/shadow-boundary-crossing.html [ Failure ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/shadow-dom-event-dispatching-svg-in-shadow-subtree.html [ Failure ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/touch-event.html [ Failure ]
+crbug.com/714962 virtual/incremental-shadow-dom/fast/dom/shadow/wheel-event-on-input-in-shadow-dom.html [ Failure ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/active-element.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/css-cascade-outer-scope2.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/css-cascade-slot-distributed.html [ Pass ]
@@ -8037,8 +10019,9 @@
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-nested.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-with-tabindex.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slots.html [ Pass ]
+crbug.com/714962 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-with-delegatesFocus.html [ Timeout ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation.html [ Pass ]
-crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/host-pseudo-elements.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/host-pseudo-elements.html [ Failure Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/layout.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/range-caret-range-from-point-left-of-shadow.html [ Crash ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slots-1.html [ Pass ]
@@ -8050,108 +10033,143 @@
 crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/float-replaced-width-002.xht [ Pass ]
 crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-static-001.xht [ Pass ]
 crbug.com/591099 virtual/layout_ng/fast/block/basic/fieldset-stretch-to-legend.html [ Pass ]
-crbug.com/591099 virtual/layout_ng/fast/block/float/026.html [ Pass ]
-crbug.com/591099 virtual/layout_ng/fast/block/float/028.html [ Pass ]
+crbug.com/591099 virtual/layout_ng/fast/block/float/026.html [ Failure Pass ]
+crbug.com/591099 virtual/layout_ng/fast/block/float/028.html [ Failure Pass ]
 crbug.com/591099 virtual/layout_ng/fast/block/float/float-not-removed-from-first-letter.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/fast/block/float/float-on-zero-height-line.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/fast/block/float/marquee-shrink-to-avoid-floats.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/fast/block/float/nested-clearance.html [ Pass ]
-crbug.com/591099 virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Pass ]
+crbug.com/591099 virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure Pass ]
 crbug.com/591099 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-cols-creates-block-formatting-context.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/overflow/overflow-basic-003.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/overflow/overflow-bug-chrome-ng-001.html [ Pass ]
-crbug.com/591099 virtual/layout_ng_paint/ [ Skip ]
 crbug.com/591099 virtual/mojo-blobs/ [ Skip ]
 crbug.com/591099 virtual/mojo-localstorage/ [ Skip ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/anchor-empty-focus.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-in-overflow-hidden-html.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/autoscroll-disabled-in-fix.html [ Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-in-overflow-hidden-html.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-in-textfield.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-nonscrollable-iframe-in-scrollable-div.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/autoscroll-upwards-propagation-overflow-hidden-body.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-upwards-propagation-overflow-hidden-iframe-body.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-with-non-scrollable-parent.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/change-frame-focus.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/check-defocus-event-order-when-triggered-by-tab.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-focus-anchor.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-focus-svganchor-has-ring.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/click-checkbox-blur-refocus-window.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/click-checkbox-refocus-window.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-focus-anchor.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-focus-svganchor-has-ring.html [ Failure Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/click-over-descendant-elements.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-range-slider.html [ Crash ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-svganchor-blur-refocus-window.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-svganchor-refocus-window.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-svganchor-blur-refocus-window.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/click-svganchor-refocus-window.html [ Failure Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/click-with-large-negative-text-indent.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/content-changed-during-drop.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/context-no-deselect.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/contextmenu-follows-focus.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/contextmenu-scrolled-page-with-frame.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/document-elementFromPoint.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/domactivate-sets-underlying-click-event-as-handled.html [ Crash ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-and-drop-autoscroll-inner-frame.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-dragend-detaches.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-image-filename.html [ Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-and-drop-autoscroll-inner-frame.html [ Pass Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/drag-and-drop-subframe-dataTransfer.html [ Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/drag-dataTransferItemList-file-handling.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-dragend-detaches.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-image-filename.html [ Pass Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/drag-in-frames.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-selects-image.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-svg-image-crash.html [ Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag-svg-image-crash.html [ Pass Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/drag_and_drop_into_removed_on_focus.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/event-hit-testing-fallback-to-iframe.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/event-hit-testing-fallback-to-iframe.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/event-listener-on-link.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/event-on-culled-inline-with-pseudo.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/event-on-culled_inline.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/event-trusted.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/frame-click-focus.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/frame-detached-in-mousedown.html [ Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/file-input-hidden-in-ondrop.html [ Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/frame-click-focus.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/frame-detached-in-mousedown.html [ Pass Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/frame-programmatic-focus.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/frame-scroll-fake-mouse-move.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/frame-tab-focus.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/hit-test-counts.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/iframe-mousewheel.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/iframe-onmousemove.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/inputevents/beforeinput-remove-iframe-crash.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/iframe-mousewheel.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/iframe-onmousemove.html [ Pass Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/input-element-display-none-in-dragleave-crash.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/inputevents/beforeinput-remove-iframe-crash.html [ Failure Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/inputevents/inputevent-drag-drop.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/js-keyboard-event-creation.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/key-events-in-input-text.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/keyboardevent-getModifierState.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/keydown-1.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/keydown-1.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/keydown-keypress-focus-change.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/keydown-keypress-preventDefault.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/keypress-focus-change.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/media-element-focus-tab.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-in-iframe.html [ Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-click-hyperlink.html [ Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-in-iframe.html [ Pass Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-latching.html [ Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-nested-divs-forbidden.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-cursor-style-change-iframe.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-cursor-style-change-iframe.html [ Failure Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-drag-from-frame-to-other-frame.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-drag-from-frame.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-drag-from-frame.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-event-buttons-attribute.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-events-within-no-element.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-focus-imagemap.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-moved-remove-frame-crash.html [ Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouse-events-on-textarea-resize.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-events-within-no-element.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-focus-imagemap.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-moved-remove-frame-crash.html [ Pass Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-relative-position.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouseenter-mouseleave-inline-attributes.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouseenter-mouseleave.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseevent-getModifierState.html [ Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mousemove-after-drag-over-scrollbar.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mousemove-to-resizer-changes-cursor.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseover-mouseout.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/no-blur-on-enter-button.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/offsetX-offsetY.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onblur-remove.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/onchange-click-hang.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onchange-range-slider.html [ Crash ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onload-re-entry.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onload-webkit-before-webcore.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/page-scaled-mouse-click-iframe.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/page-scaled-mouse-click-iframe.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointer-events-2.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-on-object.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-node-remove.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-on-object.html [ Failure Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-boundary-events-for-shadowdom.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-capture-transition-events.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-capture.html [ Pass Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-preventdefault.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/multi-pointer-preventdefault.html [ Pass Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-capture.html [ Failure Pass Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-preventdefault.html [ Failure Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-transition-events.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-updown-events.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/multi-pointer-preventdefault.html [ Failure Pass Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/pointer-use-count.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/touch-capture-in-iframe.html [ Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/touch-capture.html [ Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/touch-pointer-events.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/touch-pointercancel.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/popup-allowed-from-gesture-initiated-event.html [ Crash Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/popup-allowed-from-gesture-only-once-iframes.html [ Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/popup-blocked-from-different-frames.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/popup-blocking-click-in-iframe.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/remove-target-in-mouseup.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/remove-target-with-shadow-in-drag.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/popup-blocked-from-untrusted-mouse-click.html [ Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/popup-blocked-from-wrong-event.html [ Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/popup-blocking-click-in-iframe.html [ Pass Timeout ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/remove-target-in-mouseup.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/remove-target-with-shadow-in-drag.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/reveal-link-when-focused.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/right-click-focus.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/scroll-after-click-on-tab-index.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/scroll-div-with-prevent-default-in-subframe.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/scroll-to-anchor-in-overflow-hidden.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/select-element.html [ Timeout ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/select-onchange-mouse-released-outside.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/select-onchange-mouse-released-outside.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/selectstart-by-double-triple-clicks.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/selectstart-by-drag.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/selectstart-by-single-click-with-shift.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/sequential-focus-navigation-starting-point.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/simulated-click-coords.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/submit-reset-nested-bubble.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/tab-imagemap.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/tabindex-focus-blur-all.html [ Crash ]
@@ -8160,20 +10178,25 @@
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-click-on-inline-continations.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-frame-move.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-mouse-events-between-frames.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-near-iframe.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/long-press-drag-drop-touch-editing-combined-in-iframe.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/long-press-focuses-frame.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-scroll-iframe-editable.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-scroll-iframe-past-extent.html [ Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-input-after-composition.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-mouse-events-between-frames.html [ Failure Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-mouse-events.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-near-iframe.html [ Failure Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-result.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/long-press-drag-drop-touch-editing-combined-in-iframe.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/long-press-focuses-frame.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-scroll-iframe-editable.html [ Failure Pass ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-scroll-iframe-past-extent.html [ Failure Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/touch-action-range-input-crash.html [ Crash ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/touch-action-range-input-csp.html [ Crash ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/touch-action-range-input.html [ Crash ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/touch/touch-before-pressing-spin-button.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/touch-fractional-coordinates.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/touch-handler-assert-input-range.html [ Crash ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/touch-slider-no-js-touch-listener.html [ Crash ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/touch-slider.html [ Crash ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/latched-scroll-node-removed.html [ Pass ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/wheel/wheelevent-basic.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/window-events-bubble.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/window-events-bubble2.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/window-events-capture.html [ Failure ]
@@ -8184,16 +10207,23 @@
 crbug.com/591099 virtual/paint-timing/external/wpt/paint-timing/sibling-painting-first-image.html [ Failure ]
 crbug.com/591099 virtual/prefer_compositing_to_lcd_text/ [ Skip ]
 crbug.com/591099 virtual/prefer_compositing_to_lcd_text/compositing/overflow/composited-scroll-with-fractional-translation.html [ Pass ]
+crbug.com/714962 virtual/pwa-full-code-cache/http/tests/devtools/service-workers/service-workers-view.js [ Failure ]
 crbug.com/591099 virtual/rootlayerscrolls/ [ Skip ]
 crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance.html [ Failure ]
 crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ]
-crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/drag-image.html [ Failure ]
+crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/drag-image.html [ Failure Pass ]
 crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ]
 crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure ]
-crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/drag-image.html [ Failure ]
+crbug.com/714962 virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance.html [ Failure ]
+crbug.com/714962 virtual/scalefactor200/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ]
+crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/drag-image.html [ Failure Pass ]
+crbug.com/714962 virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance.html [ Failure ]
 crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ]
 crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure ]
-crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/drag-image.html [ Failure ]
+crbug.com/714962 virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance.html [ Failure ]
+crbug.com/714962 virtual/scalefactor200withzoom/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ]
+crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/drag-image.html [ Failure Pass ]
+crbug.com/714962 virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance.html [ Failure ]
 crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ]
 crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure ]
 crbug.com/591099 virtual/scroll_customization/ [ Skip ]
@@ -8207,11 +10237,15 @@
 crbug.com/591099 virtual/spv175/compositing/absolute-inside-out-of-view-fixed.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/animation/busy-indicator.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/animation/state-at-end-event-transform-layer.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/background-color/view-blending-base-background.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/checkerboard.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/child-transform-layer-requires-box.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/clip-child-by-non-stacking-ancestor.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/clip-path-with-composited-descendent.html [ Pass ]
 crbug.com/591099 virtual/spv175/compositing/color-matching/image-color-matching.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/columns/composited-in-paginated.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/composited-descendant-grandparent-border-radius-mask.html [ Pass ]
+crbug.com/714962 virtual/spv175/compositing/composited-descendant-requiring-border-radius-mask.html [ Pass ]
 crbug.com/591099 virtual/spv175/compositing/compositing-visible-descendant.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/contents-opaque/background-clip.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/contents-opaque/background-color.html [ Failure ]
@@ -8231,6 +10265,7 @@
 crbug.com/591099 virtual/spv175/compositing/filters/sw-shadow-overlaps-hw-layer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/filters/sw-shadow-overlaps-hw-shadow.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/fixed-position-changed-to-absolute.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/flex-composited-animated-table-row-background.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/framesets/composited-frame-alignment.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/generated-content.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/abs-position-inside-opacity.html [ Failure ]
@@ -8243,7 +10278,7 @@
 crbug.com/591099 virtual/spv175/compositing/geometry/clip-inside.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/clip-with-shadow.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/clip.html [ Failure ]
-crbug.com/591099 virtual/spv175/compositing/geometry/clipping-foreground.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/geometry/clipping-foreground.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/composited-html-size.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/composited-in-columns.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/fixed-in-composited.html [ Failure ]
@@ -8253,7 +10288,7 @@
 crbug.com/591099 virtual/spv175/compositing/geometry/fixed-position-transform-composited-page-scale.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/fixed-position.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/flipped-writing-mode.html [ Failure ]
-crbug.com/591099 virtual/spv175/compositing/geometry/foreground-layer.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/geometry/foreground-layer.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/horizontal-scroll-composited.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/layer-due-to-layer-children-deep-switch.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/layer-due-to-layer-children-deep.html [ Failure ]
@@ -8274,14 +10309,60 @@
 crbug.com/591099 virtual/spv175/compositing/geometry/vertical-scroll-composited.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/video-fixed-scrolling.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/geometry/video-opacity-overlay.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-composite.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled-late-noncomposite.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-iframe-composited-scrolled.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-iframe-composited.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-iframe-scrolled.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-iframe.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-composited-scroll-clip.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-composited-scrolled.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-composited.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change-2.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-layout-change.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled-late-composite.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled-late-noncomposite.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div-scrolled.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-1-overflow-div.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-iframe-composited-inner.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-iframe-composited-outer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-inner-late-composite.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-inner.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-outer-late-composite.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-iframe-scrolled-outer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-iframe.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner-scroll-inner.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner-scroll-outer.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-inner.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer-scroll-inner.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer-scroll-outer.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-composited-outer.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-scrolled-inner.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div-scrolled-outer.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-2-overflow-div.html [ Crash ]
 crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-img-and-text-2.html [ Failure ]
-crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-img-transformed.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-img-and-text.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/gestures/gesture-tapHighlight-img-transformed.html [ Failure Pass ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-img.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-invisible-inline-squashing.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-invisible-inline.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-on-promoted-overflow-div-scrolled.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-pixel-rotated-link.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-pixel-transparent.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-shadow-tree.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-cancel.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-cancel2.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-margin.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-multi-line.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-navigate.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-nested.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-scaled-document.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-scaledX.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-scaledY.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple-window-scroll.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-simple.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-with-box-shadow.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/gestures/gesture-tapHighlight-with-squashing.html [ Crash ]
 crbug.com/591099 virtual/spv175/compositing/iframes/become-composited-nested-iframes.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/iframes/become-overlapped-iframe.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/iframes/composited-iframe-alignment.html [ Failure ]
@@ -8310,6 +10391,7 @@
 crbug.com/591099 virtual/spv175/compositing/iframes/resizer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/iframes/scrolling-iframe.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/images/direct-image-background-color.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/images/direct-image-dynamic-border-radius.html [ Pass ]
 crbug.com/591099 virtual/spv175/compositing/images/direct-svg-image.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/img-layer-object-fit.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/layer-creation/animation-overlap-with-children.html [ Failure ]
@@ -8362,23 +10444,28 @@
 crbug.com/591099 virtual/spv175/compositing/masks/multiple-masks.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/masks/simple-composited-mask.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/nested-border-radius-composited-child.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/overflow/absolute-element-in-isolated-composited-ancestor.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/overflow/accelerated-scrolling-with-clip-reference.html [ Pass ]
 crbug.com/591099 virtual/spv175/compositing/overflow/ancestor-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-on-squashed-layers.html [ Failure Pass ]
 crbug.com/591099 virtual/spv175/compositing/overflow/clear-scroll-parent.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/clip-descendents.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/clip-parent-reset.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/clipping-ancestor-with-accelerated-scrolling-ancestor.html [ Failure ]
-crbug.com/591099 virtual/spv175/compositing/overflow/composited-nested-sticky-left.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/overflow/composited-nested-sticky-left.html [ Failure Pass ]
 crbug.com/591099 virtual/spv175/compositing/overflow/composited-scrolling-paint-phases.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/content-gains-scrollbars.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/content-loses-scrollbars.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/do-not-crash-use-after-free-update-widget-positions.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/overflow/fixed-element-in-isolated-composited-ancestor.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/fixed-position-ancestor-clip.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/fractional-sized-scrolling-layer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/get-transform-from-non-box-container.html [ Crash ]
+crbug.com/714962 virtual/spv175/compositing/overflow/image-load-overflow-scrollbars.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-filter.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-small-content-rect.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/overflow/mixed-composited-nested-sticky-overflow-scroller.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/nested-border-radius-clipping.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/nested-render-surfaces-with-intervening-clip.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/nested-render-surfaces-with-rotation.html [ Failure ]
@@ -8393,9 +10480,11 @@
 crbug.com/591099 virtual/spv175/compositing/overflow/overflow-scrollbar-layers.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/overflow-with-negative-z-index-child.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/parent-overflow.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/overflow/relpos-under-abspos-border-radius.html [ Pass ]
 crbug.com/591099 virtual/spv175/compositing/overflow/remove-overflow-crash2.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/reparented-scrollbars-non-sc-anc.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/resize-painting.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/overflow/rtl-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/scaled-mask.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/scaled-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/scroll-parent-absolute-with-backdrop-filter.html [ Failure ]
@@ -8491,15 +10580,18 @@
 crbug.com/591099 virtual/spv175/compositing/squashing/squash-transform-repainting-child.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squash-transform-repainting-transformed-child.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squash-transform.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/squashing/squash-with-ancestor-reflection.html [ Pass ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squashed-layer-loses-graphicslayer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squashed-repaints.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squashing-does-not-stop-transform-propagation.html [ Crash ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squashing-inside-perspective.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squashing-print.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/squashing/squashing-sparsity-heuristic.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/squashing/universal-accelerated-overflow-scrolling.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/squashing/vertical-writing-mode-squashed.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/text-on-large-layer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/tiled-layers-hidpi.html [ Failure ]
+crbug.com/714962 virtual/spv175/compositing/transitions/transform-on-large-layer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/update-paint-phases.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/video-frame-size-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/video/video-controls-layer-creation.html [ Failure ]
@@ -8519,9 +10611,11 @@
 crbug.com/591099 virtual/spv175/paint/background/rounded-clip-fractional-offset.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/filters/clip-filter-overflow-clip.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/filters/clip-under-filter.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/float/float-text-clip.html [ Crash ]
 crbug.com/591099 virtual/spv175/paint/frames/frameset-with-stacking-context-and-not-stacking-context-children.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/frames/frameset-with-stacking-contexts.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/high-contrast-mode/image-filter-all/text-on-backgrounds.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/inline/floating-inline.html [ Crash ]
 crbug.com/591099 virtual/spv175/paint/inline/focus-ring-under-absolute-with-relative-continuation.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/inline/outline-offset.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/input/textarea-crash.html [ Crash ]
@@ -8556,7 +10650,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/box/border-radius-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/box/border-radius-without-border.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/box/border-repaint-glitch.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/box/box-inline-resize.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/box/box-inline-resize.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/box/box-shadow-add-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/box/box-shadow-change-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/box/box-shadow-dynamic.html [ Failure ]
@@ -8582,7 +10676,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/bugzilla-6388.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/bugzilla-6473.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/bugzilla-7235.html [ Crash ]
-crbug.com/591099 virtual/spv175/paint/invalidation/button-inner-no-repaint.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/button-inner-no-repaint.html [ Failure Pass ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/caret-ancestor-clip-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/clip-unclip-and-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/clip-with-layout-delta.html [ Failure ]
@@ -8592,6 +10686,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/intermediate-layout-position-clip.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/mask-clip-change-stacking-child.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/outline-clip-change.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/clip/repaint-subsequence-on-ancestor-clip-change-complex.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/repaint-tile-clipped.html [ Crash ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/replaced-clipped-positioned-not-wrong-incremental-repainting.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/clip/resize-with-border-clipped.html [ Failure ]
@@ -8608,6 +10703,8 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/compositing/composited-document-element.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/compositing/composited-float-under-composited-inline-individual.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/compositing/composited-float-under-composited-inline.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/compositing/composited-inline-change-text-data-keep-geometry.html [ Crash ]
+crbug.com/714962 virtual/spv175/paint/invalidation/compositing/composited-non-stacking-context-not-invalidation-container.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/compositing/compositing-reason-removed.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/compositing/containing-block-added-individual.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/compositing/containing-block-added.html [ Failure ]
@@ -8705,15 +10802,16 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/filters/filter-repaint-accelerated-child-with-filter-child.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/filters/filter-repaint-accelerated-on-accelerated-filter.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/filters/filter-repaint-on-accelerated-layer.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/first-line-inline-child.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-content-change-keeping-geometry.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-content-change-no-flex.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-content-change-no-flex.html [ Failure Pass ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-content-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-content-distribution-change-grid.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-items-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-self-change-grid.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-self-change-keeping-geometry-grid.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-self-change-keeping-geometry.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-self-change-no-flex.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-self-change-no-flex.html [ Failure Pass ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/align-self-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/justify-content-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/flexbox/justify-content-distribution-change-grid.html [ Failure ]
@@ -8748,6 +10846,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/iframe-display-none-to-display-block.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/iframe-rounding.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/image/animated-gif-transformed-offscreen.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/image/percent-size-image-resize-container.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/in-scaled-iframe.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/inline-block-resize.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/inline-color-change.html [ Failure ]
@@ -8837,9 +10936,14 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/fixed-position-transparency-with-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/flexible-box-overflow-horizontal.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/flexible-box-overflow.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/overflow/float-overflow-right.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/overflow/float-overflow.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/overflow/float-overflow-right.html [ Crash Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/overflow/float-overflow.html [ Crash Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/overflow/inline-block-overflow-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/inline-block-overflow.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/overflow/inline-box-overflow-repaint.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/overflow/inline-overflow.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/overflow/inline-vertical-lr-overflow.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/overflow/inline-vertical-rl-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/justify-items-overflow-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/justify-self-overflow-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/line-overflow.html [ Failure ]
@@ -8850,6 +10954,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/overflow-hidden-to-visible.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/overflow-hide.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/overflow-into-content.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/overflow/overflow-outline-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/overflow-show.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/rel-positioned-inline-with-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/repaint-resized-overflow.html [ Failure ]
@@ -8891,16 +10996,16 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/position/positioned-document-element.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/positioned-great-grandparent-change-location.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/positioned-list-offset-change-repaint.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/position/relative-inline-positioned-movement-repaint.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/position/relative-inline-positioned-movement-repaint.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/relative-margin-change-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/relative-positioned-movement-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/relayout-fixed-position-after-scale.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/shift-relative-positioned-container-with-image-addition.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/shift-relative-positioned-container-with-image-removal.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/static-to-positioned.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/position/text-in-relative-positioned-inline.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/position/text-in-relative-positioned-inline.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/transform-absolute-child.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/position/transform-absolute-in-positioned-container.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/position/transform-absolute-in-positioned-container.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/position/transform-relative-position.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/push-block-with-first-line.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/quotes.html [ Failure ]
@@ -8911,7 +11016,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/reflection/scroll-absolute-layer-with-reflection.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/reflection/scroll-fixed-layer-with-reflection.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/reflection/scroll-fixed-reflected-layer.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/remove-anonymous-block-crash.html [ Crash ]
+crbug.com/591099 virtual/spv175/paint/invalidation/remove-anonymous-block-crash.html [ Crash Pass ]
 crbug.com/591099 virtual/spv175/paint/invalidation/remove-block-after-layout.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/remove-inline-after-layout.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/remove-inline-layer-after-layout.html [ Failure ]
@@ -8992,8 +11097,10 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/selected-replaced.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/selection-after-delete.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/selection-after-remove.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/selection/selection-and-text-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/selection-clear.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/selection/selection-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/selection-within-composited-scroller.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/text-selection-rect-in-overflow-2.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/selection/text-selection-rect-in-overflow.html [ Failure ]
@@ -9009,9 +11116,10 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/deep-nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/embedded-svg-size-changes-no-layout-triggers.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/foreign-object-repaint.svg [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/svg/hit-test-with-br.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-1.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/svg/nested-embedded-svg-size-changes.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/svg/nested-embedded-svg-size-changes.html [ Failure Pass ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/overflow-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-content-with-resources.xhtml [ Failure ]
@@ -9035,9 +11143,10 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/svg-image-change-content-size.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/svg-layout-root-style-attr-update.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/text-rescale.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/svg/text-xy-updates-SVGList.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/transform-focus-ring-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/transform-foreign-object.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/svg/use-instanceRoot-event-bubbling.xhtml [ Timeout ]
+crbug.com/591099 virtual/spv175/paint/invalidation/svg/use-instanceRoot-event-bubbling.xhtml [ Pass Timeout ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/use-setAttribute-crash.svg [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/add-table-overpaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/block-selection-gap-in-table-cell.html [ Failure ]
@@ -9055,6 +11164,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/table/caret-contenteditable-content-after.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/collapsed-border-cell-resize.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/collapsed-border-change-rowspan.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/table/collapsed-border-current-color.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/composited-table-background-col-initial-empty.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/composited-table-background-col-span-initial-empty.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/composited-table-background-col-span.html [ Failure ]
@@ -9083,6 +11193,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/table/scroll-inside-table-cell.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/scroll-relative-table-inside-table-cell.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/table/table-cell-become-visible-using-row-background.html [ Crash ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-cell-collapsed-border.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-cell-move.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-cell-overflow.html [ Failure ]
@@ -9095,7 +11206,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-row.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-section-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-section-repaint.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/table/table-shrink-row-repaint.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/table/table-shrink-row-repaint.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-two-pass-layout-overpaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-writing-modes-h.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/table/table-writing-modes-v.html [ Failure ]
@@ -9104,6 +11215,9 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/text-emphasis-h.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/text-emphasis-v.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/text-match-document-change.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/text-match-pre-wrapped-text.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/text-match-transparent-text.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/invalidation/text-match.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/text-shadow-horizontal.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/text-shadow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/transform/change-transform.html [ Failure ]
@@ -9113,7 +11227,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/transform/subpixel-offset-scaled-transform.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/transform/subtree-layoutstate-transform.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/transform/transform-disable-layoutstate.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/transform/transform-inline-layered-child.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/transform/transform-inline-layered-child.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/transform/transform-layout-repaint.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/transform/transform-repaint-descendants.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/transform/transform-rotate-and-remove.html [ Failure ]
@@ -9151,7 +11265,7 @@
 crbug.com/591099 virtual/spv175/paint/markers/grammar-markers-hidpi.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/markers/grammar-markers.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/markers/inline-spelling-markers-hidpi-composited.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/markers/inline-spelling-markers-hidpi.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/markers/inline-spelling-markers-hidpi.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/markers/inline_spelling_markers.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/markers/marker-early-break-bug.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/markers/suggestion-marker-basic.html [ Failure ]
@@ -9165,6 +11279,8 @@
 crbug.com/591099 virtual/spv175/paint/printing/print-text-shadow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/roundedrects/circle-with-shadow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/roundedrects/input-with-rounded-rect-and-shadow.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/selection/text-selection-counter.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/selection/text-selection-drag.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/selection/text-selection-inline-block-rtl.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/selection/text-selection-inline-block.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/selection/text-selection-newline-across-blocks-line-beginning-end.html [ Failure ]
@@ -9179,11 +11295,13 @@
 crbug.com/591099 virtual/spv175/paint/selection/text-selection-newline-vertical-lr.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/selection/text-selection-newline-vertical-rl.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/selection/text-selection-newline.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/selection/text-selection-update-style.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/selection/text-selection-with-composition.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/subpixel/transform-inside-clip.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/tables/collapsed-border-corner-conflict.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/tables/composited-collapsed-table-borders.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/text/selection-no-clip-text.html [ Failure ]
+crbug.com/714962 virtual/spv175/paint/text/text-match-highlights-big-line-height.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/theme/adjust-progress-bar-size.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/transforms/percentage-transform-fractional-box-size.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/transparency/compositing-alpha-fold-crash.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index ebcc5853..e083d65 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -25,14 +25,10 @@
 Bug(none) external/wpt/preload/fetch-destination.https.html [ Crash Failure Timeout ]
 Bug(none) external/wpt/resource-timing/test_resource_timing.html [ Failure Timeout ]
 Bug(none) external/wpt/service-workers/service-worker/claim-shared-worker-fetch.https.html [ Failure ]
-Bug(none) external/wpt/service-workers/service-worker/client-navigate.https.html [ Failure ]
 Bug(none) external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Failure ]
 Bug(none) external/wpt/service-workers/service-worker/clients-get.https.html [ Failure ]
-Bug(none) external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Crash ]
-Bug(none) external/wpt/service-workers/service-worker/fetch-event-redirect.https.html [ Pass Crash ]
 Bug(none) external/wpt/service-workers/service-worker/fetch-event-respond-with-response-body-with-invalid-chunk.https.html [ Failure ]
 Bug(none) external/wpt/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html [ Timeout ]
-Bug(none) external/wpt/service-workers/service-worker/fetch-event.https.html [ Timeout ]
 Bug(none) external/wpt/service-workers/service-worker/fetch-request-resources.https.html [ Pass Failure Crash ]
 Bug(none) external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https.html [ Timeout ]
 Bug(none) external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Timeout ]
@@ -93,8 +89,8 @@
 crbug.com/778542 http/tests/devtools/tracing/timeline-network/timeline-network-resource-details.js [ Failure Pass ]
 crbug.com/778542 virtual/threaded/http/tests/devtools/tracing/timeline-js/timeline-open-function-call.js [ Failure ]
 crbug.com/778542 virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-grouped-invalidations.js [ Failure ]
-crbug.com/721408 http/tests/devtools/extensions-ignore-cache.html [ Crash ]
-crbug.com/721408 http/tests/devtools/extensions-useragent.html [ Crash ]
+crbug.com/721408 http/tests/devtools/extensions/extensions-ignore-cache.js [ Crash ]
+crbug.com/721408 http/tests/devtools/extensions/extensions-useragent.js [ Crash ]
 crbug.com/721408 http/tests/devtools/network/load-resource-for-frontend.js [ Failure Timeout ]
 crbug.com/721408 http/tests/devtools/network/long-script-content.js  [ Crash ]
 crbug.com/721408 http/tests/devtools/network/network-datareceived.js [ Failure ]
@@ -134,7 +130,6 @@
 Bug(none) http/tests/loading/307-after-303-after-post.html [ Failure ]
 Bug(none) http/tests/doc-write-intervention/doc-write-sync-third-party-script-reload.html [ Crash ]
 Bug(none) http/tests/loading/bad-scheme-subframe.html [ Failure ]
-Bug(none) http/tests/local/serviceworker/fetch-request-body-file.html [ Crash Timeout ]
 Bug(none) http/tests/media/video-buffered.html [ Timeout ]
 Bug(none) http/tests/misc/embed-image-load-outlives-gc-without-crashing.html [ Failure Pass ]
 Bug(none) http/tests/misc/image-input-type-outlives-gc-without-crashing.html [ Failure Pass ]
@@ -168,7 +163,6 @@
 Bug(none) http/tests/serviceworker/chromium.update-served-from-cache.html [ Failure ]
 Bug(none) http/tests/serviceworker/chromium/register-error-messages.html [ Failure ]
 Bug(none) http/tests/serviceworker/chromium/request-body-blob-crash.html [ Crash Failure ]
-Bug(none) http/tests/serviceworker/chromium/stop-worker-during-respond-with.html [ Failure ]
 Bug(none) http/tests/serviceworker/chromium/stop-worker-with-pending-fetch.html [ Timeout ]
 Bug(none) http/tests/websocket/cookie-document-to-ws.html [ Failure ]
 Bug(none) http/tests/websocket/cookie-http-to-ws.pl [ Failure ]
@@ -238,3 +232,48 @@
 crbug.com/777879 external/wpt/FileAPI/file/send-file-form-windows-1252.tentative.html [ Crash ]
 crbug.com/777879 external/wpt/FileAPI/file/send-file-form-x-user-defined.tentative.html [ Crash ]
 crbug.com/777879 external/wpt/FileAPI/file/send-file-form.html [ Crash ]
+
+# NetworkService: ServiceWorker URLLoader are destroyed before the end of a navigation.
+# See https://crbug.com/790933
+Bug(790933) external/wpt/fetch/api/abort/serviceworker-intercepted.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/claim-affect-other-registration.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/client-navigate.https.html [ Pass Failure Crash Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-canvas-tainting-cache.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-canvas-tainting.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-cors-exposed-header-names.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-cors-xhr.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-csp.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-event-redirect.https.html [ Pass Crash Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-event.https.html [ Pass Failure Crash Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-frame-resource.https.html [ Pass Failure Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Pass Failure Crash Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-request-css-cross-origin-mime-check.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-request-no-freshness-headers.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-request-redirect.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/fetch-response-taint.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/getregistrations.https.html [ Pass Failure Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/navigation-preload/chunked-encoding.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/navigation-preload/redirect.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/navigation-preload/request-headers.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/navigation-redirect-body.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/referer.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/referrer-policy-header.https.html [ Pass Timeout ]
+Bug(790933) external/wpt/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html [ Pass Timeout ]
+Bug(790933) http/tests/devtools/service-workers/service-workers-navigation-preload.js [ Pass Timeout ]
+Bug(790933) http/tests/fetch/referrer/origin-when-cross-origin-serviceworker-from-document.html [ Pass Timeout Crash ]
+Bug(790933) http/tests/fetch/referrer/serviceworker-from-origin-only-document.html [ Pass Timeout ]
+Bug(790933) http/tests/local/serviceworker/fetch-request-body-file.html [ Pass Crash Failure Timeout ]
+Bug(790933) http/tests/serviceworker/chromium.fetch-canvas-tainting.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium.fetch-cors-xhr.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium.fetch-csp.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium.redirected-response.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium.respond-to-same-origin-request-with-cross-origin-response.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium.respond-to-same-origin-request-with-redirected-cross-origin-response.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium/css-import-crash.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium/fetch-request-with-gc.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium/fetch-script-onerror.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/chromium/stop-worker-during-respond-with.html [ Pass Failure Timeout ]
+Bug(790933) http/tests/serviceworker/navigation-preload/chromium/navigation-preload-gc-before-response.html [ Pass Timeout ]
+Bug(790933) http/tests/serviceworker/navigation-preload/chromium/use-counter.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index 2ae799e..130a7dd4 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -1034,6 +1034,10 @@
 crbug.com/707444 svg/custom/clip-mask-negative-scale.svg [ Failure ]
 crbug.com/707444 svg/custom/mask-inside-defs.svg [ Failure ]
 
+# No border radius applied to iframe documents
+Bug(none) fast/borders/border-radius-iframe.html [ Failure ]
+Bug(none) compositing/overflow/border-radius-composited-subframe.html [ Failure ]
+
 # Subpixel differences
 Bug(none) compositing/composited-scaled-child-with-border-radius-parent-clip.html [ Failure ]
 Bug(none) compositing/composited-translated-child-with-border-radius-parent-clip.html [ Failure ]
@@ -1733,5 +1737,6 @@
 Bug(none) compositing/overflow-trumps-transform-style.html [ Failure ]
 
 Bug(none) css3/blending/mix-blend-mode-simple.html [ Pass Timeout ]
+Bug(none) css3/blending/mix-blend-mode-simple-text.html [ Pass Timeout ]
 
 crbug.com/708175 virtual/mojo-blobs/external/wpt/IndexedDB/interleaved-cursors.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
index 322a941c..748f826 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -1,6 +1,9 @@
 # These tests currently fail when they run with --site-per-process.
 # See https://crbug.com/477150.
 
+# https://crbug.com/793127: Crash related to frame consolidation CL.
+crbug.com/793127 http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ]
+
 # https://crbug.com/789781: Document blocking should skip these cases.
 crbug.com/789781 http/tests/xmlhttprequest/origin-whitelisting-exact-match.html [ Failure ]
 crbug.com/789781 http/tests/xmlhttprequest/origin-whitelisting-removal.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index 2b19953..9a0367c 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -1820,6 +1820,10 @@
 external/wpt/css/css-color/t425-hsla-onscreen-multiple-boxes-c.xht [ WontFix ]
 external/wpt/css/css-color/t425-hsla-parsing-f.xht [ WontFix ]
 
+# https://github.com/w3c/web-platform-tests/issues/8547
+external/wpt/css/mediaqueries/device-aspect-ratio-001.html [ WontFix ]
+external/wpt/css/mediaqueries/device-aspect-ratio-005.html [ WontFix ]
+
 # Requires --use-fake-ui-for-media-stream to run.
 external/wpt/mediacapture-streams/MediaStream-default-feature-policy.https.html [ WontFix ]
 
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index e9b51511..e6488543 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -103,8 +103,8 @@
 
 # Misc DevTools tests that are slow
 crbug.com/246190 [ Release ] http/tests/devtools/indexeddb/ [ Slow ]
-crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-sidebar.html [ Slow ]
-crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-events.html [ Slow ]
+crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-sidebar.js [ Slow ]
+crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-events.js [ Slow ]
 crbug.com/667560 http/tests/devtools/startup/console/console-format-startup.html [ Slow ]
 crbug.com/679833 http/tests/devtools/network/network-datareceived.js [ Slow ]
 webkit.org/b/90488 [ Release ] http/tests/devtools/compiler-source-mapping-debug.js [ Slow ]
@@ -118,9 +118,9 @@
 crbug.com/451577 http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.js [ Slow ]
 crbug.com/451577 http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.js [ Slow ]
 crbug.com/510337 http/tests/devtools/elements/styles-1/edit-value-url-with-color.js [ Slow ]
-crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-reload.html [ Slow ]
-crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-resources.html [ Slow ]
-crbug.com/451577 [ Win10 ] http/tests/devtools/extensions/extensions-sidebar.html [ Slow ]
+crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-reload.js [ Slow ]
+crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-resources.js [ Slow ]
+crbug.com/451577 [ Win10 ] http/tests/devtools/extensions/extensions-sidebar.js [ Slow ]
 crbug.com/451577 [ Mac ] http/tests/devtools/layers/layer-canvas-log.js [ Slow ]
 crbug.com/451577 [ Mac ] http/tests/devtools/network/network-domain-filter.js [ Slow ]
 
@@ -173,7 +173,7 @@
 crbug.com/241576 [ Win ] http/tests/appcache/404-manifest.html [ Slow ]
 crbug.com/241869 [ Debug ] css3/flexbox/multiline-justify-content.html [ Slow ]
 crbug.com/245154 editing/selection/modify_move/move-by-character-brute-force.html [ Slow ]
-crbug.com/246749 http/tests/devtools/extensions/extensions-panel.html [ Slow ]
+crbug.com/246749 http/tests/devtools/extensions/extensions-panel.js [ Slow ]
 
 # This test takes 5+ seconds as intended because it tests connection throttling.
 crbug.com/459377 http/tests/websocket/multiple-connections-throttled.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 74d30c5..3c258a3 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -75,6 +75,7 @@
 crbug.com/769942 virtual/spv175/paint/invalidation/svg/js-late-clipPath-and-object-creation.svg [ Failure ]
 crbug.com/769942 virtual/spv175/paint/invalidation/svg/js-late-clipPath-creation.svg [ Failure ]
 
+crbug.com/771643 virtual/spv175/compositing/overflow/border-radius-composited-subframe.html [ Failure ]
 crbug.com/771643 virtual/spv175/compositing/composited-descendant-grandparent-border-radius-mask.html [ Failure ]
 crbug.com/771643 virtual/spv175/compositing/composited-descendant-requiring-border-radius-mask.html [ Failure ]
 crbug.com/771643 virtual/spv175/compositing/composited-scaled-child-with-border-radius-parent-clip.html [ Failure ]
@@ -347,17 +348,21 @@
 ### Platfom-specific tests cannot be generated automatically
 
 ### virtual/layout Mac color palette/font failures
-crbug.com/704961 [ Mac ] virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-002a.xht [ Failure ]
-crbug.com/704961 [ Mac ] virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-002b.xht [ Failure ]
-crbug.com/704961 [ Mac ] virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-valign-001.xht [ Failure ]
 crbug.com/704961 [ Mac ] virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-inherit-001.xht [ Failure ]
 crbug.com/704961 [ Mac ] virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-027.xht [ Failure ]
 
-### virtual/layout_ng Mac 1px glyph difference.
-crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/basic/015.html [ Failure ]
-crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/026.html [ Failure ]
-crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/028.html [ Failure ]
-crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ]
+### virtual/layout_ng virtual/layout_ng 1px glyph difference.
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/basic/003.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/float/editable-text-overlapping-float.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/float/multiple-float-positioning.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/float/nestedAnonymousBlocks2.html [ Failure ]
+crbug.com/714962 [ Win ] virtual/layout_ng/fast/block/margin-collapse/001.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/006.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/100.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/101.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/102.html [ Failure ]
+crbug.com/714962 [ Win ] virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/001.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/006.html [ Failure ]
 
 ### virtual/layout_ng/external/wpt/css/CSS2/floats
 crbug.com/711704 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-rule3-outside-left-002.xht [ Failure ]
@@ -531,8 +536,6 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-offset-inline-block-strict-line-height.html [ Failure ]
 
 crbug.com/635619 virtual/layout_ng/fast/block/float/independent-align-positioning.html [ Failure ]
-crbug.com/635619 [ Win10 ] virtual/layout_ng/fast/block/float/intruding-float-add-in-sibling-block-on-static-position.html [ Failure ]
-crbug.com/635619 [ Win10 ]  virtual/layout_ng/fast/block/float/intruding-float-add-in-sibling-block-on-static-position2.html [ Failure ]
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/intruding-painted-twice.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/line-break-after-white-space-crash.html [ Pass Crash Timeout ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/logical-bottom-exceeds-layoutunit-max.html [ Failure ]
@@ -540,10 +543,6 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/negative-margin-on-element-avoiding-floats.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/nopaint-after-layer-destruction.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/nopaint-after-layer-destruction2.html [ Failure ]
-crbug.com/635619 [ Win10 ]  virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block.html [ Failure ]
-crbug.com/635619 [ Win10 ]  virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block2.html [ Failure ]
-crbug.com/635619 [ Win10 ]  virtual/layout_ng/fast/block/float/overhanging-float-remove-from-absolute-position-block.html [ Failure ]
-crbug.com/635619 [ Win10 ]  virtual/layout_ng/fast/block/float/overhanging-float-remove-from-absolute-position-block2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-remove-from-fixed-position-block.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-remove-from-fixed-position-block2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overlapping-floats-paint-hittest-order-1.html [ Failure ]
@@ -580,117 +579,196 @@
 # ====== LayoutNG,LayoutNGPaintFragments ======
 
 ### Crash site: ContainerNode.cpp
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-with-empty-inline-children.html [ Crash Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-with-empty-inline-children.html [ Crash Failure ]
 
 ### Crash site: layout_ng_block_flow.cc
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/continuation-positioned-reparenting.html [ Crash ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-offsetLeft-relpos.html [ Crash Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/continuation-positioned-reparenting.html [ Crash ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-offsetLeft-relpos.html [ Crash Failure ]
 
 ### Crash site: PaintController.cpp
-crbug.com/714962 virtual/layout_ng_paint/fast/inline//continuation-outlines-with-layers-2.html [ Crash Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline//continuation-outlines-with-layers-2.html [ Crash Failure ]
 
 ### Image/text failures only on LayoutNGPaintFragments
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/001.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/br-text-decoration.html [ Crash Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/continuation-outlines-with-layers-2.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/emptyInlinesWithinLists.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-box-background-long-image.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-box-background-repeat-x.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-box-background-repeat-y.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-box-background.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-continuation-borders.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-focus-ring.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-offsetLeft-continuation.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-wrap-with-parent-padding.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/justify-emphasis-inline-box.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/outline-offset.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/positioned-object-between-replaced-elements.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/positionedLifetime.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/001.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/br-text-decoration.html [ Crash Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/continuation-outlines-with-layers-2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/emptyInlinesWithinLists.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-box-background-long-image.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-box-background-repeat-x.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-box-background-repeat-y.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-box-background.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-continuation-borders.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-focus-ring.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-offsetLeft-continuation.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-wrap-with-parent-padding.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/justify-emphasis-inline-box.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/outline-offset.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/positioned-object-between-replaced-elements.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/positionedLifetime.html [ Failure ]
 
 ### Minor text/1px failures we can rebaseline
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/002.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/25277-2.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/25277.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-destroy-dirty-lines-crash.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-padding-disables-text-quirk.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-position-top-align.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-text-quirk-bpm.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-width-containing-collapsed-whitespace-and-image-in-float.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/long-wrapped-line.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/nested-top-alignment.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/percentage-margins.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/vertical-align-text-bottom.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/vertical-align-with-fallback-fonts.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/002.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/25277-2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/25277.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-destroy-dirty-lines-crash.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-padding-disables-text-quirk.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-position-top-align.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-text-quirk-bpm.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-width-containing-collapsed-whitespace-and-image-in-float.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/long-wrapped-line.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/nested-top-alignment.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/percentage-margins.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/vertical-align-text-bottom.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/vertical-align-with-fallback-fonts.html [ Failure ]
 
 ### Image/text failures also on LayoutNG
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/absolute-positioned-inline-in-centred-block.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/br-client-rect.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/break-between-nobr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/continuation-outlines-with-layers.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/continuation-outlines.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlines.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-borders-with-bidi-override.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/outline-continuations.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/styledEmptyInlinesWithBRs.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/absolute-positioned-inline-in-centred-block.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/br-client-rect.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/break-between-nobr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/continuation-outlines-with-layers.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/continuation-outlines.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/drawStyledEmptyInlines.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-borders-with-bidi-override.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/outline-continuations.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/inline/styledEmptyInlinesWithBRs.html [ Failure ]
 
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/Kusa-Makura-background-canvas.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/auto-margins-across-boundaries.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/background-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/background-vertical-rl.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/basic-vertical-line.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/block-level-images.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/border-image-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/border-image-vertical-rl.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/border-radius-clipping-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/border-styles-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/border-styles-vertical-rl.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/border-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/borders.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/box-shadow-horizontal-tb-tile-edge.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/box-shadow-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/box-shadow-vertical-rl.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/broken-ideograph-small-caps.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/broken-ideographic-font.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/english-lr-text.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/english-rl-text.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/fallback-orientation.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/fieldsets.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/flipped-blocks-hit-test-line-edges.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/flipped-blocks-text-map-local-to-container.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/japanese-lr-selection.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/japanese-lr-text.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/japanese-rl-selection.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/japanese-rl-text-with-broken-font.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/japanese-rl-text.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/japanese-ruby-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/japanese-ruby-vertical-rl.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/logical-height-after-clear.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/margins.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/orthogonal-inline-block.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/orthogonal-writing-modes-available-width-absolute-crash.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/orthogonal-writing-modes-in-layoutview-with-floats.html [ Crash ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/percentage-height-orthogonal-writing-modes-quirks.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/percentage-height-orthogonal-writing-modes.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/percentage-margins-absolute-replaced.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/percentage-margins-absolute.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/table-hit-test.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/table-percent-width-quirk.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/text-combine-compress.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/text-combine-justify.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/text-combine-line-break.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/text-combine-various-fonts.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/text-orientation-basic.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/vertical-align-table-baseline.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/vertical-baseline-alignment.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/vertical-font-fallback.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/vertical-lr-replaced-selection.html [ Failure ]
-crbug.com/714962 virtual/layout_ng_paint/fast/writing-mode/vertical-rl-replaced-selection.html [ Failure ]
+### virtual/layout_ng/external/wpt/css/CSS2/floats/
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-overflow.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-003-right-overflow.xht [ Failure ]
+
+### virtual/layout_ng/external/wpt/css/CSS2/linebox/
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/linebox/inline-formatting-context-015.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/linebox/vertical-align-baseline-005a.xht [ Failure ]
+
+### virtual/layout_ng/external/wpt/css/CSS2/normal-flow/
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-valign-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-valign-002.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-zorder-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-zorder-002.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-002a.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-002b.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-valign-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-zorder-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-zorder-002.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-105.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-106.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-107.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-104.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-106.xht [ Failure ]
+
+### virtual/layout_ng/external/wpt/css/CSS2/positioning/
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-offset-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-offset-002.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/bottom-offset-003.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-offset-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/left-offset-002.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-032.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-offset-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-offset-002.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/right-offset-003.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-offset-001.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-offset-002.xht [ Failure ]
+crbug.com/714962 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-offset-003.xht [ Failure ]
+
+### virtual/layout_ng/fast/block/basic/
+crbug.com/714962 virtual/layout_ng/fast/block/basic/015.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/basic/016.html [ Failure ]
+
+### virtual/layout_ng/fast/block/float/
+crbug.com/714962 virtual/layout_ng/fast/block/float/002.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/015.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/017.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/021.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/025.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/026.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/027.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/028.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/avoidance-percent-width-strict.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/float-should-dirty-line-even-when-it-doesnt-intersect-it-3.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/float-should-dirty-line-when-adjacent-to-line-breaks-2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/float-should-dirty-line-when-adjacent-to-line-breaks.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/intruding-float-add-in-sibling-block-on-static-position.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/intruding-float-add-in-sibling-block-on-static-position2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/intruding-float-remove-from-sibling-block-on-absolute-position.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/intruding-float-remove-from-sibling-block-on-absolute-position2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/intruding-float-remove-from-sibling-block-on-fixed-position.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/intruding-float-remove-from-sibling-block-on-fixed-position2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/max-width-clear-float-with-overflow-hidden.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/overhanging-after-height-decrease.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/overhanging-float-remove-from-absolute-position-block.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/overhanging-float-remove-from-absolute-position-block2.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/relayout-nested-float-after-line.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/float/trailing-float-with-content.html [ Failure ]
+
+### virtual/layout_ng/fast/block/margin-collapse/
+crbug.com/714962 virtual/layout_ng/fast/block/margin-collapse/044.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/block/margin-collapse/line-beside-float-complex-margin-collapsing.html [ Failure ]
+
+### virtual/layout_ng/fast/writing-mode/
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/Kusa-Makura-background-canvas.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/auto-margins-across-boundaries.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/background-vertical-lr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/background-vertical-rl.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/basic-vertical-line.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/block-level-images.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-image-vertical-lr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-image-vertical-rl.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-radius-clipping-vertical-lr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-styles-vertical-lr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-styles-vertical-rl.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-vertical-lr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/borders.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/box-shadow-horizontal-tb-tile-edge.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/box-shadow-vertical-lr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/box-shadow-vertical-rl.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/broken-ideograph-small-caps.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/broken-ideographic-font.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/english-lr-text.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/english-rl-text.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/fallback-orientation.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/fieldsets.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/flipped-blocks-hit-test-line-edges.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/flipped-blocks-text-map-local-to-container.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-lr-selection.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-lr-text.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-rl-selection.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-rl-text-with-broken-font.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-rl-text.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-ruby-vertical-lr.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-ruby-vertical-rl.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/logical-height-after-clear.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/margins.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/orthogonal-inline-block.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/orthogonal-writing-modes-available-width-absolute-crash.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/orthogonal-writing-modes-in-layoutview-with-floats.html [ Crash ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/percentage-height-orthogonal-writing-modes-quirks.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/percentage-height-orthogonal-writing-modes.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/percentage-margins-absolute-replaced.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/percentage-margins-absolute.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/table-hit-test.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/table-percent-width-quirk.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-compress.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-justify.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-line-break.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-various-fonts.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-orientation-basic.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-align-table-baseline.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-baseline-alignment.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-font-fallback.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-lr-replaced-selection.html [ Failure ]
+crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-rl-replaced-selection.html [ Failure ]
+
+### virtual/layout_ng/overflow/
+crbug.com/714962 virtual/layout_ng/overflow/overflow-transform-perspective.html [ Failure ]
 
 # ====== LayoutNG-only failures until here ======
 
@@ -823,7 +901,7 @@
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/upload-onloadend-event-after-load.html [ Crash ]
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/upload-onloadstart-event.html [ Pass Crash ]
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/upload-onprogress-event.html [ Crash ]
-crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/upload-progress-events.html [ Crash ]
+crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/upload-progress-events.html [ Crash Timeout Pass ]
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/xmlhttprequest-data-url.html [ Crash ]
 
 crbug.com/736308 virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-status.any.html [ Pass Timeout ]
@@ -944,8 +1022,6 @@
 
 crbug.com/761798 [ Mac ] inspector-protocol/emulation/device-emulation-desktop.js [ Failure ]
 
-crbug.com/761881 [ Win7 Debug ] http/tests/devtools/sources/debugger-breakpoints/event-listener-breakpoints.js [ Pass Crash ]
-
 crbug.com/771233 [ Win10 ] http/tests/devtools/audits2/ [ Skip ]
 
 crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-basic.html [ Pass Failure ]
@@ -1041,7 +1117,6 @@
 crbug.com/498539 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Pass Failure ]
 crbug.com/498539 virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Pass Failure ]
 crbug.com/498539 [ Mac ] http/tests/devtools/sources/debugger/live-edit-no-reveal.js [ Crash Pass Timeout Failure ]
-crbug.com/790892 http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Failure Pass ]
 
 crbug.com/498539 [ Win7 ] http/tests/devtools/elements/styles-4/styles-update-from-js.js [ Crash Pass ]
 
@@ -1501,6 +1576,9 @@
 crbug.com/662010 [ Win7 ] http/tests/csspaint/invalidation-background-image.html [ Skip ]
 
 # These tests are skipped as there is no touch support on Mac.
+crbug.com/613672 [ Mac ] fast/events/touch/multi-touch-user-gesture.html [ Skip ]
+crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/touch/multi-touch-user-gesture.html [ Skip ]
+crbug.com/613672 [ Mac ] virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture.html [ Skip ]
 crbug.com/613672 [ Mac ] fast/events/pointerevents/multi-pointer-event-in-slop-region.html [ Skip ]
 crbug.com/613672 [ Mac ] fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Skip ]
 crbug.com/613672 [ Mac ] fast/events/pointerevents/pointer-event-consumed-touchstart-in-slop-region.html [ Skip ]
@@ -1907,9 +1985,27 @@
 crbug.com/711529 http/tests/origin_trials/sample-api-workers.html [ Crash Timeout ]
 crbug.com/711529 http/tests/permissions/test-api-surface.html [ Timeout ]
 crbug.com/711529 http/tests/permissions/test-query.html [ Timeout ]
-crbug.com/711529 http/tests/security/cross-origin-createImageBitmap-structured-clone.html [ Timeout ]
 crbug.com/711529 http/tests/workers/shared-worker-performance-timeline.html [ Timeout ]
 
+# Expected failures during incremental implementation of mojo notification.
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/click-dedicated-worker.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/click-document.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/click-shared-worker.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/click-window-focus-document.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/close-dedicated-worker.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/close-dispatch-asynchronous.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/close-document.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/close-shared-worker.html [ Skip ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/request-permission-granted.html [ Timeout ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-page-notification-fetch-resources.html [ Timeout ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/show-dedicated-worker.html [ Timeout ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/show-document.html [ Timeout ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/show-shared-worker.html [ Timeout ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/update-dedicated-worker.html [ Timeout ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/update-document.html [ Timeout ]
+crbug.com/595685 virtual/mojo-notifications/http/tests/notifications/update-shared-worker.html [ Timeout ]
+
+
 crbug.com/713587 external/wpt/css/css-ui/caret-color-006.html [ Skip ]
 
 # Automatically-added expectations for CSS tests which are temporarily
@@ -1958,7 +2054,7 @@
 # These need to be updated but appear not to be related to that change.
 crbug.com/626703 http/tests/devtools/indexeddb/database-refresh-view.js [ Pass Failure ]
 crbug.com/626703 http/tests/devtools/application-panel/resources-panel-selection-on-reload.js [ Pass Failure ]
-crbug.com/626703 http/tests/devtools/extensions/extensions-sidebar.html [ Pass Failure ]
+crbug.com/626703 http/tests/devtools/extensions/extensions-sidebar.js [ Pass Failure ]
 crbug.com/626703 http/tests/devtools/network/network-columns-visible.js [ Pass Failure ]
 crbug.com/626703 http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js [ Pass Failure ]
 crbug.com/751952 external/wpt/editing/run/forwarddelete.html [ Failure Pass Timeout ]
@@ -1971,6 +2067,18 @@
 crbug.com/751952 virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/budget-api-origin-trial-interfaces.html [ Pass Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Linux Mac ] virtual/outofblink-cors/external/wpt/service-workers/service-worker/clients-get-cross-origin.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-get-cross-origin.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get.https.html [ Timeout ]
+crbug.com/626703 external/wpt/service-workers/service-worker/clients-get-cross-origin.https.html [ Timeout ]
+crbug.com/626703 external/wpt/service-workers/service-worker/clients-get.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-cross-origin.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/outofblink-cors/external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Timeout ]
+crbug.com/626703 external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/outofblink-cors/external/wpt/service-workers/service-worker/clients-get.https.html [ Timeout ]
+crbug.com/626703 [ Linux Mac ] virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.12 ] external/wpt/longtask-timing/longtask-in-sibling-iframe.html [ Timeout ]
 crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1i.html [ Failure ]
 crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1j.html [ Failure ]
@@ -2399,11 +2507,6 @@
 crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ]
 crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ]
 
-crbug.com/655701 http/tests/devtools/bindings/suspendtarget-bindings.js [ Skip ]
-crbug.com/655701 http/tests/devtools/bindings/suspendtarget-navigator.js [ Skip ]
-crbug.com/655701 http/tests/devtools/startup/console-exception-source-url.html [ Skip ]
-crbug.com/655701 http/tests/devtools/startup/console-stack-overflow-source-url.html [ Skip ]
-
 # css-multicol tests failing on initial import from web-platform-tests
 crbug.com/788337 external/wpt/css/css-multicol/multicol-block-no-clip-001.xht [ Failure ]
 crbug.com/788337 external/wpt/css/css-multicol/multicol-block-no-clip-002.xht [ Failure ]
@@ -2636,6 +2739,13 @@
 crbug.com/669473 external/wpt/css/css-ui/outline-015.html [ Failure ]
 crbug.com/669473 external/wpt/css/css-ui/outline-016.html [ Failure ]
 
+# Media queries do not support calc() for internal CSS length values.
+crbug.com/421909 external/wpt/css/mediaqueries/mq-calc-001.html [ Failure ]
+crbug.com/421909 external/wpt/css/mediaqueries/mq-calc-002.html [ Failure ]
+crbug.com/421909 external/wpt/css/mediaqueries/mq-calc-003.html [ Failure ]
+crbug.com/421909 external/wpt/css/mediaqueries/mq-calc-004.html [ Failure ]
+crbug.com/421909 external/wpt/css/mediaqueries/mq-calc-005.html [ Failure ]
+
 crbug.com/670024 external/wpt/webmessaging/broadcastchannel/sandbox.html [ Failure ]
 crbug.com/660384 external/wpt/webmessaging/with-ports/001.html [ Failure ]
 crbug.com/660384 external/wpt/webmessaging/without-ports/001.html [ Failure ]
@@ -3033,7 +3143,7 @@
 crbug.com/732103 [ Mac ] http/tests/shapedetection/shapedetection-cross-origin.html [ Failure Pass Timeout ]
 
 # Sheriff failures 2017-06-14
-crbug.com/733448 http/tests/devtools/extensions/extensions-network.html [ Failure Pass ]
+crbug.com/733448 http/tests/devtools/extensions/extensions-network.js [ Failure Pass ]
 
 crbug.com/737959 http/tests/misc/object-image-load-outlives-gc-without-crashing.html [ Failure Pass ]
 
@@ -3340,7 +3450,7 @@
 crbug.com/757165 [ Win ] fast/spatial-navigation/snav-z-index.html [ Pass Failure Timeout Crash ]
 crbug.com/757165 [ Win ] http/tests/devtools/console/console-filter-test.js [ Skip ]
 crbug.com/757165 [ Win ] http/tests/devtools/console/console-links-in-errors-with-trace.js [ Skip ]
-crbug.com/757165 [ Win ] http/tests/devtools/extensions/extensions-panel.html [ Skip ]
+crbug.com/757165 [ Win ] http/tests/devtools/extensions/extensions-panel.js [ Skip ]
 crbug.com/757165 [ Win ] http/tests/devtools/sources/ui-source-code-metadata.js [ Skip ]
 crbug.com/757165 [ Win ] http/tests/misc/client-hints-accept-meta-preloader.html [ Skip ]
 crbug.com/757165 [ Win ] inspector-protocol/debugger/debugger-evaluate-in-worker-while-pause-in-page.js [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index ffa8aef5..13ece13 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -370,62 +370,74 @@
   {
     "prefix": "layout_ng",
     "base": "fast/block/basic",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "fast/block/margin-collapse",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "fast/block/float",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "external/wpt/css/CSS2/linebox",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "external/wpt/css/CSS2/normal-flow",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "external/wpt/css/CSS2/abspos",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "external/wpt/css/CSS2/positioning",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "external/wpt/css/CSS2/floats",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "external/wpt/css/CSS2/floats-clear",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "layout_ng",
     "base": "overflow",
-    "args": ["--enable-blink-features=LayoutNG"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
-    "prefix": "layout_ng_paint",
+    "prefix": "layout_ng",
     "base": "fast/inline",
-    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
-    "prefix": "layout_ng_paint",
+    "prefix": "layout_ng",
     "base": "fast/writing-mode",
-    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments"]
+    "args": ["--enable-blink-features=LayoutNG,LayoutNGPaintFragments",
+             "--enable-slimming-paint-v175"]
   },
   {
     "prefix": "feature-policy",
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index 78d610d3..d38a6c2 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -108,7 +108,6 @@
 external/wpt/css/css-text/word-break [ Skip ]
 external/wpt/css/css-transitions [ Skip ]
 external/wpt/css/filter-effects [ Skip ]
-external/wpt/css/mediaqueries [ Skip ]
 external/wpt/css/tools [ Skip ]
 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/README [ Skip ]
 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3 [ Skip ]
@@ -298,6 +297,9 @@
 external/wpt/html/semantics/document-metadata/the-style-element/style-error-01.html [ Skip ]
 external/wpt/svg/linking/scripted [ Skip ]
 
+# Temporarily skip this test until crbug.com/793160 is fixed.
+external/wpt/mimesniff/mime-types/parsing.any.js [ Skip ]
+
 # Manual tests that fail as TIMEOUT or NOTRUN. Consider adding wpt_automation.
 external/wpt/FileAPI/BlobURL/test1-manual.html [ Skip ]
 external/wpt/FileAPI/BlobURL/test2-manual.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt
index 138214b..579aa207 100644
--- a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt
+++ b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 223: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 234: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 IDL dictionary unittest
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -76,6 +76,7 @@
 PASS dict.doubleOrStringMember is 3.14
 PASS dict.doubleOrStringSequenceMember is [3.14, "Hello"]
 PASS dict.eventTargetOrNullMember is element1
+PASS dict.internalEnumOrInternalEnumSequenceMember is "foo"
 
 Additional test for union type members
 PASS dict.doubleOrStringMember is "foo"
@@ -83,6 +84,7 @@
 PASS dict.doubleOrStringMember is ""
 PASS dict.doubleOrStringMember is "null"
 PASS dict.doubleOrStringMember is undefined.
+PASS dict.internalEnumOrInternalEnumSequenceMember is ["foo", "bar"]
 
 Test for explicit undefined or null, and missing members
 PASS dict.longMember is undefined.
@@ -107,6 +109,9 @@
 Test for setting invalid enum value
 PASS dictionaryTest.set({enumMember: 'invalid'}) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': The provided value 'invalid' is not a valid enum value of type InternalEnum..
 
+Test for setting invalid enum value in union sequence
+PASS dictionaryTest.set({internalEnumOrInternalEnumSequenceMember: 'invalid'}) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': The provided value 'invalid' is not a valid enum value of type InternalEnum..
+PASS dictionaryTest.set({internalEnumOrInternalEnumSequenceMember: ['invalid']}) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': The provided value 'invalid' is not a valid enum value of type InternalEnumSequence..
 Test for setting invalid object value
 PASS dictionaryTest.set({objectMember: 42}) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': member objectMember is not an object..
 PASS dictionaryTest.set({objectMember: 'invalid'}) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': member objectMember is not an object..
diff --git a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html
index aa295c9a..76cfc00 100644
--- a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html
+++ b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html
@@ -90,6 +90,7 @@
         doubleOrStringMember: 3.14,
         doubleOrStringSequenceMember: [3.14, 'Hello'],
         eventTargetOrNullMember: element1,
+        internalEnumOrInternalEnumSequenceMember: 'foo',
     });
     dict = dictionaryTest.get();
     shouldBe('dict.longMember', '1');
@@ -117,6 +118,7 @@
     shouldBe('dict.doubleOrStringMember', '3.14');
     shouldBe('dict.doubleOrStringSequenceMember', '[3.14, "Hello"]');
     shouldBe('dict.eventTargetOrNullMember', 'element1');
+    shouldBeEqualToString('dict.internalEnumOrInternalEnumSequenceMember', 'foo');
     debug('');
 
     debug('Additional test for union type members');
@@ -145,6 +147,11 @@
     });
     dict = dictionaryTest.get();
     shouldBeUndefined('dict.doubleOrStringMember');
+    dictionaryTest.set({
+        internalEnumOrInternalEnumSequenceMember: ['foo', 'bar'],
+    });
+    dict = dictionaryTest.get();
+    shouldBe('dict.internalEnumOrInternalEnumSequenceMember', '["foo", "bar"]');
 
     debug('');
 
@@ -191,6 +198,10 @@
     shouldThrow("dictionaryTest.set({enumMember: 'invalid'})");
     debug('');
 
+    debug('Test for setting invalid enum value in union sequence');
+    shouldThrow("dictionaryTest.set({internalEnumOrInternalEnumSequenceMember: 'invalid'})");
+    shouldThrow("dictionaryTest.set({internalEnumOrInternalEnumSequenceMember: ['invalid']})");
+
     debug('Test for setting invalid object value');
     shouldThrow("dictionaryTest.set({objectMember: 42})");
     shouldThrow("dictionaryTest.set({objectMember: 'invalid'})");
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-composited-subframe.html b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-composited-subframe.html
new file mode 100644
index 0000000..0f26ba3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-composited-subframe.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+  .bordered {
+    height: 150px;
+    width: 250px;
+    background-color: blue;
+    border-style: solid;
+    border-radius: 25px;
+    border-width: 10px;
+    border-color: gray;
+    margin: 10px 10px;
+  }
+  .shadowed {
+    box-shadow: 0 0 10px 10px;
+  }
+</style>
+<iframe id="iframe1" class="bordered" src="resources/composited-subframe-2.html">
+</iframe>
+<iframe id="iframe2" class="bordered shadowed" src="resources/composited-subframe-2.html">
+</iframe>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/resources/composited-subframe-2.html b/third_party/WebKit/LayoutTests/compositing/overflow/resources/composited-subframe-2.html
new file mode 100644
index 0000000..03cb8c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/resources/composited-subframe-2.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<div id="block" style="background-color: green; position: absolute; top: 5px; bottom: 5px; left: 0; right: 0; will-change: transform">
+</div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/bug782948.html b/third_party/WebKit/LayoutTests/css3/flexbox/bug782948.html
deleted file mode 100644
index 59f4253..0000000
--- a/third_party/WebKit/LayoutTests/css3/flexbox/bug782948.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../resources/check-layout-th.js"></script>
-<style>
-.flexbox {
-  position: relative;
-  display: flex;
-  width: 150px;
-}
-
-table, tr, td {
-  padding: 0;
-  border-spacing: 0;
-}
-
-table {
-  flex: 1;
-  min-width: 0;
-}
-</style>
-
-<body onload="checkLayout('.flexbox')">
-<p>Note that this behavior is all incorrect, but we had a regression that was
-even more incorrect, so this tests that we match our historical behavior.</p>
-<p>You should not see overlapping text.</p>
-<div class="flexbox">
-  <table data-expected-width="200" data-offset-x="0">
-    <tr><td><div style="width: 200px;">Some textual content</div></tr></td>
-  </table>
-  <table data-expected-width="200" data-offset-x="200">
-    <tr><td><div style="width: 200px;">Some textual content</div></tr></td>
-  </table>
-</div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flexitem-expected.txt b/third_party/WebKit/LayoutTests/css3/flexbox/flexitem-expected.txt
deleted file mode 100644
index fda0c7a..0000000
--- a/third_party/WebKit/LayoutTests/css3/flexbox/flexitem-expected.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-This is a testharness.js-based test.
-PASS .flexbox 1
-PASS .flexbox 2
-PASS .flexbox 3
-PASS .flexbox 4
-PASS .flexbox 5
-PASS .flexbox 6
-PASS .flexbox 7
-PASS .flexbox 8
-PASS .flexbox 9
-PASS .flexbox 10
-PASS .flexbox 11
-FAIL .flexbox 12 assert_equals: 
-<div class="flexbox">
-  <!-- FIXME: This table should flex. -->
-  <div data-expected-display="table" data-expected-width="600" style="display: inline-table"></div>
-</div>
-width expected 600 but got 0
-PASS .flexbox 13
-PASS .flexbox 14
-PASS .flexbox 15
-PASS .flexbox 16
-PASS .flexbox 17
-PASS .flexbox 18
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flexitem.html b/third_party/WebKit/LayoutTests/css3/flexbox/flexitem.html
index f996cba..cfc63e0 100644
--- a/third_party/WebKit/LayoutTests/css3/flexbox/flexitem.html
+++ b/third_party/WebKit/LayoutTests/css3/flexbox/flexitem.html
@@ -79,7 +79,6 @@
 </div>
 
 <div class="flexbox">
-  <!-- FIXME: This table should flex. -->
   <div data-expected-display="table" data-expected-width="600" style="display: inline-table"></div>
 </div>
 
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index ed4aeea..546595b 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -26981,6 +26981,90 @@
      {}
     ]
    ],
+   "css/CSS3/text-decoration/line-through-vertical.html": [
+    [
+     "/css/CSS3/text-decoration/line-through-vertical.html",
+     [
+      [
+       "/css/CSS3/text-decoration/line-through-vertical-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-color-recalc.html": [
+    [
+     "/css/CSS3/text-decoration/text-decoration-color-recalc.html",
+     [
+      [
+       "/css/CSS3/text-decoration/text-decoration-color-recalc-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-color.html": [
+    [
+     "/css/CSS3/text-decoration/text-decoration-color.html",
+     [
+      [
+       "/css/CSS3/text-decoration/text-decoration-color-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-line-recalc.html": [
+    [
+     "/css/CSS3/text-decoration/text-decoration-line-recalc.html",
+     [
+      [
+       "/css/CSS3/text-decoration/text-decoration-line-recalc-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-line.html": [
+    [
+     "/css/CSS3/text-decoration/text-decoration-line.html",
+     [
+      [
+       "/css/CSS3/text-decoration/text-decoration-line-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-style-multiple.html": [
+    [
+     "/css/CSS3/text-decoration/text-decoration-style-multiple.html",
+     [
+      [
+       "/css/CSS3/text-decoration/text-decoration-style-multiple-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-style-recalc.html": [
+    [
+     "/css/CSS3/text-decoration/text-decoration-style-recalc.html",
+     [
+      [
+       "/css/CSS3/text-decoration/text-decoration-style-recalc-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-align/distribution-values/space-evenly-001.html": [
     [
      "/css/css-align/distribution-values/space-evenly-001.html",
@@ -37805,6 +37889,30 @@
      {}
     ]
    ],
+   "css/css-flexbox/table-as-item-narrow-content.html": [
+    [
+     "/css/css-flexbox/table-as-item-narrow-content.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square-only.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-flexbox/table-as-item-wide-content.html": [
+    [
+     "/css/css-flexbox/table-as-item-wide-content.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square-only.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-flexbox/ttwf-reftest-flex-align-content-center.html": [
     [
      "/css/css-flexbox/ttwf-reftest-flex-align-content-center.html",
@@ -40793,6 +40901,18 @@
      {}
     ]
    ],
+   "css/css-grid/grid-items/explicitly-sized-grid-item-as-table.html": [
+    [
+     "/css/css-grid/grid-items/explicitly-sized-grid-item-as-table.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square-only.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-grid/grid-items/grid-inline-items-001.html": [
     [
      "/css/css-grid/grid-items/grid-inline-items-001.html",
@@ -76401,6 +76521,306 @@
      {}
     ]
    ],
+   "css/mediaqueries/aspect-ratio-001.html": [
+    [
+     "/css/mediaqueries/aspect-ratio-001.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/aspect-ratio-002.html": [
+    [
+     "/css/mediaqueries/aspect-ratio-002.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/aspect-ratio-003.html": [
+    [
+     "/css/mediaqueries/aspect-ratio-003.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/aspect-ratio-004.html": [
+    [
+     "/css/mediaqueries/aspect-ratio-004.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/device-aspect-ratio-001.html": [
+    [
+     "/css/mediaqueries/device-aspect-ratio-001.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/device-aspect-ratio-002.html": [
+    [
+     "/css/mediaqueries/device-aspect-ratio-002.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/device-aspect-ratio-003.html": [
+    [
+     "/css/mediaqueries/device-aspect-ratio-003.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/device-aspect-ratio-004.html": [
+    [
+     "/css/mediaqueries/device-aspect-ratio-004.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/device-aspect-ratio-005.html": [
+    [
+     "/css/mediaqueries/device-aspect-ratio-005.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/device-aspect-ratio-006.html": [
+    [
+     "/css/mediaqueries/device-aspect-ratio-006.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/min-width-001.xht": [
+    [
+     "/css/mediaqueries/min-width-001.xht",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/min-width-tables-001.html": [
+    [
+     "/css/mediaqueries/min-width-tables-001.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-calc-001.html": [
+    [
+     "/css/mediaqueries/mq-calc-001.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-calc-002.html": [
+    [
+     "/css/mediaqueries/mq-calc-002.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-calc-003.html": [
+    [
+     "/css/mediaqueries/mq-calc-003.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-calc-004.html": [
+    [
+     "/css/mediaqueries/mq-calc-004.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-calc-005.html": [
+    [
+     "/css/mediaqueries/mq-calc-005.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-invalid-media-type-001.html": [
+    [
+     "/css/mediaqueries/mq-invalid-media-type-001.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-invalid-media-type-002.html": [
+    [
+     "/css/mediaqueries/mq-invalid-media-type-002.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-invalid-media-type-003.html": [
+    [
+     "/css/mediaqueries/mq-invalid-media-type-003.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/mq-invalid-media-type-004.html": [
+    [
+     "/css/mediaqueries/mq-invalid-media-type-004.html",
+     [
+      [
+       "/css/reference/ref-filled-green-100px-square.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/relative-units-001.html": [
+    [
+     "/css/mediaqueries/relative-units-001.html",
+     [
+      [
+       "/css/mediaqueries/reference/ref-green-body.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/relative-units-002.html": [
+    [
+     "/css/mediaqueries/relative-units-002.html",
+     [
+      [
+       "/css/mediaqueries/reference/ref-green-body.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/relative-units-003.html": [
+    [
+     "/css/mediaqueries/relative-units-003.html",
+     [
+      [
+       "/css/mediaqueries/reference/ref-green-body.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/mediaqueries/relative-units-004.html": [
+    [
+     "/css/mediaqueries/relative-units-004.html",
+     [
+      [
+       "/css/mediaqueries/reference/ref-green-body.xht",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/motion/offset-path-ray.html": [
     [
      "/css/motion/offset-path-ray.html",
@@ -97397,6 +97817,41 @@
      {}
     ]
    ],
+   "css/CSS3/text-decoration/line-through-vertical-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-color-recalc-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-color-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-line-recalc-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-line-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-style-multiple-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/CSS3/text-decoration/text-decoration-style-recalc-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/README.md": [
     [
      {}
@@ -110952,6 +111407,11 @@
      {}
     ]
    ],
+   "css/css-text-decor/text-decoration-serialization.tentative-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "css/css-text/OWNERS": [
     [
      {}
@@ -114707,11 +115167,6 @@
      {}
     ]
    ],
-   "css/css-typed-om/styleMap-update-function-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "css/css-ui/OWNERS": [
     [
      {}
@@ -120067,6 +120522,26 @@
      {}
     ]
    ],
+   "css/mediaqueries/OWNERS": [
+    [
+     {}
+    ]
+   ],
+   "css/mediaqueries/reference/ref-green-body.xht": [
+    [
+     {}
+    ]
+   ],
+   "css/mediaqueries/support/media_queries_iframe.html": [
+    [
+     {}
+    ]
+   ],
+   "css/mediaqueries/support/min-width-tables-001-iframe.html": [
+    [
+     {}
+    ]
+   ],
    "css/motion/OWNERS": [
     [
      {}
@@ -120152,6 +120627,11 @@
      {}
     ]
    ],
+   "css/reference/ref-filled-green-100px-square-only.html": [
+    [
+     {}
+    ]
+   ],
    "css/reference/ref-filled-green-100px-square.xht": [
     [
      {}
@@ -135247,6 +135727,41 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/bom.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/captions-fast.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/default-styles.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/iso2022jp3.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/metadata-area.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/no-newline-at-eof.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/no-webvtt.vtt": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt": [
     [
      {}
@@ -135267,6 +135782,21 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/utf8.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-file.vtt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-rubbish.vtt": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues-expected.txt": [
     [
      {}
@@ -135282,6 +135812,11 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-helpers.js": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/user-interface/muted-expected.txt": [
     [
      {}
@@ -140022,6 +140557,41 @@
      {}
     ]
    ],
+   "mimesniff/README.md": [
+    [
+     {}
+    ]
+   ],
+   "mimesniff/mime-types/README.md": [
+    [
+     {}
+    ]
+   ],
+   "mimesniff/mime-types/charset-parameter.window-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "mimesniff/mime-types/resources/generated-mime-types.json": [
+    [
+     {}
+    ]
+   ],
+   "mimesniff/mime-types/resources/generated-mime-types.py": [
+    [
+     {}
+    ]
+   ],
+   "mimesniff/mime-types/resources/mime-charset.py": [
+    [
+     {}
+    ]
+   ],
+   "mimesniff/mime-types/resources/mime-types.json": [
+    [
+     {}
+    ]
+   ],
    "mixed-content/OWNERS": [
     [
      {}
@@ -148727,6 +149297,11 @@
      {}
     ]
    ],
+   "webrtc/RTCSctpTransport-maxMessageSize-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "webrtc/RTCStats-helper.js": [
     [
      {}
@@ -156845,6 +157420,12 @@
      {}
     ]
    ],
+   "FileAPI/unicode.html": [
+    [
+     "/FileAPI/unicode.html",
+     {}
+    ]
+   ],
    "FileAPI/url/blob-url-in-sandboxed-iframe.html": [
     [
      "/FileAPI/url/blob-url-in-sandboxed-iframe.html",
@@ -167455,6 +168036,12 @@
      {}
     ]
    ],
+   "css/css-text-decor/text-decoration-serialization.tentative.html": [
+    [
+     "/css/css-text-decor/text-decoration-serialization.tentative.html",
+     {}
+    ]
+   ],
    "css/css-text-decor/text-decoration-skip-ink.html": [
     [
      "/css/css-text-decor/text-decoration-skip-ink.html",
@@ -169771,6 +170358,12 @@
      {}
     ]
    ],
+   "css/mediaqueries/test_media_queries.html": [
+    [
+     "/css/mediaqueries/test_media_queries.html",
+     {}
+    ]
+   ],
    "css/motion/animation/offset-anchor-interpolation.html": [
     [
      "/css/motion/animation/offset-anchor-interpolation.html",
@@ -180601,6 +181194,12 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-active-cues.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-active-cues.html",
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html": [
     [
      "/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html",
@@ -180619,6 +181218,36 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-bom.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-bom.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-header-comment.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-header-comment.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-magic-header.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-magic-header.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-newlines.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-newlines.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-utf8.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-utf8.html",
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/user-interface/muted.html": [
     [
      "/html/semantics/embedded-content/media-elements/user-interface/muted.html",
@@ -188201,6 +188830,12 @@
      {}
     ]
    ],
+   "mimesniff/mime-types/charset-parameter.window.js": [
+    [
+     "/mimesniff/mime-types/charset-parameter.window.html",
+     {}
+    ]
+   ],
    "mixed-content/audio-tag/http-csp/cross-origin-http/top-level/keep-scheme-redirect/optionally-blockable/opt-in-blocks.https.html": [
     [
      "/mixed-content/audio-tag/http-csp/cross-origin-http/top-level/keep-scheme-redirect/optionally-blockable/opt-in-blocks.https.html",
@@ -213893,6 +214528,12 @@
      {}
     ]
    ],
+   "webrtc/RTCSctpTransport-maxMessageSize.html": [
+    [
+     "/webrtc/RTCSctpTransport-maxMessageSize.html",
+     {}
+    ]
+   ],
    "webrtc/RTCTrackEvent-constructor.html": [
     [
      "/webrtc/RTCTrackEvent-constructor.html",
@@ -223152,6 +223793,24 @@
      "/css/css-writing-modes/vertical-alignment-vrl-020.xht",
      {}
     ]
+   ],
+   "css/mediaqueries/media-queries-001.xht": [
+    [
+     "/css/mediaqueries/media-queries-001.xht",
+     {}
+    ]
+   ],
+   "css/mediaqueries/media-queries-002.xht": [
+    [
+     "/css/mediaqueries/media-queries-002.xht",
+     {}
+    ]
+   ],
+   "css/mediaqueries/media-queries-003.xht": [
+    [
+     "/css/mediaqueries/media-queries-003.xht",
+     {}
+    ]
    ]
   }
  },
@@ -223169,7 +223828,7 @@
    "support"
   ],
   "./README.md": [
-   "2a2ab5b7d22a1e65e52bdb2cc2b787b8fa03472b",
+   "e2f2441021aa927518b3208f3619873d7e0fc2d1",
    "support"
   ],
   "./lint.whitelist": [
@@ -223177,7 +223836,7 @@
    "support"
   ],
   "./update-built-tests.sh": [
-   "d0184e7d0761064d0acaae095a50c0b1dfd9c3b6",
+   "e632acfa68de35b71b650db172ffff6d048399a7",
    "support"
   ],
   ".well-known/README.md": [
@@ -227664,6 +228323,10 @@
    "18972f4ed024eb5e1494ac466426ae32b3f5525f",
    "support"
   ],
+  "FileAPI/unicode.html": [
+   "99a52f519e0d12bb9ece822f1480e0b08dca77e3",
+   "testharness"
+  ],
   "FileAPI/url/blob-url-in-sandboxed-iframe.html": [
    "59188b2e679f56d5eb7ea01428ce06ff0068111a",
    "testharness"
@@ -248608,6 +249271,62 @@
    "5a99c5e2169d8f6dd54bb03cff20d86771fb7785",
    "visual"
   ],
+  "css/CSS3/text-decoration/line-through-vertical-ref.html": [
+   "f38d583fbcd41470cefb566d7b18c49758b2ebd2",
+   "support"
+  ],
+  "css/CSS3/text-decoration/line-through-vertical.html": [
+   "a0aee46cedb667c8906acb59254e6be2906947ce",
+   "reftest"
+  ],
+  "css/CSS3/text-decoration/text-decoration-color-recalc-ref.html": [
+   "f97bae89c262da57e45294db7638159114047da3",
+   "support"
+  ],
+  "css/CSS3/text-decoration/text-decoration-color-recalc.html": [
+   "90b474101ea3f862c4b25541de7eceab6f400657",
+   "reftest"
+  ],
+  "css/CSS3/text-decoration/text-decoration-color-ref.html": [
+   "4ef765ae8d80ac3eab177109e9bd5b2b7142880f",
+   "support"
+  ],
+  "css/CSS3/text-decoration/text-decoration-color.html": [
+   "1680790f5a026f1a40a09b956303a5caa1d14db9",
+   "reftest"
+  ],
+  "css/CSS3/text-decoration/text-decoration-line-recalc-ref.html": [
+   "8e8c434546c5f4b6184d935f16b8e1479c39eb11",
+   "support"
+  ],
+  "css/CSS3/text-decoration/text-decoration-line-recalc.html": [
+   "b2ecb8985db8138af208630adc912d489872ac01",
+   "reftest"
+  ],
+  "css/CSS3/text-decoration/text-decoration-line-ref.html": [
+   "3612462ad5a2c5447adf1fc80f6aa2b4ee5cb001",
+   "support"
+  ],
+  "css/CSS3/text-decoration/text-decoration-line.html": [
+   "e75f9dd8329e7a7464ead41db58965f09f9897d3",
+   "reftest"
+  ],
+  "css/CSS3/text-decoration/text-decoration-style-multiple-ref.html": [
+   "e23906652f3abb2123d70b11a7002262ba661f8b",
+   "support"
+  ],
+  "css/CSS3/text-decoration/text-decoration-style-multiple.html": [
+   "dbf494f252e5f98a17734ffad96462f4b665d8c6",
+   "reftest"
+  ],
+  "css/CSS3/text-decoration/text-decoration-style-recalc-ref.html": [
+   "6c6057bb2fd3e94e6141426a9de282120e354bb5",
+   "support"
+  ],
+  "css/CSS3/text-decoration/text-decoration-style-recalc.html": [
+   "6fb5a8423c86ef7c2b4741787c710cce6fbf2a95",
+   "reftest"
+  ],
   "css/README.md": [
    "ab97108074d4c07c5333ff1148fe9a5e425484ca",
    "support"
@@ -256108,6 +256827,14 @@
    "078e1dd6dd61d36cec239ed75d02051f61fe60a5",
    "support"
   ],
+  "css/css-flexbox/table-as-item-narrow-content.html": [
+   "ccee1a24278c3177809a09009c2f15973908fa83",
+   "reftest"
+  ],
+  "css/css-flexbox/table-as-item-wide-content.html": [
+   "b25764f22999464e3e65780f01f4adb784ce56d2",
+   "reftest"
+  ],
   "css/css-flexbox/ttwf-reftest-flex-align-content-center.html": [
    "4e094e9c286479386a39eacfc975b78bef311c63",
    "reftest"
@@ -264692,6 +265419,10 @@
    "7d6dc5106777942ad83e6bc570368af113f32d5f",
    "support"
   ],
+  "css/css-grid/grid-items/explicitly-sized-grid-item-as-table.html": [
+   "2d713db8aa5f79164259a2c7b2b3f6b89f8aeed4",
+   "reftest"
+  ],
   "css/css-grid/grid-items/grid-inline-items-001.html": [
    "026bebd69ed8b67da6b08de73b6f6bf2c1cdae7d",
    "reftest"
@@ -266889,7 +267620,7 @@
    "support"
   ],
   "css/css-paint-api/registered-properties-in-custom-paint.https.html": [
-   "3855c8c28ea3a24bade81080f3f288ef75243dce",
+   "4eee3e45f32779df4464132fa43717a3afc135b2",
    "reftest"
   ],
   "css/css-paint-api/style-background-image-ref.html": [
@@ -269296,6 +270027,14 @@
    "e0d6dbb039133f5aee07cc8dd3d96942727bdec0",
    "manual"
   ],
+  "css/css-text-decor/text-decoration-serialization.tentative-expected.txt": [
+   "02acad04f394b58273aed41657ec8bfdd8cdc210",
+   "support"
+  ],
+  "css/css-text-decor/text-decoration-serialization.tentative.html": [
+   "9266aa2318ae1e023fd287cf3f89e3f62851a8b2",
+   "testharness"
+  ],
   "css/css-text-decor/text-decoration-skip-ink.html": [
    "a633a231d8fd6b5408add5fab972046651889b09",
    "testharness"
@@ -278992,12 +279731,8 @@
    "4bcfaa7a22cbe8fa2ca234583403d26bd520474c",
    "testharness"
   ],
-  "css/css-typed-om/styleMap-update-function-expected.txt": [
-   "52ef226f1fe56bed3b6263b682ee5ac1f5c25cf1",
-   "support"
-  ],
   "css/css-typed-om/styleMap-update-function.html": [
-   "537fbd8e64906ce91b3ed387ede6abdc790750a3",
+   "a1dee75d914b68753af742ce8e6dbbac0397a9a6",
    "testharness"
   ],
   "css/css-ui/OWNERS": [
@@ -289300,6 +290035,138 @@
    "13d88ccf8c2f03db7e1db7f6fc704ba46a06e0e1",
    "support"
   ],
+  "css/mediaqueries/OWNERS": [
+   "495f99b874611fd8f82f2e33bc4b7d930cc60fde",
+   "support"
+  ],
+  "css/mediaqueries/aspect-ratio-001.html": [
+   "2fb6b604885428889a4d21d1e9aa382d86c71b44",
+   "reftest"
+  ],
+  "css/mediaqueries/aspect-ratio-002.html": [
+   "9d08122e33f1b384ed05a4557ec4f25cce27f808",
+   "reftest"
+  ],
+  "css/mediaqueries/aspect-ratio-003.html": [
+   "1de3323fd71eb4622db1a7b695d35cacb707be9a",
+   "reftest"
+  ],
+  "css/mediaqueries/aspect-ratio-004.html": [
+   "6b9a61f1c035b90e7ca288148f414f3b5501e7d2",
+   "reftest"
+  ],
+  "css/mediaqueries/device-aspect-ratio-001.html": [
+   "9cf87e68e7cfe5080d136899bf711564c7e6ef8e",
+   "reftest"
+  ],
+  "css/mediaqueries/device-aspect-ratio-002.html": [
+   "c17c079195105279336f2a1f1fc463b7b25f4b90",
+   "reftest"
+  ],
+  "css/mediaqueries/device-aspect-ratio-003.html": [
+   "14e3bee5eee8fe05a0a35a5c3260342c051614a1",
+   "reftest"
+  ],
+  "css/mediaqueries/device-aspect-ratio-004.html": [
+   "15a3ff10b5afaa5f1808ba831216111a5a878c86",
+   "reftest"
+  ],
+  "css/mediaqueries/device-aspect-ratio-005.html": [
+   "df17fe4a29f3af646427df4498ce8ec8d6fd9e5d",
+   "reftest"
+  ],
+  "css/mediaqueries/device-aspect-ratio-006.html": [
+   "2a8bf8733a10c212bad2d70d98b6dd4d9a5c1cf6",
+   "reftest"
+  ],
+  "css/mediaqueries/media-queries-001.xht": [
+   "f32969ae35116d330076482267984f6ecb4ada25",
+   "visual"
+  ],
+  "css/mediaqueries/media-queries-002.xht": [
+   "d6d7b7a58b76e1b5656b67f04691d6c309495d9c",
+   "visual"
+  ],
+  "css/mediaqueries/media-queries-003.xht": [
+   "71d2f162083daf69436af3d671c8a1c605b24c25",
+   "visual"
+  ],
+  "css/mediaqueries/min-width-001.xht": [
+   "02bc095bf2996d592a8d2f24b0d1f94b9a220e25",
+   "reftest"
+  ],
+  "css/mediaqueries/min-width-tables-001.html": [
+   "1adab8692d2ac6563a669053e2c6522a69473c56",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-calc-001.html": [
+   "db4a5205ff7dffe3cab44eece48abf8aa1177f1f",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-calc-002.html": [
+   "6b77bc8b8fec58a8fa0d246532a86282ee30a81a",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-calc-003.html": [
+   "21320b601e3c91f1d4e8ad72e53861af2c184f18",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-calc-004.html": [
+   "7cad13aa87e8a0d95dc9e35eb7d1dec7930939fb",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-calc-005.html": [
+   "75334bbcf4ef412b9976c59e1efe2177ad62b465",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-invalid-media-type-001.html": [
+   "4b11afa3270c95b0a2736f114627b6f02346805a",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-invalid-media-type-002.html": [
+   "42760d383b11e870f663e11624c5de8d7dfaa1ec",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-invalid-media-type-003.html": [
+   "c3b4ee163014326394f04d35d139bbad85e4e5be",
+   "reftest"
+  ],
+  "css/mediaqueries/mq-invalid-media-type-004.html": [
+   "f3a12b774803a97eff22a35c7a7dee3617fc57d6",
+   "reftest"
+  ],
+  "css/mediaqueries/reference/ref-green-body.xht": [
+   "fc1d68e36664c5947a8efa49fcb9d6432f717f27",
+   "support"
+  ],
+  "css/mediaqueries/relative-units-001.html": [
+   "d5a9cddad47e67048e8ba5d54c3cd0abca93efbe",
+   "reftest"
+  ],
+  "css/mediaqueries/relative-units-002.html": [
+   "1542d3980b34ff68437c734a98dd6452eae51eb0",
+   "reftest"
+  ],
+  "css/mediaqueries/relative-units-003.html": [
+   "12e3a8ff864ad507bd9f7ad860434682b9c23cba",
+   "reftest"
+  ],
+  "css/mediaqueries/relative-units-004.html": [
+   "8cf95c93cfdb225588ffa2218a2f5948a48bb849",
+   "reftest"
+  ],
+  "css/mediaqueries/support/media_queries_iframe.html": [
+   "cd3f0233cc0eaf9295e602ca25aef87fb68df851",
+   "support"
+  ],
+  "css/mediaqueries/support/min-width-tables-001-iframe.html": [
+   "29e7fb34c94e2e8411514d1e71d09aca2ddb642e",
+   "support"
+  ],
+  "css/mediaqueries/test_media_queries.html": [
+   "a602fa95fbd50191362f0373f826b547c890c518",
+   "testharness"
+  ],
   "css/motion/OWNERS": [
    "31ef5b7c36b050e1ce72d5690159a1a62b4ca4c7",
    "support"
@@ -289484,6 +290351,10 @@
    "c5f3a64d83b3f35ac627d9428eeb03668ad2865e",
    "support"
   ],
+  "css/reference/ref-filled-green-100px-square-only.html": [
+   "b78537c1c18697493412ca96bbb6e6d67304e0d7",
+   "support"
+  ],
   "css/reference/ref-filled-green-100px-square.xht": [
    "2f6ee60666fbb65497dc8749683d66ae543bad12",
    "support"
@@ -310745,7 +311616,7 @@
    "testharness"
   ],
   "html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html": [
-   "4ec33f119348303282ffe7c7e2b5538b2b63db87",
+   "1b18c4e70f84197083ab79c2868ec750d4d72168",
    "testharness"
   ],
   "html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src-expected.txt": [
@@ -311284,6 +312155,34 @@
    "3182fae8b2cef5fa28b063f2890836900bb0afbc",
    "testharness"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/bom.vtt": [
+   "2278f4ae0dd2697d522e725241e1a1357017bb6d",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/captions-fast.vtt": [
+   "68ae570e941a5b8993c163a84aca0f758d65ab01",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/default-styles.vtt": [
+   "db041f1a659ab39530144bb68e0ab76d14ca9b90",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/iso2022jp3.vtt": [
+   "e929f8e1755f72ecae96dd40430bc07c5a4a433c",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/metadata-area.vtt": [
+   "778ac955bd2e01b8c6c8fdf540c99f4513390f5e",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/no-newline-at-eof.vtt": [
+   "9cc9424c093198fedb44a2361f704ce299288f71",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/no-webvtt.vtt": [
+   "9d5d51eddc30891a0b25a628fffad6bc19d720de",
+   "support"
+  ],
   "html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt": [
    "f83f36449d6a7e9db28bba9e39dc7a4bf7458927",
    "support"
@@ -311300,6 +312199,18 @@
    "329c3f585e5e89dfc1f44fde85a1d9601e61aef2",
    "support"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/utf8.vtt": [
+   "b15aef44ae1726c362448bc561899c7dc554a767",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-file.vtt": [
+   "943c4ca7d7ba197815ad5732222558e30195b022",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-rubbish.vtt": [
+   "e0522c50ed645cbc7d483d5c410ae5d925ef4b47",
+   "support"
+  ],
   "html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues-expected.txt": [
    "1a3e0aa2f3550c3f6fbb823693781d9ecda911e9",
    "support"
@@ -311308,6 +312219,10 @@
    "9e5b2fa642544c20e04d542d9a8f701d1fa2d165",
    "testharness"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-active-cues.html": [
+   "ee900652dced5cb21fde825760c7ee3450ffba00",
+   "testharness"
+  ],
   "html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html": [
    "f7576ff332cac04a4e2b663b6fdd40aef154b6b5",
    "testharness"
@@ -311328,6 +312243,30 @@
    "e9c8849350512b1247543939ee0e529947e47c2d",
    "testharness"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-helpers.js": [
+   "fe9bae0ff27ade387e103628dd35cd6989129254",
+   "support"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-bom.html": [
+   "26343f09d663d1558881507f89eecc606304b41f",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-header-comment.html": [
+   "3e83c514cb2d18b2238f03e3d85a21f69a60d5c0",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-magic-header.html": [
+   "ef8442f73c4aae5728a8790d6a7dbc075bb09a25",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-newlines.html": [
+   "24d79495469c698e1e0296b503e44a3ee6b5db34",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-utf8.html": [
+   "65241920becf512c35f78b335de90c00af03195d",
+   "testharness"
+  ],
   "html/semantics/embedded-content/media-elements/user-interface/muted-expected.txt": [
    "8fe910fda298e3e5687b02ee3fda079721c2c470",
    "support"
@@ -318953,7 +319892,7 @@
    "support"
   ],
   "interfaces/webrtc-pc.idl": [
-   "67ca220dbed4271371f67a7a7e2a0a9734288ab6",
+   "f3bcd13429b9ab477f7b2422fa4e3ede0bfac88a",
    "support"
   ],
   "interfaces/webusb.idl": [
@@ -320124,6 +321063,38 @@
    "70a1f9e81faa3dbbe320a71a008e4594a29878a8",
    "testharness"
   ],
+  "mimesniff/README.md": [
+   "d0b95d2e21e80df8b65d5bc8217f79d862229ae2",
+   "support"
+  ],
+  "mimesniff/mime-types/README.md": [
+   "f3cd8bf009de6ceb297af8bfdecb851f817fa02d",
+   "support"
+  ],
+  "mimesniff/mime-types/charset-parameter.window-expected.txt": [
+   "d60662501e1ab5f2aedc9f1f53db10248d6ef5ea",
+   "support"
+  ],
+  "mimesniff/mime-types/charset-parameter.window.js": [
+   "baa985ca1fd0aed6644d9d1cef21764cfe826a8b",
+   "testharness"
+  ],
+  "mimesniff/mime-types/resources/generated-mime-types.json": [
+   "e4610646e4a1a417e9fccf868150aed3c5688942",
+   "support"
+  ],
+  "mimesniff/mime-types/resources/generated-mime-types.py": [
+   "1a3357e9bd14bc90cfa45f6844a270b7b3b93db4",
+   "support"
+  ],
+  "mimesniff/mime-types/resources/mime-charset.py": [
+   "635c7dd3564ddec8c7a18c9eb1dae4c01cab75c4",
+   "support"
+  ],
+  "mimesniff/mime-types/resources/mime-types.json": [
+   "e036eb74e27d8f35c411bb4d29d0b0621778e882",
+   "support"
+  ],
   "mixed-content/OWNERS": [
    "92c98aab901060d502f9b9bf70114a31bdab3511",
    "support"
@@ -338157,7 +339128,7 @@
    "testharness"
   ],
   "service-workers/service-worker/fetch-event.https-expected.txt": [
-   "cb15daced23858e660697d552d4e4a583077037a",
+   "ec5a5160dc84699b6f03501f4b2a1d73190c55df",
    "support"
   ],
   "service-workers/service-worker/fetch-event.https.html": [
@@ -338733,7 +339704,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/clients-get-worker.js": [
-   "a48201939523eb5eb0357a8354f7770f44b941a0",
+   "bc72471e16df1507a2cebd4c32f7f995299ebd4e",
    "support"
   ],
   "service-workers/service-worker/resources/clients-matchall-client-types-dedicated-worker.js": [
@@ -338893,7 +339864,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/fetch-event-test-worker.js": [
-   "c8493c87ef1877a9a5dcb1335187233b78d44485",
+   "bba096216d8fbca6d4ddb6b7e9352a095a5e5db8",
    "support"
   ],
   "service-workers/service-worker/resources/fetch-event-within-sw-worker.js": [
@@ -339421,7 +340392,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/test-helpers.sub.js": [
-   "c365bf04ba4d264c2fe955d4a4c78d971bc67dac",
+   "55acaa1edd73a39a834e1a1ee0952f47a03e3c78",
    "support"
   ],
   "service-workers/service-worker/resources/testharness-helpers.js": [
@@ -345168,6 +346139,14 @@
    "b92f3acf5113a475b58892f48406aafc9634be07",
    "testharness"
   ],
+  "webrtc/RTCSctpTransport-maxMessageSize-expected.txt": [
+   "f8df585a06dd087b24e52ddadb716f9860d18e72",
+   "support"
+  ],
+  "webrtc/RTCSctpTransport-maxMessageSize.html": [
+   "95a1a701ff1ea46c782131dcd2012d3b4d5d57d2",
+   "testharness"
+  ],
   "webrtc/RTCStats-helper.js": [
    "19e65b4d27bc350a6678409dc1194085fa93ae2a",
    "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/unicode.html b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/unicode.html
new file mode 100644
index 0000000..ce3e3579
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/unicode.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Blob/Unicode interaction: normalization and encoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+const OMICRON_WITH_OXIA = '\u1F79'; // NFC normalized to U+3CC
+const CONTAINS_UNPAIRED_SURROGATES = 'abc\uDC00def\uD800ghi';
+const REPLACED = 'abc\uFFFDdef\uFFFDghi';
+
+function readBlobAsPromise(blob) {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.readAsText(blob);
+    reader.onload = () => resolve(reader.result);
+    reader.onerror = () => reject(reader.error);
+  });
+}
+
+promise_test(async t => {
+  const blob = new Blob([OMICRON_WITH_OXIA]);
+  const result = await readBlobAsPromise(blob);
+  assert_equals(result, OMICRON_WITH_OXIA, 'String should not be normalized');
+}, 'Test that strings are not NFC normalized by Blob constructor');
+
+promise_test(async t => {
+  const file = new File([OMICRON_WITH_OXIA], 'name');
+  const result = await readBlobAsPromise(file);
+  assert_equals(result, OMICRON_WITH_OXIA, 'String should not be normalized');
+}, 'Test that strings are not NFC normalized by File constructor');
+
+promise_test(async t => {
+  const blob = new Blob([CONTAINS_UNPAIRED_SURROGATES]);
+  const result = await readBlobAsPromise(blob);
+  assert_equals(result, REPLACED, 'Unpaired surrogates should be replaced.');
+}, 'Test that unpaired surrogates are replaced by Blob constructor');
+
+promise_test(async t => {
+  const file = new File([CONTAINS_UNPAIRED_SURROGATES], 'name');
+  const result = await readBlobAsPromise(file);
+  assert_equals(result, REPLACED, 'Unpaired surrogates should be replaced.');
+}, 'Test that unpaired surrogates are replaced by File constructor');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/README.md b/third_party/WebKit/LayoutTests/external/wpt/README.md
index b67e2082a..140208a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/README.md
+++ b/third_party/WebKit/LayoutTests/external/wpt/README.md
@@ -114,7 +114,7 @@
 
 On other platforms, download the firefox archive and common.tests.zip
 archive for your platform from
-[https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/](Mozilla CI)
+[Mozilla CI](https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/).
 
 Then extract `certutil[.exe]` from the tests.zip package and
 `libnss3[.so|.dll|.dynlib]` and put the former on your path and the latter on
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/table-as-item-narrow-content.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/table-as-item-narrow-content.html
new file mode 100644
index 0000000..31cf1125
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/table-as-item-narrow-content.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>CSS Flexbox Test: Flex item as table with narrow content</title>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#layout-algorithm" title="9. Flex Layout Algorithm">
+<meta name="assert" content="A flex item as a table uses the sizing algorithm of the flexbox">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div style="display:flex; width:200px;">
+  <div style="display:table; flex:1 0; background:green;">
+    <div style="width:10px; height:100px;"></div>
+  </div>
+  <div style="flex:1 0;"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/table-as-item-wide-content.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/table-as-item-wide-content.html
new file mode 100644
index 0000000..475adf54
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/table-as-item-wide-content.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>CSS Flexbox Test: Flex item as table with wide content</title>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#layout-algorithm" title="9. Flex Layout Algorithm">
+<meta name="assert" content="A flex item as a table uses the sizing algorithm of the flexbox">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div style="display:flex; width:100px;">
+  <div style="min-width:0; flex:1 1; display:table; background:green;">
+    <div style="width:500px; height:100px;"></div>
+  </div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/grid-items/explicitly-sized-grid-item-as-table.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/grid-items/explicitly-sized-grid-item-as-table.html
new file mode 100644
index 0000000..53a09796
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/grid-items/explicitly-sized-grid-item-as-table.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>CSS Grid Layout Test: Explicitly sized grid item as table with narrow contents</title>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-grid-1/#grid-track-concept" title="3.2. Grid Tracks and Cells">
+<meta name="assert" content="A grid item as a table uses the sizing algorithm of the grid">
+<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html">
+<p>Test passes if there is a filled green square.</p>
+<div style="display:grid; grid-template-columns:50% 50%; width:200px;">
+  <div style="display:table; background:green;">
+    <div style="width:10px; height:100px;"></div>
+  </div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html
index d77a33f..c446347 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html
@@ -44,7 +44,7 @@
             ctx.strokeStyle = 'red';
         if (serializedStrings[1] != "--length-initial: [CSSUnitValue=20px]")
             ctx.strokeStyle = 'blue';
-        if (serializedStrings[2] != "--number: [CSSStyleValue=10]")
+        if (serializedStrings[2] != "--number: [CSSUnitValue=10]")
             ctx.strokeStyle = 'yellow';
         ctx.lineWidth = 4;
         ctx.strokeRect(0, 0, geom.width, geom.height);
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/line-through-vertical-expected.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/line-through-vertical-ref.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/line-through-vertical-expected.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/line-through-vertical-ref.html
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/line-through-vertical.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/line-through-vertical.html
new file mode 100644
index 0000000..0e0eff0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/line-through-vertical.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-decoration-line">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#propdef-writing-mode">
+<link rel="match" href="line-through-vertical-ref.html">
+<style>
+div {
+  writing-mode: vertical-rl;
+  text-decoration: line-through;
+  font-family: Times;
+  font-size: 50px;
+}
+</style>
+<div>
+  <span lang="ja">ABC</span>
+  <span lang="en">ABC</span>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color-recalc-expected.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color-recalc-ref.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color-recalc-expected.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color-recalc-ref.html
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color-recalc.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color-recalc.html
similarity index 72%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color-recalc.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color-recalc.html
index fa1387d..e281f62 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color-recalc.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color-recalc.html
@@ -1,4 +1,6 @@
 <!doctype html>
+<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-decoration-color">
+<link rel="match" href="text-decoration-color-recalc-ref.html">
 <style>
     div {
         font-size: 50px;
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color-expected.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color-ref.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color-expected.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color-ref.html
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color.html
similarity index 93%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color.html
index 40af29c..f275dee1 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-color.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-color.html
@@ -2,6 +2,8 @@
 <html>
     <head>
         <title>CSS Test: CSS3 text-decoration-color</title>
+        <link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-decoration-color">
+        <link rel="match" href="text-decoration-color-ref.html">
         <style>
             .underline {
                 text-decoration: underline;
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line-recalc-expected.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line-recalc-ref.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line-recalc-expected.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line-recalc-ref.html
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line-recalc.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line-recalc.html
similarity index 73%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line-recalc.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line-recalc.html
index 90f47a4..91ec880a 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line-recalc.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line-recalc.html
@@ -1,4 +1,6 @@
 <!doctype html>
+<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-decoration-line">
+<link rel="match" href="text-decoration-line-recalc-ref.html">
 <style>
     div {
         font-size: 50px;
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line-expected.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line-ref.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line-expected.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line-ref.html
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line.html
similarity index 94%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line.html
index 351b952..4c3b51b0 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-line.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-line.html
@@ -1,5 +1,7 @@
 <html>
 <head>
+    <link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-decoration-line">
+    <link rel="match" href="text-decoration-line-ref.html">
     <style>
             .none { text-decoration: none; }
             .underline { text-decoration: underline; }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-serialization.tentative-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-serialization.tentative-expected.txt
new file mode 100644
index 0000000..2fac902
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-serialization.tentative-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL text-decoration shorthand serialization assert_equals: expected "underline" but got "underline solid rgb(0, 0, 0)"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-serialization.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-serialization.tentative.html
new file mode 100644
index 0000000..2f7b2f55
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-serialization.tentative.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<title>text-decoration shorthand serialization</title>
+<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-decoration-property">
+<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block">
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+<div style="text-decoration: underline"></div>
+<script>
+test(() => {
+  const style = getComputedStyle(document.querySelector('div'));
+  // Chrome serializes as "underline solid rgb(0, 0, 0)" while Edge, Firefox an
+  // Safari use "underline", which Chrome used to do as well. The spec should
+  // probably require "underline":
+  // https://github.com/w3c/csswg-drafts/issues/1564
+  assert_equals(style.getPropertyValue("text-decoration"), "underline");
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-multiple-expected.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-multiple-ref.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-multiple-expected.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-multiple-ref.html
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-multiple.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-multiple.html
similarity index 78%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-multiple.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-multiple.html
index 0ee91134..7fef837 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-multiple.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-multiple.html
@@ -1,4 +1,6 @@
 <!doctype html>
+<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-decoration-style">
+<link rel="match" href="text-decoration-style-multiple-ref.html">
 <style>
     div {
         color: #aaa;
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-recalc-expected.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-recalc-ref.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-recalc-expected.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-recalc-ref.html
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-recalc.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-recalc.html
similarity index 73%
rename from third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-recalc.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-recalc.html
index 61fde13..b357976b 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-recalc.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text-decor/text-decoration-style-recalc.html
@@ -1,4 +1,6 @@
 <!doctype html>
+<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-decoration-style">
+<link rel="match" href="text-decoration-style-recalc-ref.html">
 <style>
     div {
         font-size: 50px;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/OWNERS
new file mode 100644
index 0000000..ada3963
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/OWNERS
@@ -0,0 +1,2 @@
+# TEAM: style-dev@chromium.org
+# COMPONENT: Blink>CSS
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-001.html
new file mode 100644
index 0000000..0dad9ea7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-001.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-aspect-ratio - 59/79 ('aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'min' set '59/79' means that the minimum of ratio is '59/79',
+only and only if the value of the 'width' to the value of the 'height' is greater than value of 'min-aspect-ratio', the style sheet will be applied.">
+<style>
+  div {
+    background-color: red;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (min-aspect-ratio: 59/79) {
+    div {
+      background-color: green;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-002.html
new file mode 100644
index 0000000..b4a25eeb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-002.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-aspect-ratio - 0/0 ('aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'min' set '0/0' is invalid that means the style sheet specified by 'min-aspect-ratio' will not be applied.">
+<style>
+  div {
+    background-color: green;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (min-aspect-ratio: 0/0) {
+    div {
+      background-color: red;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-003.html
new file mode 100644
index 0000000..76bebd7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-003.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-aspect-ratio - 1280/720 ('aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'max' set '1280/720' means that the maximum of ratio is '1280/720', only and only if the value of the 'width' to the value of the 'height' is lower than value of 'max-aspect-ratio', the style sheet will be applied.">
+<style>
+  div {
+    background-color: red;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (max-aspect-ratio: 1280/720) {
+    div {
+      background-color: green;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-004.html
new file mode 100644
index 0000000..b4b2e86
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/aspect-ratio-004.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-aspect-ratio - 0/0 ('aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link name="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.6. aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'aspect-ratio' property with prefix 'max' set '0/0' is invalid that means the style sheet specified by 'max-aspect-ratio' will not be applied.">
+<style>
+  div {
+    background-color: green;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (max-aspect-ratio: 0/0) {
+    div {
+      background-color: red;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-001.html
new file mode 100644
index 0000000..60f49b9b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-001.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-device-aspect-ratio - 1281/1024 ('device-aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'max' set '1281/1024' means that the maximum of ratio is '1281/1024', only and only if the device value of 'width' to value of 'height' is lower than value of 'max-device-aspect-ratio', the style sheet will be applied.">
+<style>
+  div {
+    background-color: red;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (max-device-aspect-ratio: 1281/1024) {
+    div {
+      background-color: green;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-002.html
new file mode 100644
index 0000000..52c985aa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-002.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: max-device-aspect-ratio - 0/0 ('device-aspect-ratio' property with prefix 'max')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'max' set '0/0' is invalid that means the style sheet specified by 'max-device-aspect-ratio' will not be applied.">
+<style>
+  div {
+    background-color: green;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (max-device-aspect-ratio: 0/0) {
+    div {
+      background-color: red;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-003.html
new file mode 100644
index 0000000..5d979ba7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-003.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-device-aspect-ratio - 1279/1024 ('device-aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'min' set '1279/1024' means that the minimum of ratio is '1279/1024', only and only if the device value of 'width' to value of 'height' is greater than value of 'min-device-aspect-ratio', the style sheet will be applied.">
+<style>
+  div {
+    background-color: red;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (min-device-aspect-ratio: 1279/1024) {
+    div {
+      background-color: green;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-004.html
new file mode 100644
index 0000000..cd94914
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-004.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: min-device-aspect-ratio - 0/0 ('device-aspect-ratio' property with prefix 'min')</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'device-aspect-ratio' property with prefix 'min' set '0/0' is invalid that means the style sheet specified by 'min-device-aspect-ratio' will not be applied.">
+<style>
+  div {
+    background-color: green;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (min-device-aspect-ratio: 0/0) {
+    div {
+      background-color: red;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-005.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-005.html
new file mode 100644
index 0000000..9190fc4f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-005.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: device-aspect-ratio - 1280/1024 (basic)</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'device-aspect-ratio' property set '1280/1024' means that the ratio is '1280/1024', only and only if the device value of 'width' to value of 'height' is equals with value of 'device-aspect-ratio', the style sheet will be applied.">
+<style>
+  div {
+    background-color: red;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (device-aspect-ratio: 1280/1024) {
+    div {
+      background-color: green;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-006.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-006.html
new file mode 100644
index 0000000..403829d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/device-aspect-ratio-006.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Media Queries Test: device-aspect-ratio - 0/0 (invalid)</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="author" title="Xin Liu" href="mailto:xinx.liu@intel.com">
+<link rel="help" title="4.7. device-aspect-ratio" href="http://www.w3.org/TR/css3-mediaqueries/#device-aspect-ratio">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="flags" content="">
+<meta name="assert" content="The 'device-aspect-ratio' property set '0/0' is invalid that means the style sheet specified by 'device-aspect-ratio' will not be applied.">
+<style>
+  div {
+    background-color: green;
+    height: 100px;
+    width: 100px;
+  }
+  @media screen and (device-aspect-ratio: 0/0) {
+    div {
+      background-color: red;
+    }
+  }
+</style>
+<body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-001.xht
new file mode 100644
index 0000000..ae8736e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-001.xht
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>Basic media queries test</title>
+  <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/>
+  <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/media/queries/001.html"/>
+  <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#media0"/>
+    <style type="text/css"><![CDATA[
+   @media only screen {
+     .a, .b { color: green; }
+   }
+   @media not only screen {
+     .b { color: red; }
+   }
+  ]]></style>
+ </head>
+ <body>
+  <p class="a"> This line should be green. </p>
+  <p class="b"> This line should be green. </p>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-002.xht b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-002.xht
new file mode 100644
index 0000000..756600a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-002.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>The 'width' media feature (for visual devices with desktop viewport widths)</title>
+  <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/>
+  <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/media/queries/002.html"/>
+  <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#width"/>
+    <style type="text/css"><![CDATA[
+   @media screen and (width) { .a { color: green; } }
+   @media screen and (min-width: 1em) { .b { color: green; } }
+   @media screen and (max-width: 1000000em) { .c { color: green; } }
+  ]]></style>
+ </head>
+ <body>
+  <p class="a"> This line should be green. </p>
+  <p class="b"> This line should be green. </p>
+  <p class="c"> This line should be green. </p>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-003.xht b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-003.xht
new file mode 100644
index 0000000..85c285ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/media-queries-003.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>The 'color' media feature (for color devices with bit depth less than 4096 bits per pixel)</title>
+  <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/>
+  <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/media/queries/003.html"/>
+  <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#color"/>
+    <style type="text/css"><![CDATA[
+   @media screen and (color) { .a { color: green; } }
+   @media screen and (min-color: 1) { .b { color: green; } }
+   @media screen and (max-color: 4096) { .c { color: green; } }
+  ]]></style>
+ </head>
+ <body>
+  <p class="a"> This line should be green. </p>
+  <p class="b"> This line should be green. </p>
+  <p class="c"> This line should be green. </p>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/min-width-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/min-width-001.xht
new file mode 100644
index 0000000..649273c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/min-width-001.xht
@@ -0,0 +1,30 @@
+<!DOCTYPE html SYSTEM "about:legacy-compat">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta charset="utf-8" />
+    <title>CSS Media Queries Test: min-width length value approximation</title>
+    <link rel="author" title="Chris Rebert" href="http://chrisrebert.com" />
+    <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#width" />
+    <link rel="help" href="http://www.w3.org/TR/mediaqueries-4/#width" />
+    <link rel="help" href="http://www.w3.org/TR/css3-values/#length-value" />
+    <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+    <meta name="flags" content="" />
+    <meta name="assert" content="min-width length values that are too large to be supported must be clamped, rounded to infinity, or approximated, but not overflowed to a small or negative value." />
+    <style>
+div {
+    width: 100px;
+    height: 100px;
+    background-color: green;
+}
+@media (min-width: 9999999999px) {
+    div {
+        background-color: red;
+    }
+}
+    </style>
+</head>
+<body>
+    <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+    <div></div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/min-width-tables-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/min-width-tables-001.html
new file mode 100644
index 0000000..dc430cc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/min-width-tables-001.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+    <meta charset="utf-8">
+    <title>CSS Test: Table Layout and Viewport Resizing</title>
+    <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+    <link rel="help" href="https://drafts.csswg.org/css2/tables.html#auto-table-layout">
+    <link rel="help" href="https://drafts.csswg.org/mediaqueries-3/#width">
+    <link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#width">
+    <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+    <meta name="flags" content="dom">
+    <meta name="assert" content="Resizing a page which toggles the `display` of elements between `block` and `table-cell` based on the viewport width should not cause unnecessary wrapping of the table.">
+    <style>
+iframe {
+    border: 0;
+}
+    </style>
+</head>
+<body>
+    <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+    <iframe id="toy" width="100" height="300" src="support/min-width-tables-001-iframe.html"></iframe>
+    <!-- See min-width-tables-001-iframe.html for the derivation of the 100px value -->
+    <!-- We use 300px height so the incorrect stacking is visible in failure cases -->
+    <!-- This test is not about iframes specifically. It's just that resizing an iframe is more reliable than resizing the window, given browser security restrictions. -->
+    <script>
+    window.addEventListener('load', function () {
+        var PAINT_MS = 250;/* Assume the browser takes about this long to layout/paint this whole page */
+        var iframe = document.getElementById('toy');
+        window.setTimeout(function () {
+            iframe.width = 64;/* <100px ; toggle media query off */
+            window.setTimeout(function () {
+                iframe.width = 100;/* >=100px ; toggle media query on; back to initial width */
+                // Take the reftest screenshot after the last relayout/repaint finishes
+                window.setTimeout(function () {
+                    document.documentElement.className = '';
+                }, PAINT_MS);
+            }, PAINT_MS);
+        }, PAINT_MS);
+    }, false);
+    </script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-001.html
new file mode 100644
index 0000000..9a39663
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-001.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: support for calc in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="calc can be used in Media Queries">
+		<meta name="flags" content="">
+		<style>
+			div {
+				width: 100px;
+				height: 100px;
+				background-color: red;
+			}
+			@media (min-width: calc(1px - 1px)){
+				div { background-color: green; }
+			}
+	</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-002.html
new file mode 100644
index 0000000..f6f2fc1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-002.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: evaluation of em in calc in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+		<link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="The size in pixels of the 'em' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+		<meta name="flags" content="">
+		<style>
+			:root { font-size: 30000px; }
+			p { font-size: 16px; }
+			div {
+				width: 100px;
+				height: 100px;
+				background-color: red;
+			}
+			@media (min-width: calc(1em)){
+				div { background-color: green; }
+			}
+		</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+		<script>
+		  document.body.offsetTop;
+		</script>
+		<style>
+			@media (min-width: calc(1em)){
+				div { background-color: green; }
+			}
+		</style>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-003.html
new file mode 100644
index 0000000..cadc448
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-003.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: evaluation of ex in calc in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+		<link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="The size in pixels of the 'ex' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+		<meta name="flags" content="">
+		<style>
+			:root { font-size: 30000px; }
+			p { font-size: 16px; }
+			div {
+				width: 100px;
+				height: 100px;
+				background-color: red;
+			}
+			@media (min-width: calc(1ex)){
+				div { background-color: green; }
+			}
+		</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+		<script>
+		  document.body.offsetTop;
+		</script>
+		<style>
+			@media (min-width: calc(1ex)){
+				div { background-color: green; }
+			}
+		</style>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-004.html
new file mode 100644
index 0000000..63190347
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-004.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: evaluation of ch in calc in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+		<link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="The size in pixels of the 'ch' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+		<meta name="flags" content="">
+		<style>
+			:root { font-size: 30000px; }
+			p { font-size: 16px; }
+			div {
+				width: 100px;
+				height: 100px;
+				background-color: red;
+			}
+	</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+		<script>
+		  document.body.offsetTop;
+		</script>
+		<style>
+			@media (min-width: calc(1ch)){
+				div { background-color: green; }
+			}
+		</style>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-005.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-005.html
new file mode 100644
index 0000000..df7409b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-calc-005.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: evaluation of rem in calc in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+		<link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="The size in pixels of the 'rem' unit used in calc inside a media query does not depend on declarations and use the initial value.">
+		<meta name="flags" content="">
+		<style>
+			:root { font-size: 30000px; }
+			p { font-size: 16px; }
+			div {
+				width: 100px;
+				height: 100px;
+				background-color: red;
+			}
+	</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+		<script>
+		  document.body.offsetTop;
+		</script>
+		<style>
+			@media (min-width: calc(1rem)){
+				div { background-color: green; }
+			}
+		</style>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-001.html
new file mode 100644
index 0000000..24ebd9f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-001.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: syntax error handling in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="'and' is an invalid media type">
+		<meta name="flags" content="invalid">
+		<style>
+			div {
+				width: 100px;
+				height: 100px;
+			}
+			@media all {
+				div { background-color: green; }
+			}
+			@media not and {
+				div { background-color: red; }
+			}
+	</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-002.html
new file mode 100644
index 0000000..71f597e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-002.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: syntax error handling in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="'or' is an invalid media type">
+		<meta name="flags" content="invalid">
+		<style>
+			div {
+				width: 100px;
+				height: 100px;
+			}
+			@media all {
+				div { background-color: green; }
+			}
+			@media not or {
+				div { background-color: red; }
+			}
+	</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-003.html
new file mode 100644
index 0000000..b12bd758
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-003.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: syntax error handling in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="'not' is an invalid media type">
+		<meta name="flags" content="invalid">
+		<style>
+			div {
+				width: 100px;
+				height: 100px;
+			}
+			@media all {
+				div { background-color: green; }
+			}
+			@media not not {
+				div { background-color: red; }
+			}
+	</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-004.html
new file mode 100644
index 0000000..d039281c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/mq-invalid-media-type-004.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+	<head>
+		<title>Test: syntax error handling in Media Queries</title>
+		<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+		<link rel="help" href="https://drafts.csswg.org/mediaqueries4/#error-handling">
+		<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+		<meta name="assert" content="'only' is an invalid media type">
+		<meta name="flags" content="invalid">
+		<style>
+			div {
+				width: 100px;
+				height: 100px;
+			}
+			@media all {
+				div { background-color: green; }
+			}
+			@media not only {
+				div { background-color: red; }
+			}
+	</style>
+	</head>
+	<body>
+		<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+		<div></div>
+	</body>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/reference/ref-green-body.xht b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/reference/ref-green-body.xht
new file mode 100644
index 0000000..f79255d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/reference/ref-green-body.xht
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>CSS Reftest Reference</title>
+<link rel="author" title="Chris Rebert" href="http://chrisrebert.com" />
+<style type="text/css">
+body {
+  background: green;
+}
+p {
+  font-size: 24px;
+}
+</style>
+</head>
+<body>
+<p>This should have a green background.</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-001.html
new file mode 100644
index 0000000..fac94d7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-001.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Test: Font-relative length units (rem) in width media queries</title>
+  <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+  <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+  <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+  <link rel="match" href="reference/ref-green-body.xht">
+  <meta name="flags" content="">
+  <meta name="assert" content="Font-relative length units (such as 'rem') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+  <style>
+:root {
+  font-size: 100000px;/* ~87ft */
+}
+body {
+  background: red;
+}
+p {
+  font-size: 24px;
+}
+  </style>
+</head>
+<body>
+  <p>This should have a green background.</p>
+  <script>
+    document.body.offsetTop;
+  </script>
+  <style>
+    @media (min-width: 1rem) {
+      body {
+        background: green;
+      }
+    }
+  </style>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-002.html
new file mode 100644
index 0000000..310e18f5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-002.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Test: Font-relative length units (em) in width media queries</title>
+  <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+  <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+  <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+  <link rel="match" href="reference/ref-green-body.xht">
+  <meta name="flags" content="">
+  <meta name="assert" content="Font-relative length units (such as 'em') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+  <style>
+:root {
+  font-size: 100000px;/* ~87ft */
+}
+body {
+  background: red;
+}
+p {
+  font-size: 24px;
+}
+  </style>
+</head>
+<body>
+  <p>This should have a green background.</p>
+  <script>
+    document.body.offsetTop;
+  </script>
+  <style>
+    @media (min-width: 1em) {
+      body {
+        background: green;
+      }
+    }
+  </style>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-003.html
new file mode 100644
index 0000000..461db324
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-003.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Test: Font-relative length units (ex) in width media queries</title>
+  <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+  <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+  <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+  <link rel="match" href="reference/ref-green-body.xht">
+  <meta name="flags" content="">
+  <meta name="assert" content="Font-relative length units (such as 'ex') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+  <style>
+:root {
+  font-size: 100000px;/* ~87ft */
+}
+body {
+  background: red;
+}
+p {
+  font-size: 24px;
+}
+  </style>
+</head>
+<body>
+  <p>This should have a green background.</p>
+  <script>
+    document.body.offsetTop;
+  </script>
+  <style>
+    @media (min-width: 1ex) {
+      body {
+        background: green;
+      }
+    }
+  </style>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-004.html
new file mode 100644
index 0000000..b0f3765
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/relative-units-004.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Test: Font-relative length units (ch) in width media queries</title>
+  <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+  <link rel="help" href="https://www.w3.org/TR/css3-mediaqueries/#units">
+  <link rel="help" href="https://www.w3.org/TR/mediaqueries-4/#units">
+  <link rel="match" href="reference/ref-green-body.xht">
+  <meta name="flags" content="">
+  <meta name="assert" content="Font-relative length units (such as 'ch') in media queries should be calculated based on the initial value of 'font-size', not based on author style declarations, such as: html { font-size: 200%; }">
+  <style>
+:root {
+  font-size: 100000px;/* ~87ft */
+}
+body {
+  background: red;
+}
+p {
+  font-size: 24px;
+}
+  </style>
+</head>
+<body>
+  <p>This should have a green background.</p>
+  <script>
+    document.body.offsetTop;
+  </script>
+  <style>
+    @media (min-width: 1ch) {
+      body {
+        background: green;
+      }
+    }
+  </style>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/media/w3c/resources/media_queries_iframe.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/support/media_queries_iframe.html
similarity index 75%
rename from third_party/WebKit/LayoutTests/fast/media/w3c/resources/media_queries_iframe.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/support/media_queries_iframe.html
index 553f542..890eb6c 100644
--- a/third_party/WebKit/LayoutTests/fast/media/w3c/resources/media_queries_iframe.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/support/media_queries_iframe.html
@@ -4,8 +4,7 @@
 <head>
 	<title>Media Queries Test inner frame</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-	<link rel="author" title="L. David Baron" href="http://dbaron.org/">
-	<link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/">
+	<link rel="author" title="L. David Baron" href="https://dbaron.org/">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css" id="style" media="all">
 	body { text-decoration: underline; }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/support/min-width-tables-001-iframe.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/support/min-width-tables-001-iframe.html
new file mode 100644
index 0000000..794c047
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/support/min-width-tables-001-iframe.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>iframe containing the meat of the test</title>
+    <style>
+body {
+    margin: 0;
+    overflow: hidden;
+}
+/* green div that should cover the red divs */
+#green {
+    position: absolute;
+    left: 0;
+    top: 0;
+    background-color: green;
+    width: 100%;
+    height: 600px;
+}
+.spacer {
+    height: 98px;
+    width: 20px;
+}
+.item {
+    background-color: red;
+    display: block;/* property under test */
+    /* border to aid understanding of boundaries between items */
+    border-style: solid;
+    border-width: 1px;
+    border-color: red;/* Note: if you're trying to debug this, use a different color here */
+}
+/* 100px = 10*(1 + 8 + 1) */
+@media (min-width: 100px) {
+    #green {
+        width: 100px;
+        height: 100px;/* = 1 + 98 + 1 */
+    }
+    .item {
+        display: table-cell;/* property and value under test */
+    }
+}
+    </style>
+</head>
+<body>
+    <div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+        <div class="item"><div class="spacer"></div></div>
+    </div>
+    <div id="green"></div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/media/w3c/test_media_queries.html b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/test_media_queries.html
similarity index 98%
rename from third_party/WebKit/LayoutTests/fast/media/w3c/test_media_queries.html
rename to third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/test_media_queries.html
index 0535b05b..e5dbff4 100644
--- a/third_party/WebKit/LayoutTests/fast/media/w3c/test_media_queries.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/mediaqueries/test_media_queries.html
@@ -2,12 +2,12 @@
 <html>
 <head>
   <title>Media Queries Self-Contained Test Suite</title>
-  <link rel="author" title="L. David Baron" href="http://dbaron.org/">
+  <link rel="author" title="L. David Baron" href="https://dbaron.org/">
   <link rel="author" title="Anne van Kesteren" href="http://annevankesteren.nl/">
   <link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
   <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/">
-  <script type="text/javascript" src="../../../resources/testharness.js"></script>
-  <script type="text/javascript" src="../../../resources/testharnessreport.js"></script>
+  <script type="text/javascript" src="/resources/testharness.js"></script>
+  <script type="text/javascript" src="/resources/testharnessreport.js"></script>
 <script id="metadata_cache">/*
 {
   "subtest_1": { "assert": "query (orientation) should be parseable" },
@@ -378,7 +378,7 @@
 </head>
 <body onload="run()">
 <div id=log></div>
-<iframe id="subdoc" src="resources/media_queries_iframe.html"></iframe>
+<iframe id="subdoc" src="support/media_queries_iframe.html"></iframe>
 <div id="content" style="display: none"></div>
 
 <script type="text/javascript">
@@ -394,7 +394,7 @@
 
     function query_applies(q) {
       style.setAttribute("media", q);
-      return body_cs.getPropertyValue("text-decoration") == "underline solid rgb(0, 0, 0)";
+      return body_cs.getPropertyValue("text-decoration-line") == "underline";
     }
 
     function should_apply(q) {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/reference/ref-filled-green-100px-square-only.html b/third_party/WebKit/LayoutTests/external/wpt/css/reference/ref-filled-green-100px-square-only.html
new file mode 100644
index 0000000..82fcaa3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/reference/ref-filled-green-100px-square-only.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
+<p>Test passes if there is a filled green square.</p>
+<div style="width:100px; height:100px; background:green;"></div>
diff --git a/third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc002-bom.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/bom.vtt
similarity index 100%
rename from third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc002-bom.vtt
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/bom.vtt
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/default-styles.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/default-styles.vtt
new file mode 100644
index 0000000..d890ca3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/default-styles.vtt
@@ -0,0 +1,19 @@
+WEBVTT
+
+COMMENT-->
+this is a comment, that will parse as part of the header;
+the STYLE and DEFAULTS below are parsed as invalid cues
+
+STYLE-->
+::cue(.narration) { color: blue; }
+
+DEFAULTS -->
+line:-1 align:middle size:50%
+
+1
+00:00:00.000 --> 00:00:30.500
+Bear is Coming!!!!!
+
+2
+00:00:31.000 --> 00:20:00.500
+I said Bear is coming!!!!
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc001-iso2022jp3.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/iso2022jp3.vtt
similarity index 100%
rename from third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc001-iso2022jp3.vtt
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/iso2022jp3.vtt
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/metadata-area.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/metadata-area.vtt
new file mode 100644
index 0000000..255298ae
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/metadata-area.vtt
@@ -0,0 +1,14 @@
+WEBVTT
+This is where metadata would go and these lines should be skipped.
+author = silviapf@google.com
+COMMENT-->
+this is a comment, that will parse as part of the header;
+the STYLE and DEFAULTS below are parsed as invalid cues
+
+1
+00:00:00.000 --> 00:00:30.500
+Bear is Coming!!!!!
+
+2
+00:00:31.000 --> 00:20:00.500
+I said Bear is coming!!!!
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc003-no-newline-at-eof.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/no-newline-at-eof.vtt
similarity index 100%
rename from third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc003-no-newline-at-eof.vtt
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/no-newline-at-eof.vtt
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/no-webvtt.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/no-webvtt.vtt
new file mode 100644
index 0000000..12053b2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/no-webvtt.vtt
@@ -0,0 +1,10 @@
+AWEBVTT FILE
+A file with wrong file header should not be recognized as a webvtt file.
+
+1
+00:00:00.000 --> 00:00:30.500
+Bear is Coming!!!!!
+
+2
+00:00:31.000 --> 00:20:00.500
+I said Bear is coming!!!!
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc001-utf8.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/utf8.vtt
similarity index 100%
rename from third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc001-utf8.vtt
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/utf8.vtt
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-file.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-file.vtt
new file mode 100644
index 0000000..0c1a5fb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-file.vtt
@@ -0,0 +1,9 @@
+WEBVTT FILE
+
+1
+00:00:00.000 --> 00:00:30.500
+Bear is Coming!!!!!
+
+2
+00:00:31.000 --> 00:20:00.500
+I said Bear is coming!!!!
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc004-webvtt-rubbish.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-rubbish.vtt
similarity index 100%
rename from third_party/WebKit/LayoutTests/media/track/captions-webvtt/tc004-webvtt-rubbish.vtt
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-rubbish.vtt
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-helpers.js b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-helpers.js
new file mode 100644
index 0000000..12e8aff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-helpers.js
@@ -0,0 +1,73 @@
+function enableAllTextTracks(textTracks) {
+    for (var i = 0; i < textTracks.length; i++) {
+        var track = textTracks[i];
+        if (track.mode == "disabled")
+            track.mode = "hidden";
+    }
+}
+
+function assert_cues_equal(cues, expected) {
+    assert_equals(cues.length, expected.length);
+    for (var i = 0; i < cues.length; i++) {
+        assert_equals(cues[i].id, expected[i].id);
+        assert_equals(cues[i].startTime, expected[i].startTime);
+        assert_equals(cues[i].endTime, expected[i].endTime);
+        assert_equals(cues[i].text, expected[i].text);
+    }
+}
+
+function assert_cues_match(cues, expected) {
+    assert_equals(cues.length, expected.length);
+    for (var i = 0; i < cues.length; i++) {
+        var cue = cues[i];
+        var expectedItem = expected[i];
+        for (var property of Object.getOwnPropertyNames(expectedItem))
+            assert_equals(cue[property], expectedItem[property]);
+    }
+}
+
+function check_cues_from_track(src, func) {
+    async_test(function(t) {
+        var video = document.createElement("video");
+        var trackElement = document.createElement("track");
+        trackElement.src = src;
+        trackElement.default = true;
+        video.appendChild(trackElement);
+
+        trackElement.onload = t.step_func_done(function() {
+            func(trackElement.track);
+        });
+    }, "Check cues from " + src);
+}
+
+function assert_cue_fragment(cue, children) {
+    var fragment = createFragment(children);
+    assert_true(fragment.isEqualNode(cue.getCueAsHTML()));
+}
+
+function assert_cue_fragment_as_textcontent(cue, children) {
+    var fragment = createFragment(children);
+    assert_equals(cue.getCueAsHTML().textContent, fragment.textContent);
+}
+
+function createFragment(children) {
+    var fragment = document.createDocumentFragment();
+    cloneChildrenToFragment(fragment, children);
+    return fragment;
+}
+
+function cloneChildrenToFragment(root, children) {
+    for (var child of children) {
+        var childElement;
+        if (child.type == "text") {
+            childElement = document.createTextNode(child.value);
+        } else {
+            childElement = document.createElement(child.type);
+            var styles = child.style || {};
+            for (var attr of Object.getOwnPropertyNames(styles))
+                childElement[attr] = styles[attr];
+            cloneChildrenToFragment(childElement, child.value);
+        }
+        root.appendChild(childElement);
+    }
+}
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-bom.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-bom.html
new file mode 100644
index 0000000..c138f96
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-bom.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed</title>
+<script src="track-helpers.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track src="resources/bom.vtt" default>
+    <script>
+        async_test(function(t) {
+            var track = document.querySelector("track");
+
+            track.onload = t.step_func_done(function() {
+                var expected = [
+                    {
+                        id : "1",
+                        startTime : 0,
+                        endTime : 30.5,
+                        text : "Bear is Coming!!!!!"
+                    },
+                    {
+                        id : "2",
+                        startTime : 31,
+                        endTime : 1200.5,
+                        text : "I said Bear is coming!!!!"
+                    }
+                ];
+
+                var cues = track.track.cues;
+                assert_equals(cues.length, 2);
+                assert_cues_equal(cues, expected);
+            });
+        });
+    </script>
+</video>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc005-header-comment.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-header-comment.html
similarity index 71%
rename from third_party/WebKit/LayoutTests/media/track/track-webvtt-tc005-header-comment.html
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-header-comment.html
index c4f4a5c..f9b35576f 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc005-header-comment.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-header-comment.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
-<title>Tests that the optional comment area under the "WEBVTT" file header is properly ignored.  Also, default settings and styling are currently ignored (treated as faulty cues).</title>
+<title>Optional comment area under the "WEBVTT" file header is properly ignored and also, default settings and styling are currently ignored (treated as faulty cues)</title>
 <script src="track-helpers.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <video>
-    <track src="captions-webvtt/tc005-default-styles.vtt">
-    <track src="captions-webvtt/tc005-metadata-area.vtt">
+    <track src="resources/default-styles.vtt">
+    <track src="resources/metadata-area.vtt">
 </video>
 <script>
 async_test(function(t) {
     var video = document.querySelector("video");
-    
+
     var trackElements = document.querySelectorAll("track");
     for (var i = 0; i < video.textTracks.length; i++)
         trackElements[i].onload = t.step_func(trackLoaded);
diff --git a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc004-magic-header.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-magic-header.html
similarity index 75%
rename from third_party/WebKit/LayoutTests/media/track/track-webvtt-tc004-magic-header.html
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-magic-header.html
index 6247ff7..ff4637a 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc004-magic-header.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-magic-header.html
@@ -1,22 +1,22 @@
 <!DOCTYPE html>
-<title>Tests that the magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file.</title>
+<title>Magic file header "WEBVTT" leads to the file properly recognized as a WebVTT file</title>
 <script src="track-helpers.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <video>
-    <track src="captions-webvtt/tc004-webvtt-file.vtt">
-    <track src="captions-webvtt/tc004-webvtt-rubbish.vtt">
-    <track src="captions-webvtt/tc004-no-webvtt.vtt">
+    <track src="resources/webvtt-file.vtt">
+    <track src="resources/webvtt-rubbish.vtt">
+    <track src="resources/no-webvtt.vtt">
 </video>
 <script>
 async_test(function(t) {
     var video = document.querySelector("video");
-    
+
     var trackElements = document.querySelectorAll("track");
     trackElements[0].onload = t.step_func(trackLoaded);
     trackElements[1].onload = t.step_func(trackLoaded);
     trackElements[2].onerror = t.step_func(trackLoaded);
-    
+
     enableAllTextTracks(video.textTracks);
 
     var numberOfTracksLoaded = 0;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-newlines.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-newlines.html
new file mode 100644
index 0000000..4da7e6b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-newlines.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>A cue with no newline at eof is parsed properly</title>
+<script src="track-helpers.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track src="resources/no-newline-at-eof.vtt" default>
+    <script>
+        async_test(function(t) {
+            var track = document.querySelector("track");
+
+            track.onload = t.step_func_done(function() {
+                var expected = [
+                    {
+                        id : "1",
+                        startTime : 0,
+                        endTime : 30.5,
+                        text : "Bear is Coming!!!!!"
+                    }
+                ];
+
+                assert_cues_equal(track.track.cues, expected);
+            });
+        });
+    </script>
+</video>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc001-utf8.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-utf8.html
similarity index 75%
rename from third_party/WebKit/LayoutTests/media/track/track-webvtt-tc001-utf8.html
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-utf8.html
index 11bf221..eb44c85b 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc001-utf8.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-utf8.html
@@ -1,17 +1,17 @@
 <!DOCTYPE html>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>Tests that UTF-8 encoded characters are recognized properly and that different encodings (iconv) are not recognized as a WebVTT file (we do allow it, it just looks ugly).</title>
-<video>
-    <track src="captions-webvtt/tc001-utf8.vtt">
-    <track src="captions-webvtt/tc001-iso2022jp3.vtt">
-</video>
+<title>UTF-8 encoded characters are recognized properly and different encodings (iconv) are not recognized as a WebVTT file</title>
 <script src="track-helpers.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track src="resources/utf8.vtt">
+    <track src="resources/iso2022jp3.vtt">
+</video>
 <script>
 async_test(function(t) {
     var video = document.querySelector("video");
-    
+
     var trackElements = document.querySelectorAll("track");
     for (var i = 0; i < video.textTracks.length; i++)
         trackElements[i].onload = t.step_func(trackLoaded);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/webrtc-pc.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/webrtc-pc.idl
index ae20055..d33562b6 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/webrtc-pc.idl
+++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/webrtc-pc.idl
@@ -507,7 +507,7 @@
 
 interface RTCSctpTransport {
     readonly attribute RTCDtlsTransport transport;
-    readonly attribute unsigned long    maxMessageSize;
+    readonly attribute unrestricted double maxMessageSize;
 };
 
 interface RTCDataChannel : EventTarget {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/README.md b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/README.md
new file mode 100644
index 0000000..8083431
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/README.md
@@ -0,0 +1 @@
+Tests for the [MIME Sniffing Standard](https://mimesniff.spec.whatwg.org/).
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/README.md b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/README.md
new file mode 100644
index 0000000..b0b1fbfd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/README.md
@@ -0,0 +1,34 @@
+== MIME types ==
+
+`resources/mime-types.json` and `resources/generated-mime-types.json` contain MIME type tests. The tests are encoded as a JSON array. String values in the array serve as documentation. All other values are objects with the following fields:
+
+* `input`: The string to be parsed.
+* `output`: Null if parsing resulted in failure and the MIME type record serialized as string otherwise.
+* `navigable`: True if the MIME type can be used for a document to be loaded in a browsing context (i.e., does not result in a download) and omitted otherwise.
+* `encoding`: The encoding that can be extracted from the MIME type or null if no encoding can be extracted, and omitted otherwise.
+
+Note: the object description implies that there tests without `navigable` or `encoding` set.
+
+A wrapper for these JSON MIME type tests needs to take care that not all `input` values can be tested in all entrypoints. Some entrypoints only accept bytes and some have further restrictions. A function such as the one below can be used to differentiate:
+
+```js
+function isByteCompatible(str) {
+  for(let i = 0; i < str.length; i++) {
+    const charCode = str.charCodeAt(i);
+    // See https://github.com/w3c/web-platform-tests/issues/8372 for 0x0B and 0x0C
+    // See https://fetch.spec.whatwg.org/#concept-header-value for the remainder
+    if(charCode > 0xFF) {
+      return "incompatible";
+    } else if(charCode === 0x00 || charCode === 0x0A || charCode === 0x0D) {
+      return "header-value-incompatible";
+    } else if(charCode === 0x0B || charCode === 0x0C) {
+      return "wptserve-incompatible";
+    }
+  }
+  return "compatible";
+}
+```
+
+`resources/generated-mime-types.json` is generated by running `resources/generated-mime-types.py`. Modify the latter to correct the former.
+
+These tests are used by resources in this directory to test various aspects of MIME types.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window-expected.txt
new file mode 100644
index 0000000..469e657f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window-expected.txt
@@ -0,0 +1,32 @@
+This is a testharness.js-based test.
+PASS Loading data…
+PASS text/html;charset=gbk
+PASS TEXT/HTML;CHARSET=GBK
+FAIL text/html;charset=gbk( assert_equals: expected "UTF-8" but got "GBK"
+PASS text/html;x=(;charset=gbk
+FAIL text/html;charset=gbk;charset=windows-1255 assert_equals: expected "GBK" but got "windows-1255"
+PASS text/html;charset =gbk
+PASS text/html ;charset=gbk
+PASS text/html; charset=gbk
+PASS text/html;charset= gbk
+PASS text/html;charset='gbk'
+PASS text/html;charset='gbk
+PASS text/html;charset=gbk'
+PASS text/html;test;charset=gbk
+PASS text/html;test=;charset=gbk
+PASS text/html;';charset=gbk
+FAIL text/html;";charset=gbk assert_equals: expected "GBK" but got "UTF-8"
+PASS text/html ; ; charset=gbk
+PASS text/html;;;;charset=gbk
+PASS text/html;charset="gbk"
+PASS text/html;charset="gbk
+PASS text/html;charset=gbk"
+FAIL text/html;charset=" gbk" assert_equals: expected "GBK" but got "UTF-8"
+FAIL text/html;charset="\ gbk" assert_equals: expected "GBK" but got "UTF-8"
+FAIL text/html;charset="\g\b\k" assert_equals: expected "GBK" but got "UTF-8"
+PASS text/html;charset="gbk"x
+PASS text/html;charset={gbk}
+PASS text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk
+PASS text/html;test=ÿ;charset=gbk
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window.js b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window.js
new file mode 100644
index 0000000..7b4e946
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window.js
@@ -0,0 +1,57 @@
+promise_test(() => {
+  // Don't load generated-mime-types.json as none of them are navigable
+  return fetch("resources/mime-types.json").then(res => res.json().then(runTests));
+}, "Loading data…");
+
+function isByteCompatible(str) {
+  for(let i = 0; i < str.length; i++) {
+    const charCode = str.charCodeAt(i);
+    // See https://github.com/w3c/web-platform-tests/issues/8372 for 0x0B and 0x0C
+    // See https://fetch.spec.whatwg.org/#concept-header-value for the remainder
+    if(charCode > 0xFF) {
+      return "incompatible";
+    } else if(charCode === 0x00 || charCode === 0x0A || charCode === 0x0D) {
+      return "header-value-incompatible";
+    } else if(charCode === 0x0B || charCode === 0x0C) {
+      return "wptserve-incompatible";
+    }
+  }
+  return "compatible";
+}
+
+function encodeForURL(str) {
+  let output = "";
+  for(let i = 0; i < str.length; i++) {
+    const char = str.charCodeAt(i);
+    if(char > 0xFF) {
+      throw new Error("We cannot deal with input that is not latin1");
+    } else  {
+      output += "%" + char.toString(16).padStart(2, "0");
+    }
+  }
+  return output;
+}
+
+function runTests(tests) {
+  tests.forEach(val => {
+    if(typeof val === "string" || val.navigable === undefined || val.encoding === undefined || isByteCompatible(val.input) !== "compatible") {
+      return;
+    }
+    const mime = val.input;
+    async_test(t => {
+      const frame = document.createElement("iframe"),
+            expectedEncoding = val.encoding === null ? "UTF-8" : val.encoding;
+      t.add_cleanup(() => frame.remove());
+      frame.onload = t.step_func(() => {
+        if(frame.contentWindow.location.href === "about:blank") {
+          return;
+        }
+        // Edge fails all these tests due to not using the correct encoding label.
+        assert_equals(frame.contentDocument.characterSet, expectedEncoding);
+        t.done();
+      });
+      frame.src = "resources/mime-charset.py?type=" + encodeForURL(mime);
+      document.body.appendChild(frame);
+    }, mime);
+  });
+}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/generated-mime-types.json b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/generated-mime-types.json
new file mode 100644
index 0000000..f8934da4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/generated-mime-types.json
@@ -0,0 +1,3526 @@
+[
+  {
+    "input": "\u0000/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0000",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0000=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0000;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0000\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0001/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0001",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0001=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0001;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0001\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0002/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0002",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0002=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0002;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0002\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0003/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0003",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0003=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0003;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0003\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0004/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0004",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0004=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0004;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0004\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0005/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0005",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0005=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0005;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0005\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0006/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0006",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0006=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0006;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0006\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0007/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0007",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0007=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0007;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0007\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\b/x",
+    "output": null
+  },
+  {
+    "input": "x/\b",
+    "output": null
+  },
+  {
+    "input": "x/x;\b=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\b;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\b\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\t/x",
+    "output": null
+  },
+  {
+    "input": "x/\t",
+    "output": null
+  },
+  {
+    "input": "x/x;\t=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\n/x",
+    "output": null
+  },
+  {
+    "input": "x/\n",
+    "output": null
+  },
+  {
+    "input": "x/x;\n=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\n;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\n\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u000b/x",
+    "output": null
+  },
+  {
+    "input": "x/\u000b",
+    "output": null
+  },
+  {
+    "input": "x/x;\u000b=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u000b;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u000b\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\f/x",
+    "output": null
+  },
+  {
+    "input": "x/\f",
+    "output": null
+  },
+  {
+    "input": "x/x;\f=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\f;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\f\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\r/x",
+    "output": null
+  },
+  {
+    "input": "x/\r",
+    "output": null
+  },
+  {
+    "input": "x/x;\r=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\r;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\r\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u000e/x",
+    "output": null
+  },
+  {
+    "input": "x/\u000e",
+    "output": null
+  },
+  {
+    "input": "x/x;\u000e=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u000e;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u000e\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u000f/x",
+    "output": null
+  },
+  {
+    "input": "x/\u000f",
+    "output": null
+  },
+  {
+    "input": "x/x;\u000f=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u000f;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u000f\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0010/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0010",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0010=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0010;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0010\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0011/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0011",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0011=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0011;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0011\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0012/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0012",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0012=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0012;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0012\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0013/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0013",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0013=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0013;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0013\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0014/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0014",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0014=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0014;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0014\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0015/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0015",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0015=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0015;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0015\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0016/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0016",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0016=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0016;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0016\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0017/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0017",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0017=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0017;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0017\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0018/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0018",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0018=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0018;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0018\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0019/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0019",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0019=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0019;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0019\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u001a/x",
+    "output": null
+  },
+  {
+    "input": "x/\u001a",
+    "output": null
+  },
+  {
+    "input": "x/x;\u001a=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u001a;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u001a\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u001b/x",
+    "output": null
+  },
+  {
+    "input": "x/\u001b",
+    "output": null
+  },
+  {
+    "input": "x/x;\u001b=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u001b;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u001b\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u001c/x",
+    "output": null
+  },
+  {
+    "input": "x/\u001c",
+    "output": null
+  },
+  {
+    "input": "x/x;\u001c=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u001c;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u001c\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u001d/x",
+    "output": null
+  },
+  {
+    "input": "x/\u001d",
+    "output": null
+  },
+  {
+    "input": "x/x;\u001d=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u001d;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u001d\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u001e/x",
+    "output": null
+  },
+  {
+    "input": "x/\u001e",
+    "output": null
+  },
+  {
+    "input": "x/x;\u001e=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u001e;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u001e\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u001f/x",
+    "output": null
+  },
+  {
+    "input": "x/\u001f",
+    "output": null
+  },
+  {
+    "input": "x/x;\u001f=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u001f;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u001f\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": " /x",
+    "output": null
+  },
+  {
+    "input": "x/ ",
+    "output": null
+  },
+  {
+    "input": "x/x; =x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\"/x",
+    "output": null
+  },
+  {
+    "input": "x/\"",
+    "output": null
+  },
+  {
+    "input": "x/x;\"=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "(/x",
+    "output": null
+  },
+  {
+    "input": "x/(",
+    "output": null
+  },
+  {
+    "input": "x/x;(=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=(;bonus=x",
+    "output": "x/x;x=\"(\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"(\";bonus=x",
+    "output": "x/x;x=\"(\";bonus=x"
+  },
+  {
+    "input": ")/x",
+    "output": null
+  },
+  {
+    "input": "x/)",
+    "output": null
+  },
+  {
+    "input": "x/x;)=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=);bonus=x",
+    "output": "x/x;x=\")\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\")\";bonus=x",
+    "output": "x/x;x=\")\";bonus=x"
+  },
+  {
+    "input": ",/x",
+    "output": null
+  },
+  {
+    "input": "x/,",
+    "output": null
+  },
+  {
+    "input": "x/x;,=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=,;bonus=x",
+    "output": "x/x;x=\",\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\",\";bonus=x",
+    "output": "x/x;x=\",\";bonus=x"
+  },
+  {
+    "input": "x/x;/=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=/;bonus=x",
+    "output": "x/x;x=\"/\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"/\";bonus=x",
+    "output": "x/x;x=\"/\";bonus=x"
+  },
+  {
+    "input": ":/x",
+    "output": null
+  },
+  {
+    "input": "x/:",
+    "output": null
+  },
+  {
+    "input": "x/x;:=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=:;bonus=x",
+    "output": "x/x;x=\":\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\":\";bonus=x",
+    "output": "x/x;x=\":\";bonus=x"
+  },
+  {
+    "input": ";/x",
+    "output": null
+  },
+  {
+    "input": "x/;",
+    "output": null
+  },
+  {
+    "input": "</x",
+    "output": null
+  },
+  {
+    "input": "x/<",
+    "output": null
+  },
+  {
+    "input": "x/x;<=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=<;bonus=x",
+    "output": "x/x;x=\"<\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"<\";bonus=x",
+    "output": "x/x;x=\"<\";bonus=x"
+  },
+  {
+    "input": "=/x",
+    "output": null
+  },
+  {
+    "input": "x/=",
+    "output": null
+  },
+  {
+    "input": "x/x;x==;bonus=x",
+    "output": "x/x;x=\"=\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"=\";bonus=x",
+    "output": "x/x;x=\"=\";bonus=x"
+  },
+  {
+    "input": ">/x",
+    "output": null
+  },
+  {
+    "input": "x/>",
+    "output": null
+  },
+  {
+    "input": "x/x;>=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=>;bonus=x",
+    "output": "x/x;x=\">\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\">\";bonus=x",
+    "output": "x/x;x=\">\";bonus=x"
+  },
+  {
+    "input": "?/x",
+    "output": null
+  },
+  {
+    "input": "x/?",
+    "output": null
+  },
+  {
+    "input": "x/x;?=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=?;bonus=x",
+    "output": "x/x;x=\"?\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"?\";bonus=x",
+    "output": "x/x;x=\"?\";bonus=x"
+  },
+  {
+    "input": "@/x",
+    "output": null
+  },
+  {
+    "input": "x/@",
+    "output": null
+  },
+  {
+    "input": "x/x;@=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=@;bonus=x",
+    "output": "x/x;x=\"@\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"@\";bonus=x",
+    "output": "x/x;x=\"@\";bonus=x"
+  },
+  {
+    "input": "[/x",
+    "output": null
+  },
+  {
+    "input": "x/[",
+    "output": null
+  },
+  {
+    "input": "x/x;[=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=[;bonus=x",
+    "output": "x/x;x=\"[\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"[\";bonus=x",
+    "output": "x/x;x=\"[\";bonus=x"
+  },
+  {
+    "input": "\\/x",
+    "output": null
+  },
+  {
+    "input": "x/\\",
+    "output": null
+  },
+  {
+    "input": "x/x;\\=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "]/x",
+    "output": null
+  },
+  {
+    "input": "x/]",
+    "output": null
+  },
+  {
+    "input": "x/x;]=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=];bonus=x",
+    "output": "x/x;x=\"]\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"]\";bonus=x",
+    "output": "x/x;x=\"]\";bonus=x"
+  },
+  {
+    "input": "{/x",
+    "output": null
+  },
+  {
+    "input": "x/{",
+    "output": null
+  },
+  {
+    "input": "x/x;{=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x={;bonus=x",
+    "output": "x/x;x=\"{\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"{\";bonus=x",
+    "output": "x/x;x=\"{\";bonus=x"
+  },
+  {
+    "input": "}/x",
+    "output": null
+  },
+  {
+    "input": "x/}",
+    "output": null
+  },
+  {
+    "input": "x/x;}=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=};bonus=x",
+    "output": "x/x;x=\"}\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"}\";bonus=x",
+    "output": "x/x;x=\"}\";bonus=x"
+  },
+  {
+    "input": "\u007f/x",
+    "output": null
+  },
+  {
+    "input": "x/\u007f",
+    "output": null
+  },
+  {
+    "input": "x/x;\u007f=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u007f;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u007f\";bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "\u0080/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0080",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0080=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0080;bonus=x",
+    "output": "x/x;x=\"\u0080\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0080\";bonus=x",
+    "output": "x/x;x=\"\u0080\";bonus=x"
+  },
+  {
+    "input": "\u0081/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0081",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0081=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0081;bonus=x",
+    "output": "x/x;x=\"\u0081\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0081\";bonus=x",
+    "output": "x/x;x=\"\u0081\";bonus=x"
+  },
+  {
+    "input": "\u0082/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0082",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0082=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0082;bonus=x",
+    "output": "x/x;x=\"\u0082\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0082\";bonus=x",
+    "output": "x/x;x=\"\u0082\";bonus=x"
+  },
+  {
+    "input": "\u0083/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0083",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0083=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0083;bonus=x",
+    "output": "x/x;x=\"\u0083\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0083\";bonus=x",
+    "output": "x/x;x=\"\u0083\";bonus=x"
+  },
+  {
+    "input": "\u0084/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0084",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0084=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0084;bonus=x",
+    "output": "x/x;x=\"\u0084\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0084\";bonus=x",
+    "output": "x/x;x=\"\u0084\";bonus=x"
+  },
+  {
+    "input": "\u0085/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0085",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0085=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0085;bonus=x",
+    "output": "x/x;x=\"\u0085\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0085\";bonus=x",
+    "output": "x/x;x=\"\u0085\";bonus=x"
+  },
+  {
+    "input": "\u0086/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0086",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0086=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0086;bonus=x",
+    "output": "x/x;x=\"\u0086\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0086\";bonus=x",
+    "output": "x/x;x=\"\u0086\";bonus=x"
+  },
+  {
+    "input": "\u0087/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0087",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0087=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0087;bonus=x",
+    "output": "x/x;x=\"\u0087\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0087\";bonus=x",
+    "output": "x/x;x=\"\u0087\";bonus=x"
+  },
+  {
+    "input": "\u0088/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0088",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0088=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0088;bonus=x",
+    "output": "x/x;x=\"\u0088\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0088\";bonus=x",
+    "output": "x/x;x=\"\u0088\";bonus=x"
+  },
+  {
+    "input": "\u0089/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0089",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0089=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0089;bonus=x",
+    "output": "x/x;x=\"\u0089\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0089\";bonus=x",
+    "output": "x/x;x=\"\u0089\";bonus=x"
+  },
+  {
+    "input": "\u008a/x",
+    "output": null
+  },
+  {
+    "input": "x/\u008a",
+    "output": null
+  },
+  {
+    "input": "x/x;\u008a=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u008a;bonus=x",
+    "output": "x/x;x=\"\u008a\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u008a\";bonus=x",
+    "output": "x/x;x=\"\u008a\";bonus=x"
+  },
+  {
+    "input": "\u008b/x",
+    "output": null
+  },
+  {
+    "input": "x/\u008b",
+    "output": null
+  },
+  {
+    "input": "x/x;\u008b=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u008b;bonus=x",
+    "output": "x/x;x=\"\u008b\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u008b\";bonus=x",
+    "output": "x/x;x=\"\u008b\";bonus=x"
+  },
+  {
+    "input": "\u008c/x",
+    "output": null
+  },
+  {
+    "input": "x/\u008c",
+    "output": null
+  },
+  {
+    "input": "x/x;\u008c=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u008c;bonus=x",
+    "output": "x/x;x=\"\u008c\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u008c\";bonus=x",
+    "output": "x/x;x=\"\u008c\";bonus=x"
+  },
+  {
+    "input": "\u008d/x",
+    "output": null
+  },
+  {
+    "input": "x/\u008d",
+    "output": null
+  },
+  {
+    "input": "x/x;\u008d=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u008d;bonus=x",
+    "output": "x/x;x=\"\u008d\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u008d\";bonus=x",
+    "output": "x/x;x=\"\u008d\";bonus=x"
+  },
+  {
+    "input": "\u008e/x",
+    "output": null
+  },
+  {
+    "input": "x/\u008e",
+    "output": null
+  },
+  {
+    "input": "x/x;\u008e=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u008e;bonus=x",
+    "output": "x/x;x=\"\u008e\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u008e\";bonus=x",
+    "output": "x/x;x=\"\u008e\";bonus=x"
+  },
+  {
+    "input": "\u008f/x",
+    "output": null
+  },
+  {
+    "input": "x/\u008f",
+    "output": null
+  },
+  {
+    "input": "x/x;\u008f=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u008f;bonus=x",
+    "output": "x/x;x=\"\u008f\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u008f\";bonus=x",
+    "output": "x/x;x=\"\u008f\";bonus=x"
+  },
+  {
+    "input": "\u0090/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0090",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0090=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0090;bonus=x",
+    "output": "x/x;x=\"\u0090\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0090\";bonus=x",
+    "output": "x/x;x=\"\u0090\";bonus=x"
+  },
+  {
+    "input": "\u0091/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0091",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0091=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0091;bonus=x",
+    "output": "x/x;x=\"\u0091\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0091\";bonus=x",
+    "output": "x/x;x=\"\u0091\";bonus=x"
+  },
+  {
+    "input": "\u0092/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0092",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0092=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0092;bonus=x",
+    "output": "x/x;x=\"\u0092\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0092\";bonus=x",
+    "output": "x/x;x=\"\u0092\";bonus=x"
+  },
+  {
+    "input": "\u0093/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0093",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0093=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0093;bonus=x",
+    "output": "x/x;x=\"\u0093\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0093\";bonus=x",
+    "output": "x/x;x=\"\u0093\";bonus=x"
+  },
+  {
+    "input": "\u0094/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0094",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0094=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0094;bonus=x",
+    "output": "x/x;x=\"\u0094\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0094\";bonus=x",
+    "output": "x/x;x=\"\u0094\";bonus=x"
+  },
+  {
+    "input": "\u0095/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0095",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0095=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0095;bonus=x",
+    "output": "x/x;x=\"\u0095\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0095\";bonus=x",
+    "output": "x/x;x=\"\u0095\";bonus=x"
+  },
+  {
+    "input": "\u0096/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0096",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0096=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0096;bonus=x",
+    "output": "x/x;x=\"\u0096\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0096\";bonus=x",
+    "output": "x/x;x=\"\u0096\";bonus=x"
+  },
+  {
+    "input": "\u0097/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0097",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0097=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0097;bonus=x",
+    "output": "x/x;x=\"\u0097\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0097\";bonus=x",
+    "output": "x/x;x=\"\u0097\";bonus=x"
+  },
+  {
+    "input": "\u0098/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0098",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0098=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0098;bonus=x",
+    "output": "x/x;x=\"\u0098\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0098\";bonus=x",
+    "output": "x/x;x=\"\u0098\";bonus=x"
+  },
+  {
+    "input": "\u0099/x",
+    "output": null
+  },
+  {
+    "input": "x/\u0099",
+    "output": null
+  },
+  {
+    "input": "x/x;\u0099=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u0099;bonus=x",
+    "output": "x/x;x=\"\u0099\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u0099\";bonus=x",
+    "output": "x/x;x=\"\u0099\";bonus=x"
+  },
+  {
+    "input": "\u009a/x",
+    "output": null
+  },
+  {
+    "input": "x/\u009a",
+    "output": null
+  },
+  {
+    "input": "x/x;\u009a=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u009a;bonus=x",
+    "output": "x/x;x=\"\u009a\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u009a\";bonus=x",
+    "output": "x/x;x=\"\u009a\";bonus=x"
+  },
+  {
+    "input": "\u009b/x",
+    "output": null
+  },
+  {
+    "input": "x/\u009b",
+    "output": null
+  },
+  {
+    "input": "x/x;\u009b=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u009b;bonus=x",
+    "output": "x/x;x=\"\u009b\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u009b\";bonus=x",
+    "output": "x/x;x=\"\u009b\";bonus=x"
+  },
+  {
+    "input": "\u009c/x",
+    "output": null
+  },
+  {
+    "input": "x/\u009c",
+    "output": null
+  },
+  {
+    "input": "x/x;\u009c=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u009c;bonus=x",
+    "output": "x/x;x=\"\u009c\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u009c\";bonus=x",
+    "output": "x/x;x=\"\u009c\";bonus=x"
+  },
+  {
+    "input": "\u009d/x",
+    "output": null
+  },
+  {
+    "input": "x/\u009d",
+    "output": null
+  },
+  {
+    "input": "x/x;\u009d=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u009d;bonus=x",
+    "output": "x/x;x=\"\u009d\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u009d\";bonus=x",
+    "output": "x/x;x=\"\u009d\";bonus=x"
+  },
+  {
+    "input": "\u009e/x",
+    "output": null
+  },
+  {
+    "input": "x/\u009e",
+    "output": null
+  },
+  {
+    "input": "x/x;\u009e=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u009e;bonus=x",
+    "output": "x/x;x=\"\u009e\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u009e\";bonus=x",
+    "output": "x/x;x=\"\u009e\";bonus=x"
+  },
+  {
+    "input": "\u009f/x",
+    "output": null
+  },
+  {
+    "input": "x/\u009f",
+    "output": null
+  },
+  {
+    "input": "x/x;\u009f=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u009f;bonus=x",
+    "output": "x/x;x=\"\u009f\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u009f\";bonus=x",
+    "output": "x/x;x=\"\u009f\";bonus=x"
+  },
+  {
+    "input": "\u00a0/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a0",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a0=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a0;bonus=x",
+    "output": "x/x;x=\"\u00a0\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a0\";bonus=x",
+    "output": "x/x;x=\"\u00a0\";bonus=x"
+  },
+  {
+    "input": "\u00a1/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a1",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a1=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a1;bonus=x",
+    "output": "x/x;x=\"\u00a1\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a1\";bonus=x",
+    "output": "x/x;x=\"\u00a1\";bonus=x"
+  },
+  {
+    "input": "\u00a2/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a2",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a2=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a2;bonus=x",
+    "output": "x/x;x=\"\u00a2\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a2\";bonus=x",
+    "output": "x/x;x=\"\u00a2\";bonus=x"
+  },
+  {
+    "input": "\u00a3/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a3",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a3=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a3;bonus=x",
+    "output": "x/x;x=\"\u00a3\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a3\";bonus=x",
+    "output": "x/x;x=\"\u00a3\";bonus=x"
+  },
+  {
+    "input": "\u00a4/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a4",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a4=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a4;bonus=x",
+    "output": "x/x;x=\"\u00a4\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a4\";bonus=x",
+    "output": "x/x;x=\"\u00a4\";bonus=x"
+  },
+  {
+    "input": "\u00a5/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a5",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a5=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a5;bonus=x",
+    "output": "x/x;x=\"\u00a5\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a5\";bonus=x",
+    "output": "x/x;x=\"\u00a5\";bonus=x"
+  },
+  {
+    "input": "\u00a6/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a6",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a6=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a6;bonus=x",
+    "output": "x/x;x=\"\u00a6\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a6\";bonus=x",
+    "output": "x/x;x=\"\u00a6\";bonus=x"
+  },
+  {
+    "input": "\u00a7/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a7",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a7=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a7;bonus=x",
+    "output": "x/x;x=\"\u00a7\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a7\";bonus=x",
+    "output": "x/x;x=\"\u00a7\";bonus=x"
+  },
+  {
+    "input": "\u00a8/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a8",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a8=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a8;bonus=x",
+    "output": "x/x;x=\"\u00a8\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a8\";bonus=x",
+    "output": "x/x;x=\"\u00a8\";bonus=x"
+  },
+  {
+    "input": "\u00a9/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00a9",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00a9=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00a9;bonus=x",
+    "output": "x/x;x=\"\u00a9\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00a9\";bonus=x",
+    "output": "x/x;x=\"\u00a9\";bonus=x"
+  },
+  {
+    "input": "\u00aa/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00aa",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00aa=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00aa;bonus=x",
+    "output": "x/x;x=\"\u00aa\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00aa\";bonus=x",
+    "output": "x/x;x=\"\u00aa\";bonus=x"
+  },
+  {
+    "input": "\u00ab/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ab",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ab=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ab;bonus=x",
+    "output": "x/x;x=\"\u00ab\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ab\";bonus=x",
+    "output": "x/x;x=\"\u00ab\";bonus=x"
+  },
+  {
+    "input": "\u00ac/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ac",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ac=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ac;bonus=x",
+    "output": "x/x;x=\"\u00ac\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ac\";bonus=x",
+    "output": "x/x;x=\"\u00ac\";bonus=x"
+  },
+  {
+    "input": "\u00ad/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ad",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ad=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ad;bonus=x",
+    "output": "x/x;x=\"\u00ad\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ad\";bonus=x",
+    "output": "x/x;x=\"\u00ad\";bonus=x"
+  },
+  {
+    "input": "\u00ae/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ae",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ae=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ae;bonus=x",
+    "output": "x/x;x=\"\u00ae\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ae\";bonus=x",
+    "output": "x/x;x=\"\u00ae\";bonus=x"
+  },
+  {
+    "input": "\u00af/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00af",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00af=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00af;bonus=x",
+    "output": "x/x;x=\"\u00af\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00af\";bonus=x",
+    "output": "x/x;x=\"\u00af\";bonus=x"
+  },
+  {
+    "input": "\u00b0/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b0",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b0=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b0;bonus=x",
+    "output": "x/x;x=\"\u00b0\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b0\";bonus=x",
+    "output": "x/x;x=\"\u00b0\";bonus=x"
+  },
+  {
+    "input": "\u00b1/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b1",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b1=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b1;bonus=x",
+    "output": "x/x;x=\"\u00b1\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b1\";bonus=x",
+    "output": "x/x;x=\"\u00b1\";bonus=x"
+  },
+  {
+    "input": "\u00b2/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b2",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b2=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b2;bonus=x",
+    "output": "x/x;x=\"\u00b2\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b2\";bonus=x",
+    "output": "x/x;x=\"\u00b2\";bonus=x"
+  },
+  {
+    "input": "\u00b3/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b3",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b3=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b3;bonus=x",
+    "output": "x/x;x=\"\u00b3\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b3\";bonus=x",
+    "output": "x/x;x=\"\u00b3\";bonus=x"
+  },
+  {
+    "input": "\u00b4/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b4",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b4=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b4;bonus=x",
+    "output": "x/x;x=\"\u00b4\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b4\";bonus=x",
+    "output": "x/x;x=\"\u00b4\";bonus=x"
+  },
+  {
+    "input": "\u00b5/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b5",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b5=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b5;bonus=x",
+    "output": "x/x;x=\"\u00b5\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b5\";bonus=x",
+    "output": "x/x;x=\"\u00b5\";bonus=x"
+  },
+  {
+    "input": "\u00b6/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b6",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b6=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b6;bonus=x",
+    "output": "x/x;x=\"\u00b6\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b6\";bonus=x",
+    "output": "x/x;x=\"\u00b6\";bonus=x"
+  },
+  {
+    "input": "\u00b7/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b7",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b7=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b7;bonus=x",
+    "output": "x/x;x=\"\u00b7\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b7\";bonus=x",
+    "output": "x/x;x=\"\u00b7\";bonus=x"
+  },
+  {
+    "input": "\u00b8/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b8",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b8=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b8;bonus=x",
+    "output": "x/x;x=\"\u00b8\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b8\";bonus=x",
+    "output": "x/x;x=\"\u00b8\";bonus=x"
+  },
+  {
+    "input": "\u00b9/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00b9",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00b9=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00b9;bonus=x",
+    "output": "x/x;x=\"\u00b9\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00b9\";bonus=x",
+    "output": "x/x;x=\"\u00b9\";bonus=x"
+  },
+  {
+    "input": "\u00ba/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ba",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ba=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ba;bonus=x",
+    "output": "x/x;x=\"\u00ba\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ba\";bonus=x",
+    "output": "x/x;x=\"\u00ba\";bonus=x"
+  },
+  {
+    "input": "\u00bb/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00bb",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00bb=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00bb;bonus=x",
+    "output": "x/x;x=\"\u00bb\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00bb\";bonus=x",
+    "output": "x/x;x=\"\u00bb\";bonus=x"
+  },
+  {
+    "input": "\u00bc/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00bc",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00bc=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00bc;bonus=x",
+    "output": "x/x;x=\"\u00bc\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00bc\";bonus=x",
+    "output": "x/x;x=\"\u00bc\";bonus=x"
+  },
+  {
+    "input": "\u00bd/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00bd",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00bd=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00bd;bonus=x",
+    "output": "x/x;x=\"\u00bd\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00bd\";bonus=x",
+    "output": "x/x;x=\"\u00bd\";bonus=x"
+  },
+  {
+    "input": "\u00be/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00be",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00be=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00be;bonus=x",
+    "output": "x/x;x=\"\u00be\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00be\";bonus=x",
+    "output": "x/x;x=\"\u00be\";bonus=x"
+  },
+  {
+    "input": "\u00bf/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00bf",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00bf=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00bf;bonus=x",
+    "output": "x/x;x=\"\u00bf\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00bf\";bonus=x",
+    "output": "x/x;x=\"\u00bf\";bonus=x"
+  },
+  {
+    "input": "\u00c0/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c0",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c0=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c0;bonus=x",
+    "output": "x/x;x=\"\u00c0\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c0\";bonus=x",
+    "output": "x/x;x=\"\u00c0\";bonus=x"
+  },
+  {
+    "input": "\u00c1/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c1",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c1=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c1;bonus=x",
+    "output": "x/x;x=\"\u00c1\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c1\";bonus=x",
+    "output": "x/x;x=\"\u00c1\";bonus=x"
+  },
+  {
+    "input": "\u00c2/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c2",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c2=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c2;bonus=x",
+    "output": "x/x;x=\"\u00c2\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c2\";bonus=x",
+    "output": "x/x;x=\"\u00c2\";bonus=x"
+  },
+  {
+    "input": "\u00c3/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c3",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c3=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c3;bonus=x",
+    "output": "x/x;x=\"\u00c3\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c3\";bonus=x",
+    "output": "x/x;x=\"\u00c3\";bonus=x"
+  },
+  {
+    "input": "\u00c4/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c4",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c4=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c4;bonus=x",
+    "output": "x/x;x=\"\u00c4\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c4\";bonus=x",
+    "output": "x/x;x=\"\u00c4\";bonus=x"
+  },
+  {
+    "input": "\u00c5/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c5",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c5=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c5;bonus=x",
+    "output": "x/x;x=\"\u00c5\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c5\";bonus=x",
+    "output": "x/x;x=\"\u00c5\";bonus=x"
+  },
+  {
+    "input": "\u00c6/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c6",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c6=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c6;bonus=x",
+    "output": "x/x;x=\"\u00c6\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c6\";bonus=x",
+    "output": "x/x;x=\"\u00c6\";bonus=x"
+  },
+  {
+    "input": "\u00c7/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c7",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c7=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c7;bonus=x",
+    "output": "x/x;x=\"\u00c7\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c7\";bonus=x",
+    "output": "x/x;x=\"\u00c7\";bonus=x"
+  },
+  {
+    "input": "\u00c8/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c8",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c8=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c8;bonus=x",
+    "output": "x/x;x=\"\u00c8\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c8\";bonus=x",
+    "output": "x/x;x=\"\u00c8\";bonus=x"
+  },
+  {
+    "input": "\u00c9/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00c9",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00c9=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00c9;bonus=x",
+    "output": "x/x;x=\"\u00c9\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00c9\";bonus=x",
+    "output": "x/x;x=\"\u00c9\";bonus=x"
+  },
+  {
+    "input": "\u00ca/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ca",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ca=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ca;bonus=x",
+    "output": "x/x;x=\"\u00ca\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ca\";bonus=x",
+    "output": "x/x;x=\"\u00ca\";bonus=x"
+  },
+  {
+    "input": "\u00cb/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00cb",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00cb=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00cb;bonus=x",
+    "output": "x/x;x=\"\u00cb\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00cb\";bonus=x",
+    "output": "x/x;x=\"\u00cb\";bonus=x"
+  },
+  {
+    "input": "\u00cc/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00cc",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00cc=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00cc;bonus=x",
+    "output": "x/x;x=\"\u00cc\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00cc\";bonus=x",
+    "output": "x/x;x=\"\u00cc\";bonus=x"
+  },
+  {
+    "input": "\u00cd/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00cd",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00cd=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00cd;bonus=x",
+    "output": "x/x;x=\"\u00cd\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00cd\";bonus=x",
+    "output": "x/x;x=\"\u00cd\";bonus=x"
+  },
+  {
+    "input": "\u00ce/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ce",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ce=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ce;bonus=x",
+    "output": "x/x;x=\"\u00ce\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ce\";bonus=x",
+    "output": "x/x;x=\"\u00ce\";bonus=x"
+  },
+  {
+    "input": "\u00cf/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00cf",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00cf=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00cf;bonus=x",
+    "output": "x/x;x=\"\u00cf\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00cf\";bonus=x",
+    "output": "x/x;x=\"\u00cf\";bonus=x"
+  },
+  {
+    "input": "\u00d0/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d0",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d0=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d0;bonus=x",
+    "output": "x/x;x=\"\u00d0\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d0\";bonus=x",
+    "output": "x/x;x=\"\u00d0\";bonus=x"
+  },
+  {
+    "input": "\u00d1/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d1",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d1=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d1;bonus=x",
+    "output": "x/x;x=\"\u00d1\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d1\";bonus=x",
+    "output": "x/x;x=\"\u00d1\";bonus=x"
+  },
+  {
+    "input": "\u00d2/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d2",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d2=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d2;bonus=x",
+    "output": "x/x;x=\"\u00d2\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d2\";bonus=x",
+    "output": "x/x;x=\"\u00d2\";bonus=x"
+  },
+  {
+    "input": "\u00d3/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d3",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d3=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d3;bonus=x",
+    "output": "x/x;x=\"\u00d3\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d3\";bonus=x",
+    "output": "x/x;x=\"\u00d3\";bonus=x"
+  },
+  {
+    "input": "\u00d4/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d4",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d4=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d4;bonus=x",
+    "output": "x/x;x=\"\u00d4\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d4\";bonus=x",
+    "output": "x/x;x=\"\u00d4\";bonus=x"
+  },
+  {
+    "input": "\u00d5/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d5",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d5=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d5;bonus=x",
+    "output": "x/x;x=\"\u00d5\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d5\";bonus=x",
+    "output": "x/x;x=\"\u00d5\";bonus=x"
+  },
+  {
+    "input": "\u00d6/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d6",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d6=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d6;bonus=x",
+    "output": "x/x;x=\"\u00d6\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d6\";bonus=x",
+    "output": "x/x;x=\"\u00d6\";bonus=x"
+  },
+  {
+    "input": "\u00d7/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d7",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d7=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d7;bonus=x",
+    "output": "x/x;x=\"\u00d7\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d7\";bonus=x",
+    "output": "x/x;x=\"\u00d7\";bonus=x"
+  },
+  {
+    "input": "\u00d8/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d8",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d8=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d8;bonus=x",
+    "output": "x/x;x=\"\u00d8\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d8\";bonus=x",
+    "output": "x/x;x=\"\u00d8\";bonus=x"
+  },
+  {
+    "input": "\u00d9/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00d9",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00d9=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00d9;bonus=x",
+    "output": "x/x;x=\"\u00d9\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00d9\";bonus=x",
+    "output": "x/x;x=\"\u00d9\";bonus=x"
+  },
+  {
+    "input": "\u00da/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00da",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00da=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00da;bonus=x",
+    "output": "x/x;x=\"\u00da\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00da\";bonus=x",
+    "output": "x/x;x=\"\u00da\";bonus=x"
+  },
+  {
+    "input": "\u00db/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00db",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00db=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00db;bonus=x",
+    "output": "x/x;x=\"\u00db\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00db\";bonus=x",
+    "output": "x/x;x=\"\u00db\";bonus=x"
+  },
+  {
+    "input": "\u00dc/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00dc",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00dc=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00dc;bonus=x",
+    "output": "x/x;x=\"\u00dc\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00dc\";bonus=x",
+    "output": "x/x;x=\"\u00dc\";bonus=x"
+  },
+  {
+    "input": "\u00dd/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00dd",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00dd=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00dd;bonus=x",
+    "output": "x/x;x=\"\u00dd\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00dd\";bonus=x",
+    "output": "x/x;x=\"\u00dd\";bonus=x"
+  },
+  {
+    "input": "\u00de/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00de",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00de=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00de;bonus=x",
+    "output": "x/x;x=\"\u00de\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00de\";bonus=x",
+    "output": "x/x;x=\"\u00de\";bonus=x"
+  },
+  {
+    "input": "\u00df/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00df",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00df=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00df;bonus=x",
+    "output": "x/x;x=\"\u00df\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00df\";bonus=x",
+    "output": "x/x;x=\"\u00df\";bonus=x"
+  },
+  {
+    "input": "\u00e0/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e0",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e0=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e0;bonus=x",
+    "output": "x/x;x=\"\u00e0\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e0\";bonus=x",
+    "output": "x/x;x=\"\u00e0\";bonus=x"
+  },
+  {
+    "input": "\u00e1/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e1",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e1=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e1;bonus=x",
+    "output": "x/x;x=\"\u00e1\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e1\";bonus=x",
+    "output": "x/x;x=\"\u00e1\";bonus=x"
+  },
+  {
+    "input": "\u00e2/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e2",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e2=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e2;bonus=x",
+    "output": "x/x;x=\"\u00e2\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e2\";bonus=x",
+    "output": "x/x;x=\"\u00e2\";bonus=x"
+  },
+  {
+    "input": "\u00e3/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e3",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e3=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e3;bonus=x",
+    "output": "x/x;x=\"\u00e3\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e3\";bonus=x",
+    "output": "x/x;x=\"\u00e3\";bonus=x"
+  },
+  {
+    "input": "\u00e4/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e4",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e4=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e4;bonus=x",
+    "output": "x/x;x=\"\u00e4\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e4\";bonus=x",
+    "output": "x/x;x=\"\u00e4\";bonus=x"
+  },
+  {
+    "input": "\u00e5/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e5",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e5=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e5;bonus=x",
+    "output": "x/x;x=\"\u00e5\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e5\";bonus=x",
+    "output": "x/x;x=\"\u00e5\";bonus=x"
+  },
+  {
+    "input": "\u00e6/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e6",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e6=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e6;bonus=x",
+    "output": "x/x;x=\"\u00e6\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e6\";bonus=x",
+    "output": "x/x;x=\"\u00e6\";bonus=x"
+  },
+  {
+    "input": "\u00e7/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e7",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e7=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e7;bonus=x",
+    "output": "x/x;x=\"\u00e7\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e7\";bonus=x",
+    "output": "x/x;x=\"\u00e7\";bonus=x"
+  },
+  {
+    "input": "\u00e8/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e8",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e8=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e8;bonus=x",
+    "output": "x/x;x=\"\u00e8\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e8\";bonus=x",
+    "output": "x/x;x=\"\u00e8\";bonus=x"
+  },
+  {
+    "input": "\u00e9/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00e9",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00e9=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00e9;bonus=x",
+    "output": "x/x;x=\"\u00e9\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00e9\";bonus=x",
+    "output": "x/x;x=\"\u00e9\";bonus=x"
+  },
+  {
+    "input": "\u00ea/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ea",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ea=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ea;bonus=x",
+    "output": "x/x;x=\"\u00ea\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ea\";bonus=x",
+    "output": "x/x;x=\"\u00ea\";bonus=x"
+  },
+  {
+    "input": "\u00eb/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00eb",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00eb=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00eb;bonus=x",
+    "output": "x/x;x=\"\u00eb\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00eb\";bonus=x",
+    "output": "x/x;x=\"\u00eb\";bonus=x"
+  },
+  {
+    "input": "\u00ec/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ec",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ec=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ec;bonus=x",
+    "output": "x/x;x=\"\u00ec\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ec\";bonus=x",
+    "output": "x/x;x=\"\u00ec\";bonus=x"
+  },
+  {
+    "input": "\u00ed/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ed",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ed=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ed;bonus=x",
+    "output": "x/x;x=\"\u00ed\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ed\";bonus=x",
+    "output": "x/x;x=\"\u00ed\";bonus=x"
+  },
+  {
+    "input": "\u00ee/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ee",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ee=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ee;bonus=x",
+    "output": "x/x;x=\"\u00ee\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ee\";bonus=x",
+    "output": "x/x;x=\"\u00ee\";bonus=x"
+  },
+  {
+    "input": "\u00ef/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ef",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ef=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ef;bonus=x",
+    "output": "x/x;x=\"\u00ef\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ef\";bonus=x",
+    "output": "x/x;x=\"\u00ef\";bonus=x"
+  },
+  {
+    "input": "\u00f0/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f0",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f0=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f0;bonus=x",
+    "output": "x/x;x=\"\u00f0\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f0\";bonus=x",
+    "output": "x/x;x=\"\u00f0\";bonus=x"
+  },
+  {
+    "input": "\u00f1/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f1",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f1=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f1;bonus=x",
+    "output": "x/x;x=\"\u00f1\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f1\";bonus=x",
+    "output": "x/x;x=\"\u00f1\";bonus=x"
+  },
+  {
+    "input": "\u00f2/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f2",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f2=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f2;bonus=x",
+    "output": "x/x;x=\"\u00f2\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f2\";bonus=x",
+    "output": "x/x;x=\"\u00f2\";bonus=x"
+  },
+  {
+    "input": "\u00f3/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f3",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f3=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f3;bonus=x",
+    "output": "x/x;x=\"\u00f3\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f3\";bonus=x",
+    "output": "x/x;x=\"\u00f3\";bonus=x"
+  },
+  {
+    "input": "\u00f4/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f4",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f4=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f4;bonus=x",
+    "output": "x/x;x=\"\u00f4\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f4\";bonus=x",
+    "output": "x/x;x=\"\u00f4\";bonus=x"
+  },
+  {
+    "input": "\u00f5/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f5",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f5=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f5;bonus=x",
+    "output": "x/x;x=\"\u00f5\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f5\";bonus=x",
+    "output": "x/x;x=\"\u00f5\";bonus=x"
+  },
+  {
+    "input": "\u00f6/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f6",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f6=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f6;bonus=x",
+    "output": "x/x;x=\"\u00f6\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f6\";bonus=x",
+    "output": "x/x;x=\"\u00f6\";bonus=x"
+  },
+  {
+    "input": "\u00f7/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f7",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f7=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f7;bonus=x",
+    "output": "x/x;x=\"\u00f7\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f7\";bonus=x",
+    "output": "x/x;x=\"\u00f7\";bonus=x"
+  },
+  {
+    "input": "\u00f8/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f8",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f8=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f8;bonus=x",
+    "output": "x/x;x=\"\u00f8\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f8\";bonus=x",
+    "output": "x/x;x=\"\u00f8\";bonus=x"
+  },
+  {
+    "input": "\u00f9/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00f9",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00f9=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00f9;bonus=x",
+    "output": "x/x;x=\"\u00f9\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00f9\";bonus=x",
+    "output": "x/x;x=\"\u00f9\";bonus=x"
+  },
+  {
+    "input": "\u00fa/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00fa",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00fa=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00fa;bonus=x",
+    "output": "x/x;x=\"\u00fa\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00fa\";bonus=x",
+    "output": "x/x;x=\"\u00fa\";bonus=x"
+  },
+  {
+    "input": "\u00fb/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00fb",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00fb=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00fb;bonus=x",
+    "output": "x/x;x=\"\u00fb\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00fb\";bonus=x",
+    "output": "x/x;x=\"\u00fb\";bonus=x"
+  },
+  {
+    "input": "\u00fc/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00fc",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00fc=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00fc;bonus=x",
+    "output": "x/x;x=\"\u00fc\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00fc\";bonus=x",
+    "output": "x/x;x=\"\u00fc\";bonus=x"
+  },
+  {
+    "input": "\u00fd/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00fd",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00fd=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00fd;bonus=x",
+    "output": "x/x;x=\"\u00fd\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00fd\";bonus=x",
+    "output": "x/x;x=\"\u00fd\";bonus=x"
+  },
+  {
+    "input": "\u00fe/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00fe",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00fe=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00fe;bonus=x",
+    "output": "x/x;x=\"\u00fe\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00fe\";bonus=x",
+    "output": "x/x;x=\"\u00fe\";bonus=x"
+  },
+  {
+    "input": "\u00ff/x",
+    "output": null
+  },
+  {
+    "input": "x/\u00ff",
+    "output": null
+  },
+  {
+    "input": "x/x;\u00ff=x;bonus=x",
+    "output": "x/x;bonus=x"
+  },
+  {
+    "input": "x/x;x=\u00ff;bonus=x",
+    "output": "x/x;x=\"\u00ff\";bonus=x"
+  },
+  {
+    "input": "x/x;x=\"\u00ff\";bonus=x",
+    "output": "x/x;x=\"\u00ff\";bonus=x"
+  }
+]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/generated-mime-types.py b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/generated-mime-types.py
new file mode 100644
index 0000000..9192114
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/generated-mime-types.py
@@ -0,0 +1,45 @@
+import json
+
+def isHTTPTokenCodePoint(cp):
+    if cp in (0x21, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2A, 0x2B, 0x2D, 0x2E, 0x5E, 0x5F, 0x60, 0x7C, 0x7E) or (cp >= 0x30 and cp <= 0x39) or (cp >= 0x41 and cp <= 0x5A) or (cp >= 0x61 and cp <= 0x7A):
+        return True
+    else:
+        return False
+
+def isHTTPQuotedStringTokenCodePoint(cp):
+    if cp == 0x09 or (cp >= 0x20 and cp <= 0x7E) or (cp >= 0x80 and cp <= 0xFF):
+        return True
+    else:
+        return False
+
+tests = []
+
+for cp in range(0x00, 0x100):
+    if isHTTPTokenCodePoint(cp):
+        continue
+    for scenario in ("type", "subtype", "name", "value"):
+        if scenario == "type" or scenario == "subtype":
+            if cp == 0x2F: # /
+                continue
+            if scenario == "type":
+                test = unichr(cp) + "/x"
+            else:
+                test = "x/" + unichr(cp)
+            tests.append({"input": test, "output": None})
+        elif scenario == "name":
+            if cp == 0x3B or cp == 0x3D: # ; =
+                continue
+            tests.append({"input": "x/x;" + unichr(cp) + "=x;bonus=x", "output": "x/x;bonus=x"})
+        elif scenario == "value":
+            if cp == 0x09 or cp == 0x20 or cp == 0x22 or cp == 0x3B or cp == 0x5C: # TAB SP " ; \
+                continue
+            if isHTTPQuotedStringTokenCodePoint(cp):
+                testOutput = "x/x;x=\"" + unichr(cp) + "\";bonus=x"
+            else:
+                testOutput = "x/x;bonus=x"
+            tests.append({"input": "x/x;x=" + unichr(cp) + ";bonus=x", "output": testOutput})
+            tests.append({"input": "x/x;x=\"" + unichr(cp) + "\";bonus=x", "output": testOutput})
+
+handle = open("generated-mime-types.json", "w")
+handle.write(json.dumps(tests, indent=2, separators=(',', ': ')))
+handle.write("\n")
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-charset.py b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-charset.py
new file mode 100644
index 0000000..433a5bb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-charset.py
@@ -0,0 +1,3 @@
+def main(request, response):
+    response.headers.set("Content-Type", request.GET.first("type"));
+    response.content = "<meta charset=utf-8>\n<script>document.write(document.characterSet)</script>"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-types.json b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-types.json
new file mode 100644
index 0000000..6bee02d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-types.json
@@ -0,0 +1,262 @@
+[
+  "Basics",
+  {
+    "input": "text/html;charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "TEXT/HTML;CHARSET=GBK",
+    "output": "text/html;charset=GBK",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  "Legacy comment syntax",
+  {
+    "input": "text/html;charset=gbk(",
+    "output": "text/html;charset=\"gbk(\"",
+    "navigable": true,
+    "encoding": null
+  },
+  {
+    "input": "text/html;x=(;charset=gbk",
+    "output": "text/html;x=\"(\";charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  "Duplicate parameter",
+  {
+    "input": "text/html;charset=gbk;charset=windows-1255",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  "Spaces",
+  {
+    "input": "text/html;charset =gbk",
+    "output": "text/html",
+    "navigable": true,
+    "encoding": null
+  },
+  {
+    "input": "text/html ;charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html; charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;charset= gbk",
+    "output": "text/html;charset=\" gbk\"",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  "Single quotes are a token, not a delimiter",
+  {
+    "input": "text/html;charset='gbk'",
+    "output": "text/html;charset='gbk'",
+    "navigable": true,
+    "encoding": null
+  },
+  {
+    "input": "text/html;charset='gbk",
+    "output": "text/html;charset='gbk",
+    "navigable": true,
+    "encoding": null
+  },
+  {
+    "input": "text/html;charset=gbk'",
+    "output": "text/html;charset=gbk'",
+    "navigable": true,
+    "encoding": null
+  },
+  "Invalid parameters",
+  {
+    "input": "text/html;test;charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;test=;charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;';charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;\";charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html ; ; charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;;;;charset=gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  "Double quotes",
+  {
+    "input": "text/html;charset=\"gbk\"",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;charset=\"gbk",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;charset=gbk\"",
+    "output": "text/html;charset=\"gbk\\\"\"",
+    "navigable": true,
+    "encoding": null
+  },
+  {
+    "input": "text/html;charset=\" gbk\"",
+    "output": "text/html;charset=\" gbk\"",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;charset=\"\\ gbk\"",
+    "output": "text/html;charset=\" gbk\"",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;charset=\"\\g\\b\\k\"",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  {
+    "input": "text/html;charset=\"gbk\"x",
+    "output": "text/html;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  "Unexpected code points",
+  {
+    "input": "text/html;charset={gbk}",
+    "output": "text/html;charset=\"{gbk}\"",
+    "navigable": true,
+    "encoding": null
+  },
+  "Parameter name longer than 127",
+  {
+    "input": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk",
+    "output": "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  "type/subtype longer than 127",
+  {
+    "input": "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
+    "output": "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+  },
+  "Valid",
+  {
+    "input": "!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+    "output": "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+  },
+  {
+    "input": "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008A\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A8\u00A9\u00AA\u00AB\u00AC\u00AD\u00AE\u00AF\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6\u00B7\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\"",
+    "output": "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008A\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F\u00A0\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A8\u00A9\u00AA\u00AB\u00AC\u00AD\u00AE\u00AF\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6\u00B7\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\""
+  },
+  "End-of-file handling",
+  {
+    "input": "x/x;test",
+    "output": "x/x"
+  },
+  {
+    "input": "x/x;test=\"\\",
+    "output": "x/x;test=\"\\\\\""
+  },
+  "Whitespace (not handled by generated-mime-types.json or above)",
+  {
+    "input": "x/x;x= ",
+    "output": "x/x"
+  },
+  {
+    "input": "x/x;x=\t",
+    "output": "x/x"
+  },
+  "Latin1",
+  {
+    "input": "text/html;test=\u00FF;charset=gbk",
+    "output": "text/html;test=\"\u00FF\";charset=gbk",
+    "navigable": true,
+    "encoding": "GBK"
+  },
+  ">Latin1",
+  {
+    "input": "x/x;test=\uFFFD;x=x",
+    "output": "x/x;x=x"
+  },
+  "Failure",
+  {
+    "input": "",
+    "output": null
+  },
+  {
+    "input": "\t",
+    "output": null
+  },
+  {
+    "input": "bogus",
+    "output": null
+  },
+  {
+    "input": "bogus/",
+    "output": null
+  },
+  {
+    "input": "bogus/ ",
+    "output": null
+  },
+  {
+    "input": "bogus/bogus/;",
+    "output": null
+  },
+  {
+    "input": "</>",
+    "output": null
+  },
+  {
+    "input": "(/)",
+    "output": null
+  },
+  {
+    "input": "text/html(;doesnot=matter",
+    "output": null
+  },
+  {
+    "input": "{/}",
+    "output": null
+  },
+  {
+    "input": "\u0100/\u0100",
+    "output": null
+  }
+]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
index d8e5589..75de0081 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
@@ -3,7 +3,7 @@
 PASS Service Worker responds to fetch event with string
 PASS Service Worker responds to fetch event with blob body
 PASS Service Worker responds to fetch event with the referrer URL
-PASS Service Worker responds to fetch event with an existing client id
+FAIL Service Worker responds to fetch event with an existing client id assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with a client id expected "Client ID Not Found" but got "Client ID Found: null" Reached unreachable code
 PASS Service Worker does not respond to fetch event
 PASS Service Worker responds to fetch event with null response body
 PASS Service Worker fetches other file in fetch event
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js
index 77c99e83..79a1ce7b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js
@@ -4,9 +4,9 @@
 // the `event` object. In the case of the `onmessage` handler, it provides the
 // Client instance attributes of the requested clients.
 self.onfetch = function(e) {
-  if (e.request.mode === 'navigate' && e.clientId !== null) {
+  if (e.request.mode === 'navigate' && e.clientId !== "") {
     e.respondWith(Response.error(
-      '`clientId` incorrectly set to non-null value for request with mode `navigate`'
+      '`clientId` incorrectly set to non-empty string for request with mode `navigate`'
     ));
     return;
   }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-test-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-test-worker.js
index 3d8eb0b..65025d9 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-test-worker.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-test-worker.js
@@ -29,7 +29,7 @@
 
 function handleClientId(event) {
   var body;
-  if (event.clientId !== null) {
+  if (event.clientId !== "") {
     body = 'Client ID Found: ' + event.clientId;
   } else {
     body = 'Client ID Not Found';
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/test-helpers.sub.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/test-helpers.sub.js
index 1f6bbaa..38ec4ae9 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/test-helpers.sub.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/test-helpers.sub.js
@@ -201,20 +201,12 @@
     });
 }
 
-function login(test) {
-  return test_login(test, 'http://{{domains[www1]}}:{{ports[http][0]}}',
-                    'username1', 'password1', 'cookie1')
-    .then(function() {
-        return test_login(test, 'http://{{host}}:{{ports[http][0]}}',
-                          'username2', 'password2', 'cookie2');
-      });
-}
-
 function login_https(test) {
-  return test_login(test, 'https://{{domains[www1]}}:{{ports[https][0]}}',
+  var host_info = get_host_info();
+  return test_login(test, host_info.HTTPS_REMOTE_ORIGIN,
                     'username1s', 'password1s', 'cookie1')
     .then(function() {
-        return test_login(test, 'https://{{host}}:{{ports[https][0]}}',
+        return test_login(test, host_info.HTTPS_ORIGIN,
                           'username2s', 'password2s', 'cookie2');
       });
 }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/update-built-tests.sh b/third_party/WebKit/LayoutTests/external/wpt/update-built-tests.sh
index 63722f4b1..f44dd5e 100755
--- a/third_party/WebKit/LayoutTests/external/wpt/update-built-tests.sh
+++ b/third_party/WebKit/LayoutTests/external/wpt/update-built-tests.sh
@@ -5,3 +5,4 @@
 infrastructure/assumptions/tools/build.sh
 html/tools/build.sh
 offscreen-canvas/tools/build.sh
+python mimesniff/mime-types/resources/generated-mime-types.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-maxMessageSize-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-maxMessageSize-expected.txt
new file mode 100644
index 0000000..4d1f9a1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-maxMessageSize-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL Determine the local side send limitation (canSendSize) by offering a max-message-size of 0 assert_equals: expected (object) null but got (undefined) undefined
+FAIL Remote offer SDP missing max-message-size attribute assert_equals: expected (object) null but got (undefined) undefined
+FAIL max-message-size with a (non-zero) value provided by the remote peer assert_equals: expected (object) null but got (undefined) undefined
+FAIL Renegotiate max-message-size with a (non-zero) value provided by the remote peer assert_equals: expected (object) null but got (undefined) undefined
+FAIL max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer assert_equals: expected (object) null but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-maxMessageSize.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-maxMessageSize.html
new file mode 100644
index 0000000..7d73cc5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-maxMessageSize.html
@@ -0,0 +1,181 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCSctpTransport.prototype.maxMessageSize</title>
+<link rel="help" href="https://w3c.github.io/webrtc-pc/#rtcsctptransport-interface">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+'use strict';
+
+// This test has an assert_unreached() that requires that the variable
+// canSendSize (initiated below) is greater than 2, if non-zero. The reason
+// is that we need two non-zero values that are less that that value for
+// testing with predictable results. This is a bit unfortunate but shouldn't
+// have any practical impact.
+
+// Helper class to read SDP attributes and generate SDPs with modified attribute values
+class SDPAttributeHelper {
+  constructor(attrName, valueRegExpStr) {
+    this.attrName = attrName;
+    this.re = new RegExp(`^a=${attrName}:(${valueRegExpStr})\\r\\n`, 'm');
+  }
+
+  getValue(sdp) {
+    const matches = sdp.match(this.re);
+    return matches ? matches[1] : null;
+  }
+
+  sdpWithValue(sdp, value) {
+    const matches = sdp.match(this.re);
+    const sdpParts = sdp.split(matches[0]);
+    const attributeLine = arguments.length > 1 ? `a=${this.attrName}:${value}\r\n` : '';
+    return `${sdpParts[0]}${attributeLine}${sdpParts[1]}`;
+  }
+
+  sdpWithoutAttribute(sdp) {
+    return this.sdpWithValue(sdp);
+  }
+}
+
+const mmsAttributeHelper = new SDPAttributeHelper('max-message-size', '\\d+');
+let canSendSize;
+const remoteValue1 = 1;
+const remoteValue2 = 2;
+
+promise_test(t => {
+  const pc = new RTCPeerConnection();
+  assert_equals(pc.sctp, null);
+  let maxMessageSize;
+
+  return generateOffer({ pc, data: true })
+  .then((offer) => {
+    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
+      'SDP should have max-message-size attribute');
+
+    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, 0) };
+    return pc.setRemoteDescription(offer);
+  })
+  .then(() => pc.createAnswer())
+  .then((answer) => pc.setLocalDescription(answer))
+  .then(() => {
+    assert_not_equals(pc.sctp, null);
+    canSendSize = pc.sctp.maxMessageSize == Number.POSITIVE_INFINITY ? 0 : pc.sctp.maxMessageSize;
+    if (canSendSize != 0 && canSendSize < remoteValue2) {
+      assert_unreached('This test needs two values that are less than canSendSize (unless it is zero)');
+    }
+  });
+}, 'Determine the local side send limitation (canSendSize) by offering a max-message-size of 0');
+
+promise_test(t => {
+  const pc = new RTCPeerConnection();
+  assert_equals(pc.sctp, null);
+
+  return generateOffer({ pc, data: true })
+  .then((offer) => {
+    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
+      'SDP should have max-message-size attribute');
+
+    // Remove the max-message-size SDP attribute
+    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithoutAttribute(offer.sdp) };
+    return pc.setRemoteDescription(offer)
+  })
+  .then(() => pc.createAnswer())
+  .then((answer) => pc.setLocalDescription(answer))
+  .then(() => {
+    assert_not_equals(pc.sctp, null);
+    // Test outcome depends on canSendSize value
+    if (canSendSize) {
+      assert_equals(pc.sctp.maxMessageSize, Math.min(65535, canSendSize),
+        'Missing SDP attribute and a non-zero canSendSize should give an maxMessageSize of min(65535, canSendSize)');
+    } else {
+      assert_equals(pc.sctp.maxMessageSize, 65535,
+        'Missing SDP attribute and a canSendSize of 0 should give an maxMessageSize of 65535');
+    }
+  });
+}, 'Remote offer SDP missing max-message-size attribute');
+
+promise_test(t => {
+  const pc = new RTCPeerConnection();
+  assert_equals(pc.sctp, null);
+
+  return generateOffer({ pc, data: true })
+  .then((offer) => {
+    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
+      'SDP should have max-message-size attribute');
+
+    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) };
+    return pc.setRemoteDescription(offer);
+  })
+  .then(() => pc.createAnswer())
+  .then((answer) => pc.setLocalDescription(answer))
+  .then(() => {
+    assert_not_equals(pc.sctp, null);
+    assert_equals(pc.sctp.maxMessageSize, remoteValue1,
+      'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
+  });
+}, 'max-message-size with a (non-zero) value provided by the remote peer');
+
+promise_test(t => {
+  const pc = new RTCPeerConnection();
+  assert_equals(pc.sctp, null);
+
+  return generateOffer({ pc, data: true })
+  .then((offer) => {
+    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
+      'SDP should have max-message-size attribute');
+
+    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) };
+    return pc.setRemoteDescription(offer)
+  })
+  .then(() => pc.createAnswer())
+  .then((answer) => pc.setLocalDescription(answer))
+  .then(() => {
+    assert_not_equals(pc.sctp, null);
+    assert_equals(pc.sctp.maxMessageSize, remoteValue1,
+      'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
+  })
+  .then(() => pc.createOffer()) // Start new O/A exchange that updates max-message-size
+  .then((offer) => {
+    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue2)};
+    return pc.setRemoteDescription(offer)
+  })
+  .then(() => pc.createAnswer())
+  .then((answer) => pc.setLocalDescription(answer))
+  .then(() => {
+    assert_not_equals(pc.sctp, null);
+    assert_equals(pc.sctp.maxMessageSize, remoteValue2,
+      'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)');
+  })
+  ;
+}, 'Renegotiate max-message-size with a (non-zero) value provided by the remote peer');
+
+promise_test(t => {
+  const pc = new RTCPeerConnection();
+  assert_equals(pc.sctp, null);
+  const largerThanCanSendSize = canSendSize + 1;
+
+  return generateOffer({ pc, data: true })
+  .then((offer) => {
+    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
+      'SDP should have max-message-size attribute');
+
+    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, largerThanCanSendSize) };
+    return pc.setRemoteDescription(offer)
+  })
+  .then(() => pc.createAnswer())
+  .then((answer) => pc.setLocalDescription(answer))
+  .then(() => {
+    assert_not_equals(pc.sctp, null);
+    // Test outcome depends on canSendSize value
+    if (canSendSize) {
+      assert_equals(pc.sctp.maxMessageSize, canSendSize,
+        'A remote value larger than a non-zero canSendSize should limit maxMessageSize to canSendSize');
+    } else {
+      assert_equals(pc.sctp.maxMessageSize, 65535,
+        'A canSendSize of zero should let the remote value set maxMessageSize');
+    }
+  });
+}, 'max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-radius-iframe-expected.html b/third_party/WebKit/LayoutTests/fast/borders/border-radius-iframe-expected.html
new file mode 100644
index 0000000..0325744
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-radius-iframe-expected.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<style>
+  #outer {
+    height: 500px;
+    width: 500px;
+    background-color: blue;
+    border-style: solid;
+    border-color: gray;
+    border-radius: 50px;
+    border-width: 10px;
+    overflow: hidden;
+  }
+</style>
+<div id="outer">
+    <div style="background-color: green; position: relative; width: 600px; height: 480px; top: 10px; left: 0">
+    </div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-radius-iframe.html b/third_party/WebKit/LayoutTests/fast/borders/border-radius-iframe.html
new file mode 100644
index 0000000..41746aa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-radius-iframe.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+  #iframe {
+    height: 500px;
+    width: 500px;
+    background-color: blue;
+    border-style: solid;
+    border-radius: 50px;
+    border-width: 10px;
+    border-color: gray;
+  }
+</style>
+<iframe id="iframe" src="resources/subframe.html">
+</iframe>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/resources/subframe.html b/third_party/WebKit/LayoutTests/fast/borders/resources/subframe.html
new file mode 100644
index 0000000..3df2fe9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/borders/resources/subframe.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<div id="block" style="background-color: green; position: absolute; top: 10px; bottom: 10px; left: 0; right: 0;">
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/line-through-vertical.html b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/line-through-vertical.html
deleted file mode 100644
index 187f993..0000000
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/line-through-vertical.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<style>
-div {
-  writing-mode: vertical-rl;
-  text-decoration: line-through;
-  font-family: Times;
-  font-size: 50px;
-}
-</style>
-<div>
-  <span lang="ja">ABC</span>
-  <span lang="en">ABC</span>
-</div>
diff --git a/third_party/WebKit/LayoutTests/fast/events/pointerevents/touch-pointer-event-properties.html b/third_party/WebKit/LayoutTests/fast/events/pointerevents/touch-pointer-event-properties.html
index 2ee83df8..fe388ff 100644
--- a/third_party/WebKit/LayoutTests/fast/events/pointerevents/touch-pointer-event-properties.html
+++ b/third_party/WebKit/LayoutTests/fast/events/pointerevents/touch-pointer-event-properties.html
@@ -39,9 +39,9 @@
     for (var i = 0 ; i < POINTER_PROPERTIES.length; ++i) {
       var pp = POINTER_PROPERTIES[i];
       if (i != POINTER_PROPERTIES.length-1)
-        eventSender.addTouchPoint(x + i, y + i, pp["width"], pp["height"], pp["pressure"], pp["tiltX"], pp["tiltY"], pp["pointerType"]);
+        eventSender.addTouchPoint(x + i, y + i, pp["width"] / 2.0, pp["height"] / 2.0, pp["pressure"], pp["tiltX"], pp["tiltY"], pp["pointerType"]);
       else // Test default pointerType
-        eventSender.addTouchPoint(x + i, y + i, pp["width"], pp["height"], pp["pressure"], pp["tiltX"], pp["tiltY"]);
+        eventSender.addTouchPoint(x + i, y + i, pp["width"] / 2.0, pp["height"] / 2.0, pp["pressure"], pp["tiltX"], pp["tiltY"]);
     }
     eventSender.touchStart();
 
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/multi-touch-user-gesture.html b/third_party/WebKit/LayoutTests/fast/events/touch/multi-touch-user-gesture.html
new file mode 100644
index 0000000..9aabdea
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/events/touch/multi-touch-user-gesture.html
@@ -0,0 +1,67 @@
+<script src='../../../resources/testharness.js'></script>
+<script src='../../../resources/testharnessreport.js'></script>
+<div id="target1" style="touch-action:none; width: 200px; height: 50px;">Target1</div>
+<div id="target2" style="touch-action:none; width: 200px; height: 50px;">Target2</div>
+<div id="description">Test user gesture behavior during multi-finger touch events.</div>
+<div id="console"></div>
+
+<script>
+
+var target1 = document.getElementById('target1');
+var rect1 = target1.getBoundingClientRect();
+var targetX1 = rect1.left + rect1.width / 2;
+var targetY1 = rect1.top + rect1.height / 2;
+
+var target2 = document.getElementById('target2');
+var rect2 = target2.getBoundingClientRect();
+var targetX2 = rect2.left + rect2.width / 2;
+var targetY2 = rect2.top + rect2.height / 2;
+
+var receivedEvents = [];
+
+['touchstart', 'touchmove', 'touchend'].forEach( eventName => {
+  [target1, target2].forEach(t => {
+    t.addEventListener(eventName, event => {
+      var w = window.open("about:blank", "_blank");
+      var openedPopup = undefined;
+      if (w) {
+        w.close();
+        openedPopup = true;
+      } else {
+        openedPopup = false;
+      }
+      receivedEvents.push(event.type + '@' + event.target.id + '(' + openedPopup + ')');
+    });
+  });
+});
+
+var testUserGesture = async_test('Test user gesture behavior during multi-finger touch events.');
+
+function callback() {
+  testUserGesture.step(function () {
+    assert_equals(receivedEvents.join(', '), "touchstart@target1(false), touchstart@target2(false), touchmove@target1(false), touchmove@target2(false), touchend@target1(true), touchend@target2(true)");
+  });
+  testUserGesture.done();
+}
+
+if (window.chrome && chrome.gpuBenchmarking && window.testRunner) {
+  testRunner.setCloseRemainingWindowsWhenComplete(true);
+  testRunner.setCanOpenWindows();
+  testRunner.setPopupBlockingEnabled(true);
+  var pointerActions =
+    [
+    {source: "touch",
+      actions: [
+      { name: "pointerDown", x: targetX1, y: targetY1 },
+      { name: "pointerMove", x: targetX1+30, y: targetY1 },
+      { name: "pointerUp" }]},
+    {source: "touch",
+      actions: [
+      { name: "pointerDown", x: targetX2, y: targetY2 },
+      { name: "pointerMove", x: targetX2+30, y: targetY2 },
+      { name: "pointerUp" }]}
+    ];
+  chrome.gpuBenchmarking.pointerActionSequence(pointerActions, callback);
+}
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt b/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt
index fe734b7f..f3fe4d0 100644
--- a/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt
@@ -31,12 +31,6 @@
 PASS new Blob([(new Float64Array(100)).buffer, (new Int32Array(100)).buffer, (new Uint8Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1400
 PASS new Blob([new Blob([(new Int32Array(100)).buffer]), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1000
 PASS new Blob([new Uint8Array(new SharedArrayBuffer(4))]) threw exception TypeError: Failed to construct 'Blob': The provided ArrayBufferView value must not be shared..
-PASS OMICRON_WITH_OXIA.charCodeAt(0) is 0x1F79
-PASS reader.result.charCodeAt(0) is 0x1F79
-PASS CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3) is 0xDC00
-PASS CONTAINS_UNPAIRED_SURROGATES.charCodeAt(7) is 0xD800
-PASS reader.result.charCodeAt(3) is 0xFFFD
-PASS reader.result.charCodeAt(7) is 0xFFFD
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html b/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html
index 936e78c1..d060319c 100644
--- a/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html
+++ b/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html
@@ -3,8 +3,6 @@
 <script src="../../resources/js-test.js"></script>
 <script>
 description("Test the Blob constructor.");
-var jsTestIsAsync = true;
-
 // Test that the File-specific lastModified is not set by the Blob constructor.
 shouldBe("(new Blob([])).lastModified", "undefined");
 shouldBe("(new Blob([], {})).lastModified", "undefined");
@@ -42,33 +40,4 @@
   // Test SharedArrayBuffer parameters.
   shouldThrow("new Blob([new Uint8Array(new SharedArrayBuffer(4))])", '"TypeError: Failed to construct \'Blob\': The provided ArrayBufferView value must not be shared."');
 }
-
-testNormalization();
-
-function testNormalization() {
-  // Test that strings are not NFC normalized
-  OMICRON_WITH_OXIA = '\u1F79'; // NFC normalized to U+3CC
-  shouldBe("OMICRON_WITH_OXIA.charCodeAt(0)", "0x1F79");
-  reader = new FileReader();
-  reader.readAsText(new Blob([OMICRON_WITH_OXIA]));
-  reader.onload = function() {
-    shouldBe("reader.result.charCodeAt(0)", "0x1F79");
-    testEncodingReplacements();
-  };
-}
-
-function testEncodingReplacements() {
-  // Test that invalid UTF-16 code units are replaced.
-  CONTAINS_UNPAIRED_SURROGATES = 'abc\uDC00def\uD800ghi';
-  shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3)", "0xDC00");
-  shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(7)", "0xD800");
-  reader = new FileReader();
-  reader.readAsText(new Blob([CONTAINS_UNPAIRED_SURROGATES]));
-  reader.onload = function() {
-    shouldBe("reader.result.charCodeAt(3)", "0xFFFD");
-    shouldBe("reader.result.charCodeAt(7)", "0xFFFD");
-    finishJSTest();
-  };
-}
-
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/media/w3c/README b/third_party/WebKit/LayoutTests/fast/media/w3c/README
deleted file mode 100644
index a9cd257..0000000
--- a/third_party/WebKit/LayoutTests/fast/media/w3c/README
+++ /dev/null
@@ -1,8 +0,0 @@
-Imported CSS3 MediaQuery test suite from:
-
-http://hg.csswg.org/test/file/c88a96071aac/approved/css3-mediaqueries/src
-
-For license and acknowledgements see:
-
-http://hg.csswg.org/test/file/c88a96071aac/approved/css3-mediaqueries/src/index.html
-
diff --git a/third_party/WebKit/LayoutTests/fullscreen/full-screen-contentEditable-crash-expected.txt b/third_party/WebKit/LayoutTests/fullscreen/full-screen-contentEditable-crash-expected.txt
index 2799b65..a2f48eb 100644
--- a/third_party/WebKit/LayoutTests/fullscreen/full-screen-contentEditable-crash-expected.txt
+++ b/third_party/WebKit/LayoutTests/fullscreen/full-screen-contentEditable-crash-expected.txt
@@ -1,3 +1,2 @@
-CONSOLE WARNING: line 22: The behavior that Selection.addRange() merges existing Range and the specified Range was removed. See https://www.chromestatus.com/features/6680566019653632 for more details.
 Pass if there is no crash.
 Click anywhere to test manually.
diff --git a/third_party/WebKit/LayoutTests/fullscreen/keyboard-focus.html b/third_party/WebKit/LayoutTests/fullscreen/keyboard-focus.html
new file mode 100644
index 0000000..ea5fe64
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fullscreen/keyboard-focus.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<title>Elements not contained by the fullscreen element are inert</title>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../shadow-dom/resources/focus-utils.js"></script>
+<script src="trusted-click.js"></script>
+<div id="log"></div>
+<div id="before">
+  <input>
+</div>
+<div id="target">
+ <input>
+ <input>
+</div>
+<div id="after">
+  <input>
+</div>
+<script>
+// The important side effect of inertness is that focus moves away from an
+// element that becomes inert, and that when in fullscreen it's not possible to
+// move focus out of the fullscreen element.
+//
+// TODO(foolip): This is not yet per spec, so change the spec:
+// https://github.com/whatwg/fullscreen/issues/15
+async_test(t => {
+  const target = document.getElementById("target");
+  const beforeInput = document.querySelector("#before input");
+  const targetInputs = target.querySelectorAll("input");
+
+  // Initial focus is body, cycle to first input.
+  assert_equals(document.activeElement, document.body, 'active element #1');
+  navigateFocusForward();
+  assert_equals(document.activeElement, beforeInput, 'active element #2');
+
+  document.onfullscreenchange = t.step_func_done(() => {
+    // Entering fullscreen moved the focus back to body.
+    assert_equals(document.activeElement, document.body);
+
+    // Cycling focus should now skip the inert elements.
+    navigateFocusForward();
+    assert_equals(document.activeElement, targetInputs[0], 'active element #3');
+    navigateFocusForward();
+    assert_equals(document.activeElement, targetInputs[1], 'active element #4');
+    navigateFocusForward();
+    assert_equals(document.activeElement, targetInputs[0], 'active element #5');
+
+    // Cycling focus in reverse should also skip the inert elements.
+    navigateFocusBackward();
+    assert_equals(document.activeElement, targetInputs[1], 'active element #6');
+    navigateFocusBackward();
+    assert_equals(document.activeElement, targetInputs[0], 'active element #7');
+  });
+
+  trusted_request(t, target);
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-headers.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-headers.html
deleted file mode 100644
index a058986..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-headers.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<html>
-<head>
-<script src="../inspector/inspector-test.js"></script>
-<script src="../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-
-function extension_testAddHeaders(nextTest)
-{
-    webInspector.network.addRequestHeaders({
-        "x-webinspector-extension": "test",
-        "user-agent": "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)"
-    });
-    function cleanUpHeaders()
-    {
-        webInspector.network.addRequestHeaders({
-            "x-webinspector-extension": null,
-            "user-agent": null
-        });
-    }
-    webInspector.inspectedWindow.eval("doXHR()", callbackAndNextTest(cleanUpHeaders, nextTest));
-}
-
-function doXHR()
-{
-    var xhr = new XMLHttpRequest();
-    xhr.open("GET", "resources/echo-headers.php", false);
-    xhr.send(null);
-    // Can't use output() here due to output order instability: this is invoked by inspectedWindow.eval(),
-    // which is not serialized against output from extension, as the latter is posted asynchronously via
-    // postMessage to front-end window.
-    document.getElementById("headers").textContent += xhr.responseText;
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API</p>
-<div style="white-space: pre" id="headers"></div>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-iframe-eval.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-iframe-eval.html
deleted file mode 100644
index 24dca51..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-iframe-eval.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<html>
-<head>
-<script src="../inspector/inspector-test.js"></script>
-<script src="../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-
-function extension_testEvalInIFrame(nextTest) 
-{
-    var url = 'http://127.0.0.1:8000/devtools/resources/extensions-frame-eval.html';
-    var origin = "http://127.0.0.1:8000"
-    var options = {
-        frameURL: url
-    };
-    var loc = "window.location.pathname";
-    webInspector.inspectedWindow.eval(loc, options, callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalInIFrameBadOption(nextTest) 
-{
-    var url = 'http://127.0.0.1:8000/devtools/resources/extensions-frame-eval.html';
-    var origin = "http://127.0.0.1:8000"
-    var options = {
-        frameURL: url,
-        scriptExecutionContext: "bogus"
-    };
-    var loc = "window.location.pathname";
-    webInspector.inspectedWindow.eval(loc, options, callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_onEval(value, isException)
-{
-    output("Evaluate: " + JSON.stringify(value) + " (exception: " + isException + ")");
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API</p>
-<iframe src="resources/extensions-frame-eval.html"></iframe>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-ignore-cache.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-ignore-cache.html
deleted file mode 100644
index 18c455b..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-ignore-cache.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<html>
-<head>
-<script src="../inspector/inspector-test.js"></script>
-<script src="../inspector/extensions-test.js"></script>
-<script src="network/resources/random-script.php"></script>
-
-<script type="text/javascript">
-
-function extension_testIgnoreCache(nextTest)
-{
-    var beforeReload;
-    var afterReloadWithIgnoreCache;
-    var afterNormalReload;
-
-    function onNormalReload()
-    {
-        webInspector.inspectedWindow.eval("randomValue", function(value) {
-            afterNormalReload = value;
-            evaluateOnFrontend("TestRunner.runWhenPageLoads(reply)", onReloadWithIgnoreCache);
-            webInspector.inspectedWindow.reload({ ignoreCache: true });
-        });
-    };
-
-    function onReloadWithIgnoreCache()
-    {
-        webInspector.inspectedWindow.eval("randomValue", function(value) {
-            afterReloadWithIgnoreCache = value;
-            output("afterNormalReload " + (afterNormalReload === beforeReload ? "===" : "!==" ) + " beforeReload");
-            output("afterNormalReload " + (afterNormalReload === afterReloadWithIgnoreCache ? "===" : "!==" ) + " afterReloadWithIgnoreCache");
-            nextTest();
-        });
-    }
-
-    webInspector.inspectedWindow.eval("randomValue", function(value) {
-        beforeReload = value;
-        evaluateOnFrontend("TestRunner.runWhenPageLoads(reply)", onNormalReload);
-        webInspector.inspectedWindow.reload();
-    });
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests ignoreCache flag of WebInspector.inspectedPage.reload()</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-network-redirect.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-network-redirect.html
deleted file mode 100644
index e096244..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-network-redirect.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<html>
-<head>
-<script src="../inspector/inspector-test.js"></script>
-<script src="../inspector/extensions-network-test.js"></script>
-<script src="../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-
-function extension_doRequest(force, callback)
-{
-    function callbackWrapper(request)
-    {
-        var lastCallback = !request || /\?redirected=true$/.test(request.request.url);
-        if (lastCallback)
-            webInspector.network.onRequestFinished.removeListener(callbackWrapper);
-        callback(request, lastCallback);
-    }
-    webInspector.network.onRequestFinished.addListener(callbackWrapper);
-    webInspector.inspectedWindow.eval("doRequest(" + force + ")", function(result) {
-        if (result)
-            callbackWrapper(null);
-    });
-}
-
-function extension_testGetRedirectRequestContent(nextTest)
-{
-    function onRequestFinished(request, lastCallback)
-    {
-        if (!lastCallback)
-            return;
-        extension_getRequestByUrl([ /redirect-methods-result.php\?status=302$/ ], function(request) {
-            request.getContent(onContent);
-        });
-    }
-    function onContent(content, encoding)
-    {
-        output("content: " + content + ", encoding: " + encoding);
-        nextTest();
-    }
-    extension_doRequest(false, onRequestFinished);
-}
-
-function extension_testRedirectRequestInHAR(nextTest)
-{
-    function onRequestFinished(resource, lastCallback)
-    {
-        if (lastCallback)
-            webInspector.network.getHAR(onHAR);
-    }
-    function onHAR(har)
-    {
-        var entries = har.entries;
-        var urls = [];
-        for (var i = 0; i < entries.length; ++i) {
-            var url = entries[i].request.url;
-            // Workaround for GTK DRT that requests favicon.ico along with the page.
-            if (!/\/favicon\.ico$/.test(url))
-                urls.push(url);
-        }
-        urls.sort();
-        output("Requests in HAR:\n" + urls.join("\n"));
-        nextTest();
-    }
-    extension_doRequest(false, onRequestFinished);
-}
-
-function extension_testRedirectRequestFinished(nextTest)
-{
-    function onRequestFinished(request, lastCallback)
-    {
-        output("Finished request: " + request.request.url);
-        if (lastCallback)
-            nextTest();
-    }
-    extension_doRequest(true, onRequestFinished);
-}
-
-var requestDone = false;
-
-function doRequest(force)
-{
-    // Only do request once per test suite, to make tests independent on each other.
-    // Returns true iff request is alredy done (so the caller shouldn't wait for onFinished).
-    if (requestDone && !force)
-        return true;
-    requestDone = true;
-    // We can't use XHR here -- the content for XHRs is pushed from back-end.
-    var iframe = document.createElement("iframe");
-    iframe.src = "/loading/resources/redirect-methods-result.php?status=302";
-    document.body.appendChild(iframe);
-    return false;
-}
-
-var test = function() {
-  TestRunner.reloadPage(ExtensionsTestRunner.runExtensionTests);
-};
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API returns valid data for redirected resources</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-useragent-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-useragent-expected.txt
deleted file mode 100644
index 1572e1d9..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-useragent-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-CONSOLE WARNING: line 59: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE WARNING: line 59: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE WARNING: line 59: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-Tests overriding user agent via WebInspector extension API
-
-Started extension.
-Running tests...
-RUNNING TEST: extension_testUserAgent
-Page reloaded.
-Page reloaded.
-user-agent header for extensions-useragent.html: Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)
-user-agent header for xhr-exists.html: Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)
-navigator.userAgent: Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)
-All tests done.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-useragent.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-useragent.html
deleted file mode 100644
index cef11b6..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-useragent.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<html>
-<head>
-<script src="../inspector/inspector-test.js"></script>
-<script src="../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-
-function extension_testUserAgent(nextTest)
-{
-    const requestsToCheck = [
-        "extensions-useragent.html",
-        "xhr-exists.html"
-    ];
-    var requestCount = 0;
-    var queuedOutput = [];
-
-    function onRequestFinished(request)
-    {
-        var url = request.request.url.replace(/^.*[/]/, "");
-        if (requestsToCheck.indexOf(url) < 0)
-            return;
-
-        queuedOutput.push("user-agent header for " + url + ": " + getHeader(request.request.headers, "user-agent"));
-        if (++requestCount < requestsToCheck.length)
-            return;
-        webInspector.network.onRequestFinished.removeListener(onRequestFinished);
-        webInspector.inspectedWindow.eval("navigator.userAgent", onEval);
-    }
-    function getHeader(headers, name)
-    {
-        for (var i = 0; i < headers.length; ++i) {
-            if (headers[i].name.toLowerCase() === name)
-                return headers[i].value;
-        }
-    }
-    function onEval(result)
-    {
-        queuedOutput.push("navigator.userAgent: " + result);
-        webInspector.inspectedWindow.eval("undefined", cleanUp);
-    }
-    function cleanUp()
-    {
-        evaluateOnFrontend("TestRunner.runWhenPageLoads(reply)", onPageLoaded);
-        webInspector.inspectedWindow.reload("");
-    }
-    function onPageLoaded()
-    {
-        for (var i = 0; i < queuedOutput.length; ++i)
-            output(queuedOutput[i]);
-        nextTest();
-    }
-
-    webInspector.network.onRequestFinished.addListener(onRequestFinished);
-    webInspector.inspectedWindow.reload({ignoreCache: true, userAgent: "Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)"});
-}
-
-(function()
-{
-    var xhr = new XMLHttpRequest();
-    xhr.open("GET", "resources/xhr-exists.html", false);
-    xhr.send(null);
-})();
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests overriding user agent via WebInspector extension API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api-expected.txt
index fdec36f..0cf8c01 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api-expected.txt
@@ -1,3 +1,5 @@
+CONSOLE WARNING: line 31: network.onFinished is deprecated. Use network.onRequestFinished instead
+CONSOLE WARNING: line 31: webInspector.resources is deprecated. Use webInspector.network instead
 Tests public interface of WebInspector Extensions API
 
 Started extension.
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api.html
deleted file mode 100644
index 4bb44f1..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-function extension_testAPI(nextTest)
-{
-    dumpObject(webInspector);
-    nextTest();
-}
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests public interface of WebInspector Extensions API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api.js
new file mode 100644
index 0000000..0224526
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-api.js
@@ -0,0 +1,15 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.addResult(`Tests public interface of WebInspector Extensions API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testAPI(nextTest) {
+      dumpObject(webInspector);
+      nextTest();
+    }
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval-content-script.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval-content-script.html
deleted file mode 100644
index aa7b803..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval-content-script.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-
-window.whereAmI = "main world";
-
-testRunner.setIsolatedWorldSecurityOrigin(632, extensionsOrigin);
-testRunner.evaluateScriptInIsolatedWorld(632, "window.whereAmI = 'brave new world'");
-
-function extension_testEvalInMainWorldImplicit(nextTest)
-{
-    webInspector.inspectedWindow.eval("whereAmI", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalInMainWorldExplicit(nextTest)
-{
-    webInspector.inspectedWindow.eval("whereAmI", { useContentScriptContext: false }, callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalInContentScriptContext(nextTest)
-{
-    webInspector.inspectedWindow.eval("whereAmI", { useContentScriptContext: true }, callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_onEval(value, isException)
-{
-    output("Evaluate: " + JSON.stringify(value) + " (exception: " + isException + ")");
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval-content-script.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval-content-script.js
new file mode 100644
index 0000000..ca88861
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval-content-script.js
@@ -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.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.evaluateInPagePromise(`
+    window.whereAmI = "main world";
+
+    testRunner.setIsolatedWorldSecurityOrigin(632, "http://devtools-extensions.oopif.test:8000");
+    testRunner.evaluateScriptInIsolatedWorld(632, "window.whereAmI = 'brave new world'");
+  `);
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testEvalInMainWorldImplicit(nextTest) {
+      webInspector.inspectedWindow.eval("whereAmI", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalInMainWorldExplicit(nextTest) {
+      webInspector.inspectedWindow.eval("whereAmI", { useContentScriptContext: false }, callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalInContentScriptContext(nextTest) {
+      webInspector.inspectedWindow.eval("whereAmI", { useContentScriptContext: true }, callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_onEval(value, isException) {
+      output("Evaluate: " + JSON.stringify(value) + " (exception: " + isException + ")");
+    },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval.html
deleted file mode 100644
index 7956dc15..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-
-window.inspectedValue = { str: "foo", num: 42 };
-
-window.loop = { };
-window.loop.next = window.loop;
-
-function extension_testEvalOk(nextTest)
-{
-    webInspector.inspectedWindow.eval("inspectedValue", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalStringifyingLoopFailed(nextTest)
-{
-    webInspector.inspectedWindow.eval("window.loop", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalDefinesGlobalSymbols(nextTest)
-{
-    webInspector.inspectedWindow.eval("function extensionFunc() {}");
-    webInspector.inspectedWindow.eval("extensionVar = 42;");
-    webInspector.inspectedWindow.eval("({ func: typeof window.extensionFunc, variable: window.extensionVar })", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalStatement(nextTest)
-{
-    webInspector.inspectedWindow.eval("var x = 3; while (--x); x", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalUndefined(nextTest)
-{
-    webInspector.inspectedWindow.eval("undefined", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalConsoleAPI(nextTest)
-{
-    webInspector.inspectedWindow.eval("typeof inspect", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testWithStringifyOverridden(nextTest)
-{
-    webInspector.inspectedWindow.eval("(JSON.stringify = function() { throw 'oops! you can not use JSON.stringify'; }), 'OK'", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_testEvalThrows(nextTest)
-{
-    webInspector.inspectedWindow.eval("throw('testExceptionString')", callbackAndNextTest(extension_onEval, nextTest));
-}
-
-function extension_onEval(value, status)
-{
-    var exceptionString = typeof status === "undefined" ? "undefined" : JSON.stringify(status);
-    output("Evaluate: " + JSON.stringify(value) + " (exception: " + exceptionString + ")");
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval.js
new file mode 100644
index 0000000..bdcddee
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-eval.js
@@ -0,0 +1,55 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.evaluateInPagePromise(`
+    window.inspectedValue = { str: "foo", num: 42 };
+
+    window.loop = { };
+    window.loop.next = window.loop;
+  `);
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testEvalOk(nextTest) {
+      webInspector.inspectedWindow.eval("inspectedValue", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalStringifyingLoopFailed(nextTest) {
+      webInspector.inspectedWindow.eval("window.loop", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalDefinesGlobalSymbols(nextTest) {
+      webInspector.inspectedWindow.eval("function extensionFunc() {}");
+      webInspector.inspectedWindow.eval("extensionVar = 42;");
+      webInspector.inspectedWindow.eval("({ func: typeof window.extensionFunc, variable: window.extensionVar })", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalStatement(nextTest) {
+      webInspector.inspectedWindow.eval("var x = 3; while (--x); x", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalUndefined(nextTest) {
+      webInspector.inspectedWindow.eval("undefined", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalConsoleAPI(nextTest) {
+      webInspector.inspectedWindow.eval("typeof inspect", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testWithStringifyOverridden(nextTest) {
+      webInspector.inspectedWindow.eval("(JSON.stringify = function() { throw 'oops! you can not use JSON.stringify'; }), 'OK'", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalThrows(nextTest) {
+      webInspector.inspectedWindow.eval("throw('testExceptionString')", callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_onEval(value, status) {
+      var exceptionString = typeof status === "undefined" ? "undefined" : JSON.stringify(status);
+      output("Evaluate: " + JSON.stringify(value) + " (exception: " + exceptionString + ")");
+    },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events-expected.txt
index 76b95a9..455281f8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events-expected.txt
@@ -5,8 +5,6 @@
 RUNNING TEST: extension_testElementsOnSelectionChanged
 onSelectionChanged fired
 RUNNING TEST: extension_testOnNavigated
-Page reloaded.
-Page reloaded.
 Navigated to: extensions-events.html?navigated
 Navigated to: extensions-events.html
 RUNNING TEST: extension_testOnRequestFinished
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events.html
deleted file mode 100644
index e39a703..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events.html
+++ /dev/null
@@ -1,177 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script src="../../inspector/debugger-test.js"></script>
-<script src="resources/test-script.js"></script>
-<script type="text/javascript">
-
-function initialize_extensionsSidebarTest()
-{
-    InspectorTest.expandSidebar = function(callback)
-    {
-        var sidebar = InspectorTest._extensionSidebar();
-        TestRunner.deprecatedRunAfterPendingDispatches(function() {
-            sidebar.revealView();
-            callback();
-        });
-    }
-
-    InspectorTest._extensionSidebar = function()
-    {
-        return Extensions.extensionServer.sidebarPanes()[0];
-    }
-}
-
-function extension_expandSidebar(callback)
-{
-    evaluateOnFrontend("InspectorTest.expandSidebar(reply);", callback);
-}
-
-function extension_testElementsOnSelectionChanged(nextTest)
-{
-    function onSelectionChanged()
-    {
-        webInspector.panels.elements.onSelectionChanged.removeListener(onSelectionChanged);
-        output("onSelectionChanged fired");
-        nextTest();
-    }
-    webInspector.panels.elements.onSelectionChanged.addListener(onSelectionChanged);
-    webInspector.inspectedWindow.eval("inspect(document.body.children[0]), 0");
-}
-
-function extension_testSourcesOnSelectionChangedShowFile(nextTest)
-{
-    function onSelectionChanged(selectionInfo)
-    {
-        webInspector.panels.sources.onSelectionChanged.removeListener(onSelectionChanged);
-        output("sources onSelectionChanged fired, selectionInfo:");
-        dumpObject(selectionInfo, {url: "url"});
-        nextTest();
-    }
-    webInspector.panels.sources.onSelectionChanged.addListener(onSelectionChanged);
-    evaluateOnFrontend("InspectorTest.showScriptSource(\"test-script.js\")");
-}
-
-function extension_testSourcesOnSelectionChangedShowFileAndLine(nextTest)
-{
-    webInspector.inspectedWindow.eval("location.href", function(inspectedPageURL) {
-        function onSelectionChanged(selectionInfo)
-        {
-            webInspector.panels.sources.onSelectionChanged.removeListener(onSelectionChanged);
-            output("sources onSelectionChanged fired, selectionInfo:");
-            dumpObject(selectionInfo, {url: "url"});
-            nextTest();
-        }
-        webInspector.panels.sources.onSelectionChanged.addListener(onSelectionChanged);
-
-        var basePath = inspectedPageURL.replace(/\/[^/]*$/, "/");
-        webInspector.panels.openResource(basePath + "resources/test-script.js", 2);
-    });
-}
-
-function extension_testOnRequestFinished(nextTest)
-{
-    function onRequestFinished()
-    {
-        webInspector.network.onRequestFinished.removeListener(onRequestFinished);
-        output("onRequestFinished fired");
-        nextTest();
-    }
-    webInspector.network.onRequestFinished.addListener(onRequestFinished);
-    webInspector.inspectedWindow.eval("var xhr = new XMLHttpRequest(); xhr.open('GET', location.href, false); xhr.send(null);");
-}
-
-function extension_testOnNavigated(nextTest)
-{
-    var urls = [];
-    var loadCount = 0;
-
-    function onLoad()
-    {
-        ++loadCount;
-        processEvent();
-    }
-    function processEvent()
-    {
-        if (loadCount !== urls.length)
-            return;
-        if (loadCount === 1)
-            evaluateOnFrontend("TestRunner.navigate(TestRunner.mainTarget.inspectedURL().substring(0, TestRunner.mainTarget.inspectedURL().indexOf('?')), reply)", onLoad);
-        else {
-            webInspector.network.onNavigated.removeListener(onNavigated);
-            for (var i = 0; i < urls.length; ++i)
-                output("Navigated to: " + urls[i]);
-            nextTest();
-        }
-    }
-    function onNavigated(url)
-    {
-        urls.push(url.replace(/^(.*\/)*/, ""));
-        processEvent();
-    }
-    webInspector.network.onNavigated.addListener(onNavigated);
-    evaluateOnFrontend("TestRunner.navigate(TestRunner.mainTarget.inspectedURL() + '?navigated', reply)", onLoad);
-}
-
-function extension_testViewShowHide(nextTest)
-{
-    var listenersToCleanup = [];
-    var sidebar;
-    var beenToExtensionPanel = false;
-
-    function onViewEvent(type, viewName, viewWindow)
-    {
-        output("Got " + type + " event for " + viewName);
-        if (type !== "onShown")
-            return;
-        if (viewName === "panel") {
-            output("Panel shown, location: " + trimURL(viewWindow.location.href));
-            extension_showPanel("elements");
-        } else if (viewName === "sidebar") {
-            output("Sidebar shown, location: " + trimURL(viewWindow.location.href));
-            if (!beenToExtensionPanel) {
-                extension_showPanel("extension");
-                beenToExtensionPanel = true;
-            } else {
-                cleanupListeners();
-                nextTest();
-            }
-        }
-    }
-    function addListener(view, viewName, type)
-    {
-        var listener = bind(onViewEvent, null, type, viewName);
-        var event = view[type];
-        listenersToCleanup.push({ event: event, listener: listener });
-        event.addListener(listener);
-    }
-    function cleanupListeners()
-    {
-        for (var i = 0; i < listenersToCleanup.length; ++i)
-            listenersToCleanup[i].event.removeListener(listenersToCleanup[i].listener);
-    }
-    function onPanelCreated(panel)
-    {
-        addListener(panel, "panel", "onShown");
-        addListener(panel, "panel", "onHidden");
-        addListener(sidebar, "sidebar", "onHidden");
-        addListener(sidebar, "sidebar", "onShown");
-        sidebar.setPage(basePath + "extension-sidebar.html");
-    }
-    extension_showPanel("elements", extension_expandSidebar);
-    var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-    function onSidebarCreated(sidebarPane)
-    {
-        sidebar = sidebarPane;
-        webInspector.panels.create("Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
-    }
-    webInspector.panels.elements.createSidebarPane("Test Sidebar", onSidebarCreated);
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events.js
new file mode 100644
index 0000000..0164f1f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-events.js
@@ -0,0 +1,138 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.loadModule('sources_test_runner');
+  await TestRunner.showPanel('sources');
+  await TestRunner.navigatePromise(TestRunner.url('./resources/extensions-events.html'));
+
+  TestRunner.expandSidebar = function(callback) {
+    var sidebar = Extensions.extensionServer.sidebarPanes()[0];
+    sidebar.revealView().then(callback);
+  }
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testElementsOnSelectionChanged(nextTest) {
+      function onSelectionChanged() {
+        webInspector.panels.elements.onSelectionChanged.removeListener(onSelectionChanged);
+        output("onSelectionChanged fired");
+        nextTest();
+      }
+      webInspector.panels.elements.onSelectionChanged.addListener(onSelectionChanged);
+      webInspector.inspectedWindow.eval("inspect(document.body.children[0]), 0");
+    },
+
+    function extension_testSourcesOnSelectionChangedShowFile(nextTest) {
+      function onSelectionChanged(selectionInfo) {
+        webInspector.panels.sources.onSelectionChanged.removeListener(onSelectionChanged);
+        output("sources onSelectionChanged fired, selectionInfo:");
+        dumpObject(selectionInfo, {url: "url"});
+        nextTest();
+      }
+      webInspector.panels.sources.onSelectionChanged.addListener(onSelectionChanged);
+      evaluateOnFrontend("SourcesTestRunner.showScriptSourcePromise(\"test-script.js\")");
+    },
+
+    function extension_testSourcesOnSelectionChangedShowFileAndLine(nextTest) {
+      function onSelectionChanged(selectionInfo) {
+        webInspector.panels.sources.onSelectionChanged.removeListener(onSelectionChanged);
+        output("sources onSelectionChanged fired, selectionInfo:");
+        dumpObject(selectionInfo, {url: "url"});
+        nextTest();
+      }
+      webInspector.panels.sources.onSelectionChanged.addListener(onSelectionChanged);
+      webInspector.panels.openResource('http://127.0.0.1:8000/devtools/extensions/resources/test-script.js', 2);
+    },
+
+    function extension_testOnRequestFinished(nextTest) {
+      function onRequestFinished() {
+        webInspector.network.onRequestFinished.removeListener(onRequestFinished);
+        output("onRequestFinished fired");
+        nextTest();
+      }
+      webInspector.network.onRequestFinished.addListener(onRequestFinished);
+      webInspector.inspectedWindow.eval("var xhr = new XMLHttpRequest(); xhr.open('GET', location.href, false); xhr.send(null);");
+    },
+
+    function extension_testOnNavigated(nextTest) {
+      var urls = [];
+      var loadCount = 0;
+
+      function onLoad() {
+        ++loadCount;
+        processEvent();
+      }
+      function processEvent() {
+        if (loadCount !== urls.length)
+          return;
+        if (loadCount === 1)
+          evaluateOnFrontend("TestRunner.navigate(TestRunner.mainTarget.inspectedURL().substring(0, TestRunner.mainTarget.inspectedURL().indexOf('?')), reply)", onLoad);
+        else {
+          webInspector.network.onNavigated.removeListener(onNavigated);
+          for (var i = 0; i < urls.length; ++i)
+            output("Navigated to: " + urls[i]);
+          nextTest();
+        }
+      }
+      function onNavigated(url) {
+        urls.push(url.replace(/^(.*\/)*/, ""));
+        processEvent();
+      }
+      webInspector.network.onNavigated.addListener(onNavigated);
+      evaluateOnFrontend("TestRunner.navigate(TestRunner.mainTarget.inspectedURL() + '?navigated', reply)", onLoad);
+    },
+
+    function extension_testViewShowHide(nextTest) {
+      var listenersToCleanup = [];
+      var sidebar;
+      var beenToExtensionPanel = false;
+
+      function onViewEvent(type, viewName, viewWindow) {
+        output("Got " + type + " event for " + viewName);
+        if (type !== "onShown")
+          return;
+        if (viewName === "panel") {
+          output("Panel shown, location: " + trimURL(viewWindow.location.href));
+          extension_showPanel("elements");
+        } else if (viewName === "sidebar") {
+          output("Sidebar shown, location: " + trimURL(viewWindow.location.href));
+          if (!beenToExtensionPanel) {
+            extension_showPanel("extension");
+            beenToExtensionPanel = true;
+          } else {
+            cleanupListeners();
+            nextTest();
+          }
+        }
+      }
+      function addListener(view, viewName, type) {
+        var listener = bind(onViewEvent, null, type, viewName);
+        var event = view[type];
+        listenersToCleanup.push({ event: event, listener: listener });
+        event.addListener(listener);
+      }
+      function cleanupListeners() {
+        for (var i = 0; i < listenersToCleanup.length; ++i)
+          listenersToCleanup[i].event.removeListener(listenersToCleanup[i].listener);
+      }
+      function onPanelCreated(panel) {
+        addListener(panel, "panel", "onShown");
+        addListener(panel, "panel", "onHidden");
+        addListener(sidebar, "sidebar", "onHidden");
+        addListener(sidebar, "sidebar", "onShown");
+        sidebar.setPage(basePath + "extension-sidebar.html");
+      }
+      extension_showPanel("elements", callback => evaluateOnFrontend("TestRunner.expandSidebar(reply);", callback));
+
+      var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+      function onSidebarCreated(sidebarPane) {
+        sidebar = sidebarPane;
+        webInspector.panels.create("Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
+      }
+      webInspector.panels.elements.createSidebarPane("Test Sidebar", onSidebarCreated);
+    },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-headers-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-headers-expected.txt
similarity index 99%
rename from third_party/WebKit/LayoutTests/http/tests/devtools/extensions-headers-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-headers-expected.txt
index 3e67a161..8e0c34b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-headers-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-headers-expected.txt
@@ -1,9 +1,10 @@
 Tests WebInspector extension API
 
-HTTP_X_WEBINSPECTOR_EXTENSION: test
-HTTP_USER_AGENT: Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)
 Started extension.
 Running tests...
 RUNNING TEST: extension_testAddHeaders
+HTTP_X_WEBINSPECTOR_EXTENSION: test
+HTTP_USER_AGENT: Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)
+
 All tests done.
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-headers.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-headers.js
new file mode 100644
index 0000000..fd143d062
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-headers.js
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.loadHTML(`
+    <div style="white-space: pre" id="headers"></div>
+    <script>
+      function doXHR()
+      {
+          var xhr = new XMLHttpRequest();
+          xhr.open("GET", "../resources/echo-headers.php", false);
+          xhr.send(null);
+          return xhr.responseText;
+      }
+    </script>
+  `);
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testAddHeaders(nextTest) {
+      webInspector.network.addRequestHeaders({
+        "x-webinspector-extension": "test",
+        "user-agent": "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)"
+      });
+      function cleanUpHeaders(headers) {
+        output(headers);
+        webInspector.network.addRequestHeaders({
+          "x-webinspector-extension": null,
+          "user-agent": null
+        });
+      }
+      webInspector.inspectedWindow.eval("doXHR()", callbackAndNextTest(cleanUpHeaders, nextTest));
+    }
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-iframe-eval-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-iframe-eval-expected.txt
similarity index 70%
rename from third_party/WebKit/LayoutTests/http/tests/devtools/extensions-iframe-eval-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-iframe-eval-expected.txt
index 6bcf861..c3896af 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-iframe-eval-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-iframe-eval-expected.txt
@@ -1,6 +1,6 @@
+CONSOLE WARNING: line 8028: The JavaScript context bogus was not found in the frame http://127.0.0.1:8000/devtools/resources/extensions-frame-eval.html
 Tests WebInspector extension API
 
-
 Started extension.
 Running tests...
 RUNNING TEST: extension_testEvalInIFrame
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-iframe-eval.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-iframe-eval.js
new file mode 100644
index 0000000..d17b46e6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-iframe-eval.js
@@ -0,0 +1,35 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.loadHTML(`<iframe src="${TestRunner.url('../resources/extensions-frame-eval.html')}"></iframe>`);
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testEvalInIFrame(nextTest) {
+      var url = 'http://127.0.0.1:8000/devtools/resources/extensions-frame-eval.html';
+      var origin = "http://127.0.0.1:8000"
+      var options = {
+        frameURL: url
+      };
+      var loc = "window.location.pathname";
+      webInspector.inspectedWindow.eval(loc, options, callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_testEvalInIFrameBadOption(nextTest) {
+      var url = 'http://127.0.0.1:8000/devtools/resources/extensions-frame-eval.html';
+      var origin = "http://127.0.0.1:8000"
+      var options = {
+        frameURL: url,
+        scriptExecutionContext: "bogus"
+      };
+      var loc = "window.location.pathname";
+      webInspector.inspectedWindow.eval(loc, options, callbackAndNextTest(extension_onEval, nextTest));
+    },
+
+    function extension_onEval(value, isException) {
+      output("Evaluate: " + JSON.stringify(value) + " (exception: " + isException + ")");
+    }
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-ignore-cache-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-ignore-cache-expected.txt
similarity index 66%
rename from third_party/WebKit/LayoutTests/http/tests/devtools/extensions-ignore-cache-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-ignore-cache-expected.txt
index 59ea2d0..5d87710b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-ignore-cache-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-ignore-cache-expected.txt
@@ -1,13 +1,8 @@
-CONSOLE MESSAGE: line 1: Done.
-CONSOLE MESSAGE: line 1: Done.
-CONSOLE MESSAGE: line 1: Done.
 Tests ignoreCache flag of WebInspector.inspectedPage.reload()
 
 Started extension.
 Running tests...
 RUNNING TEST: extension_testIgnoreCache
-Page reloaded.
-Page reloaded.
 afterNormalReload === beforeReload
 afterNormalReload !== afterReloadWithIgnoreCache
 All tests done.
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-ignore-cache.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-ignore-cache.js
new file mode 100644
index 0000000..2c5e03b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-ignore-cache.js
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.addResult(`Tests ignoreCache flag of WebInspector.inspectedPage.reload()\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.navigatePromise('resources/random-script.html');
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testIgnoreCache(nextTest) {
+      var beforeReload;
+      var afterReloadWithIgnoreCache;
+      var afterNormalReload;
+
+      function onNormalReload() {
+        webInspector.inspectedWindow.eval("randomValue", function(value) {
+          afterNormalReload = value;
+          evaluateOnFrontend("TestRunner.waitForPageLoad(reply)", onReloadWithIgnoreCache);
+          webInspector.inspectedWindow.reload({ ignoreCache: true });
+        });
+      };
+
+      function onReloadWithIgnoreCache() {
+        webInspector.inspectedWindow.eval("randomValue", function(value) {
+          afterReloadWithIgnoreCache = value;
+          output("afterNormalReload " + (afterNormalReload === beforeReload ? "===" : "!==" ) + " beforeReload");
+          output("afterNormalReload " + (afterNormalReload === afterReloadWithIgnoreCache ? "===" : "!==" ) + " afterReloadWithIgnoreCache");
+          nextTest();
+        });
+      }
+
+      webInspector.inspectedWindow.eval("randomValue", function(value) {
+        beforeReload = value;
+        evaluateOnFrontend("TestRunner.waitForPageLoad(reply)", onNormalReload);
+        webInspector.inspectedWindow.reload();
+      });
+    }
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-expected.txt
index 074fe12..d383798 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-expected.txt
@@ -1,18 +1,13 @@
 Tests WebInspector extension API
 
- 
-Page reloaded.
 Started extension.
 Running tests...
 RUNNING TEST: extension_testGetHAR
-resource: http://127.0.0.1:8000/inspector/extensions-network-test.js
-resource: http://127.0.0.1:8000/inspector/extensions-test.js
-resource: http://127.0.0.1:8000/inspector/extensions/extensions-network.html
-resource: http://127.0.0.1:8000/inspector/extensions/extensions-network.html
-resource: http://127.0.0.1:8000/inspector/extensions/resources/abe.png
-resource: http://127.0.0.1:8000/inspector/extensions/resources/audits-style1.css
-resource: http://127.0.0.1:8000/inspector/extensions/resources/missing-image.png
-resource: http://127.0.0.1:8000/inspector/inspector-test.js
+resource: http://127.0.0.1:8000/devtools/extensions/resources/abe.png
+resource: http://127.0.0.1:8000/devtools/extensions/resources/audits-style1.css
+resource: http://127.0.0.1:8000/devtools/extensions/resources/extensions-network.html
+resource: http://127.0.0.1:8000/devtools/extensions/resources/extensions-network.html
+resource: http://127.0.0.1:8000/devtools/extensions/resources/missing-image.png
 resource: http://127.0.0.1:8000/resources/Ahem.ttf
 RUNNING TEST: extension_testGetRequestContent
 {
@@ -27,6 +22,6 @@
     1 : "base64"
 }
 RUNNING TEST: extension_testRequestNotification
-Request finished: .../inspector/extensions/extensions-network.html
+Request finished: .../extensions/resources/extensions-network.html
 All tests done.
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-network-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-redirect-expected.txt
similarity index 77%
rename from third_party/WebKit/LayoutTests/http/tests/devtools/extensions-network-redirect-expected.txt
rename to third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-redirect-expected.txt
index 8a328a3..df7f7b4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions-network-redirect-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-redirect-expected.txt
@@ -1,7 +1,5 @@
 Tests WebInspector extension API returns valid data for redirected resources
 
-
-Page reloaded.
 Started extension.
 Running tests...
 RUNNING TEST: extension_testGetRedirectRequestContent
@@ -11,10 +9,7 @@
 Finished request: http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true
 RUNNING TEST: extension_testRedirectRequestInHAR
 Requests in HAR:
-http://127.0.0.1:8000/devtools/extensions-network-redirect.html
-http://127.0.0.1:8000/inspector/extensions-network-test.js
-http://127.0.0.1:8000/inspector/extensions-test.js
-http://127.0.0.1:8000/inspector/inspector-test.js
+http://127.0.0.1:8000/devtools/extensions/resources/extensions-network-redirect.html
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?status=302
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-redirect.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-redirect.js
new file mode 100644
index 0000000..da32dbb9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network-redirect.js
@@ -0,0 +1,79 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API returns valid data for redirected resources\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.navigatePromise('resources/extensions-network-redirect.html');
+  ExtensionsTestRunner.runExtensionTests([
+      function extension_doRequest(force, callback)
+      {
+          function callbackWrapper(request)
+          {
+              var lastCallback = !request || /\?redirected=true$/.test(request.request.url);
+              if (lastCallback)
+                  webInspector.network.onRequestFinished.removeListener(callbackWrapper);
+              callback(request, lastCallback);
+          }
+          webInspector.network.onRequestFinished.addListener(callbackWrapper);
+          webInspector.inspectedWindow.eval("doRequest(" + force + ")", function(result) {
+              if (result)
+                  callbackWrapper(null);
+          });
+      },
+
+      function extension_testGetRedirectRequestContent(nextTest)
+      {
+          function onRequestFinished(request, lastCallback)
+          {
+              if (!lastCallback)
+                  return;
+              extension_getRequestByUrl([ /redirect-methods-result.php\?status=302$/ ], function(request) {
+                  request.getContent(onContent);
+              });
+          }
+          function onContent(content, encoding)
+          {
+              output("content: " + content + ", encoding: " + encoding);
+              nextTest();
+          }
+          extension_doRequest(false, onRequestFinished);
+      },
+
+      function extension_testRedirectRequestInHAR(nextTest)
+      {
+          function onRequestFinished(resource, lastCallback)
+          {
+              if (lastCallback)
+                  webInspector.network.getHAR(onHAR);
+          }
+          function onHAR(har)
+          {
+              var entries = har.entries;
+              var urls = [];
+              for (var i = 0; i < entries.length; ++i) {
+                  var url = entries[i].request.url;
+                  // Workaround for GTK DRT that requests favicon.ico along with the page.
+                  if (!/\/favicon\.ico$/.test(url))
+                      urls.push(url);
+              }
+              urls.sort();
+              output("Requests in HAR:\n" + urls.join("\n"));
+              nextTest();
+          }
+          extension_doRequest(false, onRequestFinished);
+      },
+
+      function extension_testRedirectRequestFinished(nextTest)
+      {
+          function onRequestFinished(request, lastCallback)
+          {
+              output("Finished request: " + request.request.url);
+              if (lastCallback)
+                  nextTest();
+          }
+          extension_doRequest(true, onRequestFinished);
+      },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network.html
deleted file mode 100644
index f2cb314..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<html>
-<head>
-<style>
-@font-face {
-    font-family: 'test';
-    src: url(../../resources/Ahem.ttf);
-}
-
-p { font-family: 'test'; }
-</style>
-
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script src="../../inspector/extensions-network-test.js"></script>
-<link rel="stylesheet" href="resources/audits-style1.css" type="text/css">
-<script type="text/javascript">
-
-function extension_testGetHAR(nextTest)
-{
-    function compareEntries(a, b)
-    {
-        return a.request.url.toLowerCase().localeCompare(b.request.url.toLowerCase());
-    }
-
-    function onHAR(result)
-    {
-        result.entries.sort(compareEntries);
-
-        for (var i = 0; i < result.entries.length; ++i)
-            output("resource: " + result.entries[i].request.url);
-    }
-    extension_doXHR(function() {
-        webInspector.network.getHAR(callbackAndNextTest(onHAR, nextTest));
-    });
-}
-
-function doXHR()
-{
-    return new Promise((fulfill) => {
-        var xhr = new XMLHttpRequest();
-        xhr.open("GET", "", true);
-        xhr.send(null);
-        xhr.onreadystatechange = () => {
-          if (xhr.readyState == 4 && xhr.status == 200)
-            fulfill();
-        };
-    });
-}
-
-function extension_doXHR(callback)
-{
-    invokePageFunctionAsync("doXHR", callback);
-}
-
-function extension_testRequestNotification(nextTest)
-{
-    function onRequestFinished(request)
-    {
-        output("Request finished: " + request.request.url.replace(/.*((\/[^/]*){3}$)/,"...$1"));
-    }
-
-    webInspector.network.onRequestFinished.addListener(callbackAndNextTest(onRequestFinished, nextTest));
-    extension_doXHR();
-}
-
-function extension_onRequestBody(content, encoding)
-{
-    dumpObject(Array.prototype.slice.call(arguments));
-}
-
-function extension_testGetRequestContent(nextTest)
-{
-    extension_getRequestByUrl([/audits-style1.css$/], function(request) {
-        request.getContent(callbackAndNextTest(extension_onRequestBody, nextTest));
-    });
-}
-
-function extension_testGetResourceContentEncoded(nextTest)
-{
-    extension_getRequestByUrl([/abe.png$/ ], function(request) {
-        request.getContent(callbackAndNextTest(extension_onRequestBody, nextTest));
-    });
-}
-
-var test = function() {
-  TestRunner.reloadPage(ExtensionsTestRunner.runExtensionTests);
-};
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API</p>
-<img src="resources/abe.png">
-<img src="resources/missing-image.png">
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network.js
new file mode 100644
index 0000000..fb31b2f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-network.js
@@ -0,0 +1,55 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.navigatePromise('resources/extensions-network.html');
+  ExtensionsTestRunner.runExtensionTests([
+    function extension_testGetHAR(nextTest) {
+      function compareEntries(a, b) {
+        return a.request.url.toLowerCase().localeCompare(b.request.url.toLowerCase());
+      }
+
+      function onHAR(result) {
+        result.entries.sort(compareEntries);
+
+        for (var i = 0; i < result.entries.length; ++i)
+            output("resource: " + result.entries[i].request.url);
+      }
+      extension_doXHR(function() {
+        webInspector.network.getHAR(callbackAndNextTest(onHAR, nextTest));
+      });
+    },
+
+    function extension_doXHR(callback) {
+      invokePageFunctionAsync("doXHR", callback);
+    },
+
+    function extension_testRequestNotification(nextTest) {
+      function onRequestFinished(request) {
+          output("Request finished: " + request.request.url.replace(/.*((\/[^/]*){3}$)/,"...$1"));
+      }
+
+      webInspector.network.onRequestFinished.addListener(callbackAndNextTest(onRequestFinished, nextTest));
+      extension_doXHR();
+    },
+
+    function extension_onRequestBody(content, encoding) {
+      dumpObject(Array.prototype.slice.call(arguments));
+    },
+
+    function extension_testGetRequestContent(nextTest) {
+      extension_getRequestByUrl([/audits-style1.css$/], function(request) {
+        request.getContent(callbackAndNextTest(extension_onRequestBody, nextTest));
+      });
+    },
+
+    function extension_testGetResourceContentEncoded(nextTest) {
+      extension_getRequestByUrl([/abe.png$/ ], function(request) {
+        request.getContent(callbackAndNextTest(extension_onRequestBody, nextTest));
+      });
+    }
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel-expected.txt
index 9e399864..c1427435 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel-expected.txt
@@ -1,7 +1,5 @@
-CONSOLE MESSAGE: line 12: hello
 Tests WebInspector extension API
 
-
 Started extension.
 Running tests...
 RUNNING TEST: extension_testCreatePanel
@@ -30,13 +28,13 @@
 Panel resized, test passed.
 RUNNING TEST: extension_testOpenResource
 Showing .../extensions-panel.html
-Showing resource .../devtools/extensions/extensions-panel.html in panel sources), line: 1001
+Showing resource .../extensions/resources/extensions-panel.html in panel sources), line: 1001
 Showing .../abe.png
 Showing resource .../extensions/resources/abe.png in panel sources), line: 1002
 Showing .../missing.txt
 Showing resource .../extensions/resources/missing.txt in panel network), line: undefined
-Showing not-found.html
-error: Extension server error: Object not found: not-found.html
+Showing .../not-found.html
+error: Extension server error: Object not found: http://127.0.0.1:8000/devtools/extensions/not-found.html
 Showing javascript:console.error('oh no!')
 error: Extension server error: Object not found: javascript:console.error('oh no!')
 RUNNING TEST: extension_testSearch
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel.html
deleted file mode 100644
index 36e6060..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel.html
+++ /dev/null
@@ -1,350 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/console-test.js"></script>
-<script src="../../inspector/network-test.js"></script>
-<script src="../../inspector/sources-test.js"></script>
-<script src="../../inspector/resources-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-function logMessage()
-{
-    console.log("hello");
-}
-
-function initialize_extensionsPanelTest()
-{
-    InspectorTest.getPanelSize = function()
-    {
-        var boundingRect = UI.inspectorView._tabbedPane._contentElement.getBoundingClientRect();
-        return {
-            width: boundingRect.width,
-            height: boundingRect.height
-        };
-    }
-
-    InspectorTest.dumpStatusBarButtons = function()
-    {
-        var panel = UI.inspectorView.currentPanelDeprecated();
-        var items = panel._panelToolbar._contentElement.children;
-        TestRunner.addResult("Status bar buttons state:");
-        for (var i = 0; i < items.length; ++i) {
-            var item = items[i];
-            if (item instanceof HTMLContentElement)
-                continue;
-            if (!(item instanceof HTMLButtonElement)) {
-                TestRunner.addResult("status bar item " + i + " is not a button: " + item);
-                continue;
-            }
-            // Strip url(...) and prefix of the URL within, leave just last 3 components.
-            var url = item.style.backgroundImage.replace(/^url\(.*(([/][^/]*){3}[^/)]*)\)$/, "...$1");
-            TestRunner.addResult("status bar item " + i + ", icon: \"" + url + ", tooltip: '" + item[UI.Tooltip._symbol].content + "', disabled: " + item.disabled);
-       }
-    }
-
-    InspectorTest.clickButton = function(index)
-    {
-        var panel = UI.inspectorView.currentPanelDeprecated();
-        var items = panel._panelToolbar._contentElement.children;
-        for (var i = 0, buttonIndex = 0; i < items.length; ++i) {
-            if (items[i] instanceof HTMLButtonElement) {
-                if (buttonIndex === index) {
-                    items[i].click();
-                    return;
-                }
-                buttonIndex++;
-            }
-        }
-        TestRunner.addResult("No button with index " + index);
-        items[index].click();
-    }
-
-    InspectorTest.logMessageAndClickOnURL = function()
-    {
-        ConsoleTestRunner.disableConsoleViewport();
-        TestRunner.evaluateInPage("logMessage()");
-        var wrappedConsoleMessageAdded = TestRunner.safeWrap(consoleMessageAdded);
-        ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded);
-
-        function consoleMessageAdded()
-        {
-            ConsoleModel.consoleModel.removeEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded);
-            Console.ConsoleView.instance()._invalidateViewport();
-            TestRunner.deprecatedRunAfterPendingDispatches(clickOnMessage)
-        }
-
-        function clickOnMessage()
-        {
-            var xpathResult = document.evaluate("//span[@class='devtools-link' and starts-with(., 'extensions-panel.html')]", Console.ConsoleView.instance()._viewport.element, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
-
-            var click = document.createEvent("MouseEvent");
-            click.initMouseEvent("click", true, true);
-            xpathResult.singleNodeValue.dispatchEvent(click);
-        }
-    }
-
-    InspectorTest.installShowResourceLocationHooks = function()
-    {
-        function showURL(panelName, url, lineNumber)
-        {
-            var url = url.replace(/^.*(([/][^/]*){3}[^/)]*)$/, "...$1");
-            TestRunner.addResult("Showing resource " + url + " in panel " + panelName + "), line: " + lineNumber);
-        }
-        NetworkTestRunner.recordNetwork();
-        TestRunner.addSniffer(UI.panels.sources, "showUILocation", showUILocationHook, true);
-        TestRunner.addSniffer(UI.panels.resources._sidebar, "showResource", showResourceHook, true);
-        TestRunner.addSniffer(UI.panels.network, "revealAndHighlightRequest", showRequestHook, true);
-
-        function showUILocationHook(uiLocation)
-        {
-            showURL("sources", uiLocation.uiSourceCode.url(), uiLocation.lineNumber);
-        }
-
-        function showResourceHook(resource, lineNumber)
-        {
-            showURL("resources", resource.url, lineNumber);
-        }
-
-        /**
-         * @param {!SDK.NetworkRequest} request
-         */
-        function showRequestHook(request)
-        {
-            showURL("network", request.url());
-        }
-    }
-
-    InspectorTest.switchToLastPanel = function()
-    {
-        var lastPanelName = UI.inspectorView._tabbedPane._tabs.peekLast().id;
-        return UI.inspectorView.showPanel(lastPanelName);
-    }
-}
-
-function extension_testThemeName(nextTest)
-{
-    output("Theme name: " + webInspector.panels.themeName);
-    nextTest();
-}
-
-function extension_testCreatePanel(nextTest)
-{
-    var expectOnShown = false;
-
-    function onPanelShown(panel, window)
-    {
-        if (!expectOnShown) {
-            output("FAIL: unexpected onShown event");
-            nextTest();
-            return;
-        }
-        output("Panel shown");
-        panel.onShown.removeListener(onPanelShown);
-        evaluateOnFrontend("reply(InspectorTest.getPanelSize())", function(result) {
-            if (result.width !== window.innerWidth)
-                output("panel width mismatch, outer: " + result.width + ", inner:" + window.innerWidth);
-            else if (result.height !== window.innerHeight)
-                output("panel height mismatch, outer: " + result.height + ", inner:" + window.innerHeight);
-            else
-                output("Extension panel size correct");
-            nextTest();
-        });
-    }
-
-    function onPanelCreated(panel)
-    {
-        function onPanelShown(window)
-        {
-            if (!expectOnShown) {
-                 output("FAIL: unexpected onShown event");
-                 nextTest();
-                 return;
-            }
-            output("Panel shown");
-            panel.onShown.removeListener(onPanelShown);
-            panel.onHidden.addListener(onPanelHidden);
-            evaluateOnFrontend("reply(InspectorTest.getPanelSize())", function(result) {
-                 if (result.width !== window.innerWidth)
-                     output("panel width mismatch, outer: " + result.width + ", inner:" + window.innerWidth);
-                 else if (result.height !== window.innerHeight)
-                     output("panel height mismatch, outer: " + result.height + ", inner:" + window.innerHeight);
-                 else
-                     output("Extension panel size correct");
-                 extension_showPanel("console");
-            });
-         }
-
-         function onPanelHidden()
-         {
-             panel.onHidden.removeListener(onPanelHidden);
-             output("Panel hidden");
-             nextTest();
-         }
-
-        output("Panel created");
-        dumpObject(panel);
-        panel.onShown.addListener(onPanelShown);
-
-        // This is not authorized and therefore should not produce any output
-        panel.show();
-        extension_showPanel("console");
-
-        function handleOpenResource(resource, lineNumber)
-        {
-            // This will force extension iframe to be really loaded.
-            panel.show();
-        }
-        webInspector.panels.setOpenResourceHandler(handleOpenResource);
-        evaluateOnFrontend("Components.Linkifier._linkHandlerSetting().set('test extension')");
-        evaluateOnFrontend("InspectorTest.logMessageAndClickOnURL();");
-        expectOnShown = true;
-    }
-    var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-    webInspector.panels.create("Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
-}
-
-function extension_testSearch(nextTest)
-{
-    var callbackCount = 0;
-
-    function onPanelCreated(panel)
-    {
-        var callback = function(action, queryString)
-        {
-            output("Panel searched:");
-            dumpObject(Array.prototype.slice.call(arguments));
-            callbackCount++;
-            if (callbackCount === 2) {
-                nextTest();
-                panel.onSearch.removeListener(callback);
-            }
-        };
-        panel.onSearch.addListener(callback);
-
-        extension_showPanel("extension");
-
-        function performSearch(query)
-        {
-            UI.inspectorView.panel(extensionsOrigin + "TestPanelforsearch").then(panel => {
-                panel.searchableView().showSearchField();
-                panel.searchableView()._searchInputElement.value = query;
-                panel.searchableView()._performSearch(true, true);
-                panel.searchableView().cancelSearch();
-            });
-        }
-
-        evaluateOnFrontend(performSearch.toString() + " performSearch(\"hello\");");
-    }
-    var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-    webInspector.panels.create("Test Panel for search", basePath + "extension-panel.png", basePath + "non-existent.html", onPanelCreated);
-}
-
-function extension_testStatusBarButtons(nextTest)
-{
-    var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-
-    function onPanelCreated(panel)
-    {
-        var button1 = panel.createStatusBarButton(basePath + "button1.png", "Button One tooltip");
-        var button2 = panel.createStatusBarButton(basePath + "button2.png", "Button Two tooltip", true);
-        output("Created a status bar button, dump follows:");
-        dumpObject(button1);
-        function updateButtons()
-        {
-            button1.update(basePath + "button1-updated.png");
-            button2.update(null, "Button Two updated tooltip", false);
-            output("Updated status bar buttons");
-            evaluateOnFrontend("InspectorTest.dumpStatusBarButtons(); InspectorTest.clickButton(1);");
-        }
-        button1.onClicked.addListener(function() {
-            output("button1 clicked");
-            evaluateOnFrontend("InspectorTest.dumpStatusBarButtons(); reply();", updateButtons);
-        });
-        button2.onClicked.addListener(function() {
-            output("button2 clicked");
-            nextTest();
-        });
-        // First we click on button2 (that is [1] in array). But it is disabled, so this should be a noop. Then we click on button1.
-        // button1 click updates buttons. and clicks button2.
-        evaluateOnFrontend("InspectorTest.showPanel('extension').then(function() { InspectorTest.clickButton(1); InspectorTest.clickButton(0); })");
-    }
-
-    webInspector.panels.create("Buttons Panel", basePath + "extension-panel.png", basePath + "non-existent.html", onPanelCreated);
-}
-
-function extension_testOpenResource(nextTest)
-{
-    var urls;
-    var urlIndex = 0;
-
-    evaluateOnFrontend("InspectorTest.installShowResourceLocationHooks(); reply();", function() {
-        webInspector.inspectedWindow.eval("loadResources(); location.href", function(inspectedPageURL) {
-            var basePath = inspectedPageURL.replace(/\/[^/]*$/, "/");
-            urls = [inspectedPageURL, basePath + "resources/abe.png", basePath + "resources/missing.txt", "not-found.html", "javascript:console.error('oh no!')"];
-            showNextURL();
-        });
-    });
-    function showNextURL()
-    {
-        if (urlIndex >= urls.length) {
-            nextTest();
-            return;
-        }
-        var url = urls[urlIndex++];
-        output("Showing " + trimURL(url));
-        webInspector.panels.openResource(url, 1000 + urlIndex, showNextURL);
-    }
-}
-
-function extension_testGlobalShortcuts(nextTest)
-{
-    var platform;
-    var testPanel;
-    evaluateOnFrontend("reply(Host.platform())", function(result) {
-        platform = result;
-        var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-        webInspector.panels.create("Shortcuts Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
-    });
-    function dispatchKeydownEvent(attributes)
-    {
-        var event = new KeyboardEvent("keydown", attributes);
-        document.dispatchEvent(event);
-    }
-    function onPanelCreated(panel)
-    {
-        testPanel = panel;
-        testPanel.onShown.addListener(onPanelShown);
-        evaluateOnFrontend("InspectorTest.switchToLastPanel();");
-    }
-    var panelWindow;
-    function onPanelShown(win)
-    {
-        panelWindow = win;
-        testPanel.onShown.removeListener(onPanelShown);
-        output("Panel shown, now toggling console...");
-        panelWindow.addEventListener("resize", onPanelResized);
-        dispatchKeydownEvent({ key: "Escape" });
-    }
-    function onPanelResized()
-    {
-        panelWindow.removeEventListener("resize", onPanelResized);
-        output("Panel resized, test passed.");
-        evaluateOnFrontend("reply(UI.inspectorView._closeDrawer())", nextTest);
-    }
-}
-
-function loadResources()
-{
-    var xhr = new XMLHttpRequest();
-    xhr.open("GET", "resources/missing.txt", false);
-    xhr.send();
-    var img = document.createElement("img");
-    img.src = "resources/abe.png";
-    document.body.appendChild(img);
-}
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests WebInspector extension API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel.js
new file mode 100644
index 0000000..4b65782
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-panel.js
@@ -0,0 +1,302 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests WebInspector extension API\n`);
+  await TestRunner.loadModule('console_test_runner');
+  await TestRunner.loadModule('network_test_runner');
+  await TestRunner.loadModule('sources_test_runner');
+  await TestRunner.loadModule('application_test_runner');
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.showPanel('network');
+  await TestRunner.showPanel('sources');
+  await TestRunner.showPanel('resources');
+  await TestRunner.navigatePromise('resources/extensions-panel.html');
+
+  TestRunner.getPanelSize = function() {
+    var boundingRect = UI.inspectorView._tabbedPane._contentElement.getBoundingClientRect();
+    return {
+      width: boundingRect.width,
+      height: boundingRect.height
+    };
+  }
+
+  TestRunner.dumpStatusBarButtons = function() {
+    var panel = UI.inspectorView.currentPanelDeprecated();
+    var items = panel._panelToolbar._contentElement.children;
+    TestRunner.addResult("Status bar buttons state:");
+    for (var i = 0; i < items.length; ++i) {
+      var item = items[i];
+      if (item instanceof HTMLContentElement)
+        continue;
+      if (!(item instanceof HTMLButtonElement)) {
+        TestRunner.addResult("status bar item " + i + " is not a button: " + item);
+        continue;
+      }
+      // Strip url(...) and prefix of the URL within, leave just last 3 components.
+      var url = item.style.backgroundImage.replace(/^url\(.*(([/][^/]*){3}[^/)]*)\)$/, "...$1");
+      TestRunner.addResult("status bar item " + i + ", icon: \"" + url + ", tooltip: '" + item[UI.Tooltip._symbol].content + "', disabled: " + item.disabled);
+    }
+  }
+
+  TestRunner.clickButton = function(index) {
+    var panel = UI.inspectorView.currentPanelDeprecated();
+    var items = panel._panelToolbar._contentElement.children;
+    for (var i = 0, buttonIndex = 0; i < items.length; ++i) {
+      if (items[i] instanceof HTMLButtonElement) {
+        if (buttonIndex === index) {
+          items[i].click();
+          return;
+        }
+        buttonIndex++;
+      }
+    }
+    TestRunner.addResult("No button with index " + index);
+    items[index].click();
+  }
+
+  TestRunner.logMessageAndClickOnURL = function() {
+    ConsoleTestRunner.disableConsoleViewport();
+    TestRunner.evaluateInPage("logMessage()");
+    var wrappedConsoleMessageAdded = TestRunner.safeWrap(consoleMessageAdded);
+    ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded);
+
+    function consoleMessageAdded() {
+      ConsoleModel.consoleModel.removeEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, wrappedConsoleMessageAdded);
+      Console.ConsoleView.instance()._invalidateViewport();
+      var xpathResult = document.evaluate("//span[@class='devtools-link' and starts-with(., 'extensions-panel.html')]", Console.ConsoleView.instance()._viewport.element, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
+
+      var click = document.createEvent("MouseEvent");
+      click.initMouseEvent("click", true, true);
+      xpathResult.singleNodeValue.dispatchEvent(click);
+    }
+  }
+
+  TestRunner.installShowResourceLocationHooks = function() {
+    function showURL(panelName, url, lineNumber) {
+      var url = url.replace(/^.*(([/][^/]*){3}[^/)]*)$/, "...$1");
+      TestRunner.addResult("Showing resource " + url + " in panel " + panelName + "), line: " + lineNumber);
+    }
+    NetworkTestRunner.recordNetwork();
+    TestRunner.addSniffer(UI.panels.sources, "showUILocation", showUILocationHook, true);
+    TestRunner.addSniffer(UI.panels.resources._sidebar, "showResource", showResourceHook, true);
+    TestRunner.addSniffer(UI.panels.network, "revealAndHighlightRequest", showRequestHook, true);
+
+    function showUILocationHook(uiLocation) {
+      showURL("sources", uiLocation.uiSourceCode.url(), uiLocation.lineNumber);
+    }
+
+    function showResourceHook(resource, lineNumber) {
+      showURL("resources", resource.url, lineNumber);
+    }
+
+    /**
+     * @param {!SDK.NetworkRequest} request
+     */
+    function showRequestHook(request) {
+      showURL("network", request.url());
+    }
+  }
+
+  TestRunner.switchToLastPanel = function() {
+    var lastPanelName = UI.inspectorView._tabbedPane._tabs.peekLast().id;
+    return UI.inspectorView.showPanel(lastPanelName);
+  }
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testThemeName(nextTest) {
+      output("Theme name: " + webInspector.panels.themeName);
+      nextTest();
+    },
+
+    function extension_testCreatePanel(nextTest) {
+      var expectOnShown = false;
+
+      function onPanelShown(panel, window) {
+        if (!expectOnShown) {
+          output("FAIL: unexpected onShown event");
+          nextTest();
+          return;
+        }
+        output("Panel shown");
+        panel.onShown.removeListener(onPanelShown);
+        evaluateOnFrontend("reply(TestRunner.getPanelSize())", function(result) {
+          if (result.width !== window.innerWidth)
+            output("panel width mismatch, outer: " + result.width + ", inner:" + window.innerWidth);
+          else if (result.height !== window.innerHeight)
+            output("panel height mismatch, outer: " + result.height + ", inner:" + window.innerHeight);
+          else
+            output("Extension panel size correct");
+          nextTest();
+        });
+      }
+
+      function onPanelCreated(panel) {
+        function onPanelShown(window) {
+          if (!expectOnShown) {
+             output("FAIL: unexpected onShown event");
+             nextTest();
+             return;
+          }
+          output("Panel shown");
+          panel.onShown.removeListener(onPanelShown);
+          panel.onHidden.addListener(onPanelHidden);
+          evaluateOnFrontend("reply(TestRunner.getPanelSize())", function(result) {
+            if (result.width !== window.innerWidth)
+              output("panel width mismatch, outer: " + result.width + ", inner:" + window.innerWidth);
+            else if (result.height !== window.innerHeight)
+              output("panel height mismatch, outer: " + result.height + ", inner:" + window.innerHeight);
+            else
+              output("Extension panel size correct");
+            extension_showPanel("console");
+          });
+        }
+
+        function onPanelHidden() {
+          panel.onHidden.removeListener(onPanelHidden);
+          output("Panel hidden");
+          nextTest();
+        }
+
+        output("Panel created");
+        dumpObject(panel);
+        panel.onShown.addListener(onPanelShown);
+
+        // This is not authorized and therefore should not produce any output
+        panel.show();
+        extension_showPanel("console");
+
+        function handleOpenResource(resource, lineNumber) {
+          // This will force extension iframe to be really loaded.
+          panel.show();
+        }
+        webInspector.panels.setOpenResourceHandler(handleOpenResource);
+        evaluateOnFrontend("Components.Linkifier._linkHandlerSetting().set('test extension')");
+        evaluateOnFrontend("TestRunner.logMessageAndClickOnURL();");
+        expectOnShown = true;
+      }
+      var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+      webInspector.panels.create("Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
+    },
+
+    function extension_testSearch(nextTest) {
+      var callbackCount = 0;
+
+      function onPanelCreated(panel) {
+        var callback = function(action, queryString) {
+          output("Panel searched:");
+          dumpObject(Array.prototype.slice.call(arguments));
+          callbackCount++;
+          if (callbackCount === 2) {
+            nextTest();
+            panel.onSearch.removeListener(callback);
+          }
+        };
+        panel.onSearch.addListener(callback);
+
+        extension_showPanel("extension");
+
+        function performSearch(query) {
+          UI.inspectorView.panel(extensionsOrigin + "TestPanelforsearch").then(panel => {
+            panel.searchableView().showSearchField();
+            panel.searchableView()._searchInputElement.value = query;
+            panel.searchableView()._performSearch(true, true);
+            panel.searchableView().cancelSearch();
+          });
+        }
+
+        evaluateOnFrontend(performSearch.toString() + " performSearch(\"hello\");");
+      }
+      var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+      webInspector.panels.create("Test Panel for search", basePath + "extension-panel.png", basePath + "non-existent.html", onPanelCreated);
+    },
+
+    function extension_testStatusBarButtons(nextTest) {
+      var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+
+      function onPanelCreated(panel) {
+        var button1 = panel.createStatusBarButton(basePath + "button1.png", "Button One tooltip");
+        var button2 = panel.createStatusBarButton(basePath + "button2.png", "Button Two tooltip", true);
+        output("Created a status bar button, dump follows:");
+        dumpObject(button1);
+        function updateButtons() {
+          button1.update(basePath + "button1-updated.png");
+          button2.update(null, "Button Two updated tooltip", false);
+          output("Updated status bar buttons");
+          evaluateOnFrontend("TestRunner.dumpStatusBarButtons(); TestRunner.clickButton(1);");
+        }
+        button1.onClicked.addListener(function() {
+          output("button1 clicked");
+          evaluateOnFrontend("TestRunner.dumpStatusBarButtons(); reply();", updateButtons);
+        });
+        button2.onClicked.addListener(function() {
+          output("button2 clicked");
+          nextTest();
+        });
+        // First we click on button2 (that is [1] in array). But it is disabled, so this should be a noop. Then we click on button1.
+        // button1 click updates buttons. and clicks button2.
+        evaluateOnFrontend("ExtensionsTestRunner.showPanel('extension').then(function() { TestRunner.clickButton(1); TestRunner.clickButton(0); })");
+      }
+
+      webInspector.panels.create("Buttons Panel", basePath + "extension-panel.png", basePath + "non-existent.html", onPanelCreated);
+    },
+
+    function extension_testOpenResource(nextTest) {
+      var urls = [
+        'http://127.0.0.1:8000/devtools/extensions/resources/extensions-panel.html',
+        'http://127.0.0.1:8000/devtools/extensions/resources/abe.png',
+        'http://127.0.0.1:8000/devtools/extensions/resources/missing.txt',
+        'http://127.0.0.1:8000/devtools/extensions/not-found.html',
+        "javascript:console.error('oh no!')"
+      ];
+
+      var urlIndex = 0;
+
+      evaluateOnFrontend("TestRunner.installShowResourceLocationHooks(); reply();", function() {
+        webInspector.inspectedWindow.eval("loadResources();", showNextURL);
+      });
+      function showNextURL() {
+        if (urlIndex >= urls.length) {
+          nextTest();
+          return;
+        }
+        var url = urls[urlIndex++];
+        output("Showing " + trimURL(url));
+        webInspector.panels.openResource(url, 1000 + urlIndex, showNextURL);
+      }
+    },
+
+    function extension_testGlobalShortcuts(nextTest) {
+      var platform;
+      var testPanel;
+      evaluateOnFrontend("reply(Host.platform())", function(result) {
+        platform = result;
+        var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+        webInspector.panels.create("Shortcuts Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
+      });
+      function dispatchKeydownEvent(attributes) {
+        var event = new KeyboardEvent("keydown", attributes);
+        document.dispatchEvent(event);
+      }
+      function onPanelCreated(panel) {
+        testPanel = panel;
+        testPanel.onShown.addListener(onPanelShown);
+        evaluateOnFrontend("TestRunner.switchToLastPanel();");
+      }
+      var panelWindow;
+      function onPanelShown(win) {
+        panelWindow = win;
+        testPanel.onShown.removeListener(onPanelShown);
+        output("Panel shown, now toggling console...");
+        panelWindow.addEventListener("resize", onPanelResized);
+        dispatchKeydownEvent({ key: "Escape" });
+      }
+      function onPanelResized() {
+        panelWindow.removeEventListener("resize", onPanelResized);
+        output("Panel resized, test passed.");
+        evaluateOnFrontend("reply(UI.inspectorView._closeDrawer())", nextTest);
+      }
+    },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload-expected.txt
index c6e31bf..cf2c9abe 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: line 1: 42
 Tests that webInspector.inspectedWindow.reload() successfully injects and preprocesses user's code upon reload
 
 Started extension.
@@ -11,6 +10,6 @@
 RUNNING TEST: extension_testReloadInjectsCodeWithMessage
 Page reloaded.
 Source received:
-(function(){console.log(42)})()
+console.log(42)
 All tests done.
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload.html
deleted file mode 100644
index 5d2a78a..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload.html
+++ /dev/null
@@ -1,94 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/debugger-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script src="../../inspector/console-test.js"></script>
-<script type="text/javascript">
-
-window.bar = "foo = " + window.foo;
-
-function extension_testReloadInjectsCode(nextTest)
-{
-    var valueWithInjectedCode;
-
-    function onPageWithInjectedCodeLoaded()
-    {
-        webInspector.inspectedWindow.eval("window.bar", function(value) {
-            valueWithInjectedCode = value;
-            evaluateOnFrontend("TestRunner.runWhenPageLoads(reply)", onPageWithoutInjectedCodeLoaded);
-            webInspector.inspectedWindow.reload();
-        });
-    }
-    function onPageWithoutInjectedCodeLoaded()
-    {
-        webInspector.inspectedWindow.eval("window.bar", function(value) {
-            output("With injected code: " + valueWithInjectedCode);
-            output("Without injected code: " + value);
-            nextTest();
-        });
-    }
-    evaluateOnFrontend("TestRunner.runWhenPageLoads(reply)", onPageWithInjectedCodeLoaded);
-    webInspector.inspectedWindow.reload({
-        injectedScript: "window.foo = 42;"
-    });
-}
-
-function initialize_testReloadInjectsCodeWithMessage()
-{
-    InspectorTest.lastMessageScriptId = function(callback)
-    {
-        var consoleView = Console.ConsoleView.instance();
-        if (consoleView._needsFullUpdate)
-            consoleView._updateMessageList();
-        var viewMessages = consoleView._visibleViewMessages;
-        if (viewMessages.length !== 1)
-            callback(null);
-        var uiMessage = viewMessages[viewMessages.length - 1];
-        var message = uiMessage.consoleMessage();
-        if (!message.stackTrace)
-            callback(null);
-        callback(message.stackTrace.callFrames[0].scriptId);
-    }
-    InspectorTest.getScriptSource = async function(scriptId, callback)
-    {
-        var source = await TestRunner.DebuggerAgent.getScriptSource(scriptId);
-        callback(source);
-    }
-}
-
-function extension_testReloadInjectsCodeWithMessage(nextTest)
-{
-    var valueWithInjectedCode;
-
-    function onPageWithInjectedCodeLoaded()
-    {
-        evaluateOnFrontend("InspectorTest.lastMessageScriptId(reply);", onScriptIdReceived);
-    }
-
-    function onScriptIdReceived(scriptId)
-    {
-        if (!scriptId) {
-            output("Script ID unavailable");
-            nextTest();
-        } else {
-            evaluateOnFrontend("InspectorTest.getScriptSource(\"" + scriptId + "\", reply);", function(source) {
-                output("Source received:");
-                output(source);
-                nextTest();
-            });
-        }
-    }
-
-    evaluateOnFrontend("TestRunner.runWhenPageLoads(reply)", onPageWithInjectedCodeLoaded);
-    webInspector.inspectedWindow.reload({
-        injectedScript: "console.log(42)"
-    });
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests that webInspector.inspectedWindow.reload() successfully injects and preprocesses user's code upon reload</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload.js
new file mode 100644
index 0000000..ce54ee85f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-reload.js
@@ -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.
+
+(async function() {
+  TestRunner.addResult(
+      `Tests that webInspector.inspectedWindow.reload() successfully injects and preprocesses user's code upon reload\n`);
+  await TestRunner.loadModule('sources_test_runner');
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.loadModule('console_test_runner');
+  await TestRunner.navigatePromise(TestRunner.url('resources/reload.html'));
+
+  TestRunner.lastMessageScriptId = function(callback) {
+    var consoleView = Console.ConsoleView.instance();
+    if (consoleView._needsFullUpdate)
+      consoleView._updateMessageList();
+    var viewMessages = consoleView._visibleViewMessages;
+    if (viewMessages.length !== 1)
+      callback(null);
+    var uiMessage = viewMessages[viewMessages.length - 1];
+    var message = uiMessage.consoleMessage();
+    if (!message.stackTrace)
+      callback(null);
+    callback(message.stackTrace.callFrames[0].scriptId);
+  }
+  TestRunner.getScriptSource = async function(scriptId, callback) {
+    var source = await TestRunner.DebuggerAgent.getScriptSource(scriptId);
+    callback(source);
+  }
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testReloadInjectsCode(nextTest) {
+      var injectedValue;
+
+      function onPageWithInjectedCodeLoaded() {
+        webInspector.inspectedWindow.eval("window.bar", function(value) {
+          injectedValue = value;
+          evaluateOnFrontend("TestRunner.reloadPage(reply)", onPageWithoutInjectedCodeLoaded);
+        });
+      }
+      function onPageWithoutInjectedCodeLoaded() {
+        webInspector.inspectedWindow.eval("window.bar", function(value) {
+          output("With injected code: " + injectedValue);
+          output("Without injected code: " + value);
+          nextTest();
+        });
+      }
+      var injectedScript = "window.foo = 42;"
+      evaluateOnFrontend(`TestRunner.reloadPageWithInjectedScript("${injectedScript}", reply)`, onPageWithInjectedCodeLoaded);
+    },
+
+    function extension_testReloadInjectsCodeWithMessage(nextTest) {
+      function onPageWithInjectedCodeLoaded() {
+        evaluateOnFrontend("TestRunner.lastMessageScriptId(reply);", onScriptIdReceived);
+      }
+
+      function onScriptIdReceived(scriptId) {
+        if (!scriptId) {
+          output("Script ID unavailable");
+          nextTest();
+        } else {
+          evaluateOnFrontend("TestRunner.getScriptSource(\"" + scriptId + "\", reply);", function(source) {
+            output("Source received:");
+            output(source);
+            nextTest();
+          });
+        }
+      }
+
+      var injectedScript = "console.log(42)";
+      evaluateOnFrontend(`TestRunner.reloadPageWithInjectedScript("${injectedScript}", reply)`, onPageWithInjectedCodeLoaded);
+    }
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources-expected.txt
index 80460674..d6958a7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources-expected.txt
@@ -1,7 +1,5 @@
-CONSOLE MESSAGE: line 3: don't panic!
 Tests resource-related methods of WebInspector extension API
 
-
 Started extension.
 Running tests...
 RUNNING TEST: extension_testGetAllResources
@@ -24,11 +22,17 @@
             getContent : <function>
             setContent : <function>
             type : "document"
-            url : .../subframe.html
+            url : .../inspected-page.html
         }
         3 : {
             getContent : <function>
             setContent : <function>
+            type : "document"
+            url : .../subframe.html
+        }
+        4 : {
+            getContent : <function>
+            setContent : <function>
             type : "script"
             url : .../test-script.js
         }
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources.html
deleted file mode 100644
index f1c1bffb..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources.html
+++ /dev/null
@@ -1,215 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/console-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script src="../../inspector/debugger-test.js"></script>
-<script type="text/javascript">
-function loadFrame()
-{
-    var callback;
-    var promise = new Promise((fulfill) => callback = fulfill);
-    var iframe = document.createElement("iframe");
-    iframe.src = "resources/subframe.html";
-    iframe.addEventListener("load", callback);
-    document.body.appendChild(iframe);
-    return promise;
-}
-
-function logMessage()
-{
-    frames[0].logMessage();
-}
-
-function initialize_ExtensionResourceTests()
-{
-
-InspectorTest.clickOnURL = function()
-{
-    UI.viewManager.showView("console").then(() => {
-        Console.ConsoleView.instance()._updateMessageList();
-        var xpathResult = document.evaluate("//span[@class='devtools-link' and starts-with(., 'test-script.js')]",
-                                            Console.ConsoleView.instance().element, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
-
-        var click = document.createEvent("MouseEvent");
-        click.initMouseEvent("click", true, true);
-        xpathResult.singleNodeValue.dispatchEvent(click);
-    });
-}
-
-InspectorTest.waitForStyleSheetChangedEvent = function(reply)
-{
-    var originalSetTimeout = Common.Throttler.prototype._setTimeout;
-    Common.Throttler.prototype._setTimeout = innerSetTimeout;
-    TestRunner.addSniffer(SDK.CSSModel.prototype, "_fireStyleSheetChanged", onStyleSheetChanged);
-
-    function onStyleSheetChanged()
-    {
-        Common.Throttler.prototype._setTimeout = originalSetTimeout;
-        reply();
-    }
-
-    function innerSetTimeout(operation, timeout)
-    {
-        return originalSetTimeout.call(this, operation, 0);
-    }
-}
-
-}
-
-function extension_testGetAllResources(nextTest)
-{
-    function callback(resources)
-    {
-        // For some reason scripts from tests previously run in the same test shell sometimes appear, so we need to filter them out.
-        var resourceURLsWhiteList = ["subframe.html", "abe.png", "audits-style1.css", "test-script.js"];
-        function filter(resource)
-        {
-            for (var i = 0; i < resourceURLsWhiteList.length; ++i) {
-                if (resource.url.indexOf(resourceURLsWhiteList[i]) !== -1) {
-                    resourceURLsWhiteList.splice(i, 1);
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        function compareResources(a, b)
-        {
-            return trimURL(a.url).localeCompare(trimURL(b.url));
-        }
-        resources = resources.filter(filter);
-        resources.sort(compareResources);
-        output("page resources:");
-        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
-    }
-    invokePageFunctionAsync("loadFrame", function() {
-        webInspector.inspectedWindow.getResources(callbackAndNextTest(callback, nextTest));
-    });
-}
-
-function extension_runWithResource(regexp, callback)
-{
-    function onResources(resources)
-    {
-       for (var i = 0; i < resources.length; ++i) {
-           if (regexp.test(resources[i].url)) {
-               callback(resources[i])
-               return;
-           }
-       }
-       throw "Failed to find a resource: " + regexp.toString();
-    }
-    webInspector.inspectedWindow.getResources(onResources);
-}
-
-function extension_testGetResourceContent(nextTest)
-{
-    function onContent()
-    {
-        dumpObject(Array.prototype.slice.call(arguments));
-    }
-    extension_runWithResource(/test-script\.js$/, function(resource) {
-        resource.getContent(callbackAndNextTest(onContent, nextTest));
-    });
-}
-
-function extension_testSetResourceContent(nextTest)
-{
-    evaluateOnFrontend("InspectorTest.waitForStyleSheetChangedEvent(reply);", step2);
-
-    extension_runWithResource(/audits-style1\.css$/, function(resource) {
-        resource.setContent("div.test { width: 126px; height: 42px; }", false, function() {});
-    });
-
-    function step2()
-    {
-        webInspector.inspectedWindow.eval("frames[0].document.getElementById('test-div').clientWidth", function(result) {
-            output("div.test width after stylesheet edited (should be 126): " + result);
-            nextTest();
-        });
-    }
-}
-
-function extension_testOnContentCommitted(nextTest)
-{
-    var expected_content = "div.test { width: 220px; height: 42px; }";
-
-    webInspector.inspectedWindow.onResourceContentCommitted.addListener(onContentCommitted);
-    extension_runWithResource(/audits-style1\.css$/, function(resource) {
-        resource.setContent("div.test { width: 140px; height: 42px; }", false);
-    });
-    // The next step is going to produce a console message that will be logged, so synchronize the output now.
-    evaluateOnFrontend("TestRunner.deprecatedRunAfterPendingDispatches(reply)", function() {
-        extension_runWithResource(/abe\.png$/, function(resource) {
-            resource.setContent("", true);
-        });
-        extension_runWithResource(/audits-style1\.css$/, function(resource) {
-            resource.setContent(expected_content, true);
-        });
-    });
-
-    function onContentCommitted(resource, content)
-    {
-        output("content committed for resource " + trimURL(resource.url) + " (type: " + resource.type + "), new content: " + content);
-        if (!/audits-style1\.css$/.test(resource.url) || content !== expected_content)
-            output("FAIL: stray onContentEdited event");
-        webInspector.inspectedWindow.onResourceContentCommitted.removeListener(onContentCommitted);
-        resource.getContent(function(content) {
-            output("Revision content: " + content);
-            nextTest();
-        });
-    }
-}
-
-function extension_testOnResourceAdded(nextTest)
-{
-    evaluateOnFrontend("SourcesTestRunner.startDebuggerTest(reply);", step2);
-
-    function step2()
-    {
-        webInspector.inspectedWindow.onResourceAdded.addListener(onResourceAdded);
-        webInspector.inspectedWindow.eval("addResource()");
-    }
-
-    function onResourceAdded(resource)
-    {
-        if (resource.url.indexOf("test_func") === -1)
-            return;
-        output("resource added:");
-        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
-        webInspector.inspectedWindow.onResourceAdded.removeListener(onResourceAdded);
-
-        evaluateOnFrontend("SourcesTestRunner.resumeExecution(reply);", nextTest);
-    }
-}
-
-function extension_testOpenResourceHandler(nextTest)
-{
-    function handleOpenResource(resource, lineNumber)
-    {
-        output("handleOpenResource() invoked [this should only appear once!]: ");
-        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
-        webInspector.panels.setOpenResourceHandler(null);
-        evaluateOnFrontend("InspectorTest.clickOnURL(); reply()", nextTest);
-    }
-    webInspector.panels.setOpenResourceHandler(handleOpenResource);
-    webInspector.inspectedWindow.eval("logMessage()", function() {
-        evaluateOnFrontend("InspectorTest.clickOnURL();");
-        evaluateOnFrontend("Components.Linkifier._linkHandlerSetting().set('test extension'); InspectorTest.clickOnURL();");
-    });
-}
-
-function addResource()
-{
-    var script = document.createElement("script");
-    script.src = "data:application/javascript," + escape("function test_func(){};");
-    document.head.appendChild(script);
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests resource-related methods of WebInspector extension API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources.js
new file mode 100644
index 0000000..3de11b5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-resources.js
@@ -0,0 +1,161 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests resource-related methods of WebInspector extension API\n`);
+  await TestRunner.loadModule('console_test_runner');
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.loadModule('sources_test_runner');
+
+  TestRunner.clickOnURL = function() {
+    UI.viewManager.showView("console").then(() => {
+      Console.ConsoleView.instance()._updateMessageList();
+      var xpathResult = document.evaluate("//span[@class='devtools-link' and starts-with(., 'test-script.js')]",
+                                          Console.ConsoleView.instance().element, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
+
+      var click = document.createEvent("MouseEvent");
+      click.initMouseEvent("click", true, true);
+      xpathResult.singleNodeValue.dispatchEvent(click);
+    });
+  }
+
+  TestRunner.waitForStyleSheetChangedEvent = function(reply) {
+    TestRunner.addSniffer(SDK.CSSModel.prototype, "_fireStyleSheetChanged", reply);
+  }
+
+  await TestRunner.evaluateInPageAnonymously(`
+    function loadFrame() {
+      var callback;
+      var promise = new Promise((fulfill) => callback = fulfill);
+      var iframe = document.createElement("iframe");
+      iframe.src = "resources/subframe.html";
+      iframe.addEventListener("load", callback);
+      document.body.appendChild(iframe);
+      return promise;
+    }
+
+    function logMessage() {
+      frames[0].logMessage();
+    }
+
+    function addResource() {
+      var script = document.createElement("script");
+      script.src = "data:application/javascript," + escape("function test_func(){};");
+      document.head.appendChild(script);
+    }
+  `);
+
+  ExtensionsTestRunner.evaluateInExtension(function extension_runWithResource(regexp, callback) {
+    function onResources(resources) {
+      for (var i = 0; i < resources.length; ++i) {
+        if (regexp.test(resources[i].url)) {
+          callback(resources[i])
+          return;
+        }
+      }
+      throw "Failed to find a resource: " + regexp.toString();
+    }
+    webInspector.inspectedWindow.getResources(onResources);
+  });
+
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testGetAllResources(nextTest) {
+      function callback(resources) {
+        resources.sort((a, b) => trimURL(a.url).localeCompare(trimURL(b.url)));
+        output("page resources:");
+        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
+      }
+      invokePageFunctionAsync("loadFrame", function() {
+        webInspector.inspectedWindow.getResources(callbackAndNextTest(callback, nextTest));
+      });
+    },
+
+    function extension_testGetResourceContent(nextTest) {
+      function onContent() {
+        dumpObject(Array.prototype.slice.call(arguments));
+      }
+      extension_runWithResource(/test-script\.js$/, function(resource) {
+        resource.getContent(callbackAndNextTest(onContent, nextTest));
+      });
+    },
+
+    function extension_testSetResourceContent(nextTest) {
+      evaluateOnFrontend("TestRunner.waitForStyleSheetChangedEvent(reply);", step2);
+
+      extension_runWithResource(/audits-style1\.css$/, function(resource) {
+        resource.setContent("div.test { width: 126px; height: 42px; }", false, function() {});
+      });
+
+      function step2() {
+        webInspector.inspectedWindow.eval("frames[0].document.getElementById('test-div').clientWidth", function(result) {
+          output("div.test width after stylesheet edited (should be 126): " + result);
+          nextTest();
+        });
+      }
+    },
+
+    function extension_testOnContentCommitted(nextTest) {
+      var expected_content = "div.test { width: 220px; height: 42px; }";
+
+      webInspector.inspectedWindow.onResourceContentCommitted.addListener(onContentCommitted);
+      extension_runWithResource(/audits-style1\.css$/, function(resource) {
+        resource.setContent("div.test { width: 140px; height: 42px; }", false);
+      });
+      // The next step is going to produce a console message that will be logged, so synchronize the output now.
+      evaluateOnFrontend("TestRunner.deprecatedRunAfterPendingDispatches(reply)", function() {
+        extension_runWithResource(/abe\.png$/, function(resource) {
+          resource.setContent("", true);
+        });
+        extension_runWithResource(/audits-style1\.css$/, function(resource) {
+          resource.setContent(expected_content, true);
+        });
+      });
+
+      function onContentCommitted(resource, content) {
+        output("content committed for resource " + trimURL(resource.url) + " (type: " + resource.type + "), new content: " + content);
+        if (!/audits-style1\.css$/.test(resource.url) || content !== expected_content)
+          output("FAIL: stray onContentEdited event");
+        webInspector.inspectedWindow.onResourceContentCommitted.removeListener(onContentCommitted);
+        resource.getContent(function(content) {
+          output("Revision content: " + content);
+          nextTest();
+        });
+      }
+    },
+
+    function extension_testOnResourceAdded(nextTest) {
+      evaluateOnFrontend("SourcesTestRunner.startDebuggerTest(reply);", step2);
+
+      function step2() {
+        webInspector.inspectedWindow.onResourceAdded.addListener(onResourceAdded);
+        webInspector.inspectedWindow.eval("addResource()");
+      }
+
+      function onResourceAdded(resource) {
+        if (resource.url.indexOf("test_func") === -1)
+          return;
+        output("resource added:");
+        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
+        webInspector.inspectedWindow.onResourceAdded.removeListener(onResourceAdded);
+
+        evaluateOnFrontend("SourcesTestRunner.resumeExecution(reply);", nextTest);
+      }
+    },
+
+    function extension_testOpenResourceHandler(nextTest) {
+      function handleOpenResource(resource, lineNumber) {
+        output("handleOpenResource() invoked [this should only appear once!]: ");
+        dumpObject(Array.prototype.slice.call(arguments), { url: "url" });
+        webInspector.panels.setOpenResourceHandler(null);
+        evaluateOnFrontend("TestRunner.clickOnURL(); reply()", nextTest);
+      }
+      webInspector.panels.setOpenResourceHandler(handleOpenResource);
+      webInspector.inspectedWindow.eval("logMessage()", function() {
+        evaluateOnFrontend("TestRunner.clickOnURL();");
+        evaluateOnFrontend("Components.Linkifier._linkHandlerSetting().set('test extension'); TestRunner.clickOnURL();");
+      });
+    },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar-expected.txt
index 1ceacec..983efa0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar-expected.txt
@@ -6,7 +6,7 @@
 Got onShown(), frame defined
 Got onShown(), frame not defined
 RUNNING TEST: extension_testElementsSidebarSetExpression
-elements sidebar content: titlef0: "expression"f1: undefinedf2: nullf3: {}f4: []f5: (3) ["aa", "bb", "cc"]f6: {f60: 42, f61: "foo", f62: Array(0)}f7: 42f8: Foo {bar: 1}f9: [p]f10: ƒ ()f11: "foo"__proto__: Object
+elements sidebar content: titlef0: "expression"f1: undefinedf2: nullf3: {}f4: []f5: (3) ["aa", "bb", "cc"]f6: {f60: 42, f61: "foo", f62: Array(0)}f7: 42f8: Foo {bar: 1}f9: HTMLCollection []f10: ƒ ()f11: "foo"__proto__: Object
 RUNNING TEST: extension_testElementsSidebarSetObject
 Watch sidebar created, callback arguments dump follows:
 {
@@ -47,7 +47,7 @@
 Got onShown(), frame defined
 Got onShown(), frame not defined
 RUNNING TEST: extension_testSourcesSidebarSetExpression
-sources sidebar content: titlef0: "expression"f1: undefinedf2: nullf3: {}f4: []f5: (3) ["aa", "bb", "cc"]f6: {f60: 42, f61: "foo", f62: Array(0)}f7: 42f8: Foo {bar: 1}f9: [p]f10: ƒ ()__proto__: Object
+sources sidebar content: titlef0: "expression"f1: undefinedf2: nullf3: {}f4: []f5: (3) ["aa", "bb", "cc"]f6: {f60: 42, f61: "foo", f62: Array(0)}f7: 42f8: Foo {bar: 1}f9: HTMLCollection []f10: ƒ ()__proto__: Object
 RUNNING TEST: extension_testSourcesSidebarSetExpressionOnShown
 setExpression onShown frame: undefined
 RUNNING TEST: extension_testSourcesSidebarSetObject
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar.html
deleted file mode 100644
index df753da..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar.html
+++ /dev/null
@@ -1,245 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-
-function initialize_extensionsSidebarTest()
-{
-    InspectorTest.dumpSidebarContent = function(panelName, callback)
-    {
-        var sidebar = InspectorTest._extensionSidebar(panelName);
-        TestRunner.deprecatedRunAfterPendingDispatches(function() {
-            TestRunner.addResult(panelName + " sidebar content: " + TestRunner.textContentWithoutStyles(sidebar.element));
-            callback();
-        });
-    }
-
-    InspectorTest.expandSidebar = function(panelName, callback)
-    {
-        var sidebar = InspectorTest._extensionSidebar(panelName);
-        TestRunner.deprecatedRunAfterPendingDispatches(function() {
-            sidebar.revealView();
-            callback();
-        });
-    }
-
-    InspectorTest._extensionSidebar = function(panelName)
-    {
-        var sidebarPanes = Extensions.extensionServer.sidebarPanes();
-        var result;
-        for (var i = 0; i < sidebarPanes.length; ++i) {
-            if (sidebarPanes[i].panelName() === panelName)
-                result = sidebarPanes[i];
-        }
-        return result;
-    }
-}
-
-function extension_sidebarSetPage(panelName, nextTest)
-{
-    function onSidebarCreated(sidebar)
-    {
-        output("Sidebar created");
-        dumpObject(sidebar);
-        function onShown(win)
-        {
-            if (panelName !== "elements")
-                output("sidebar height " + win.document.documentElement.getBoundingClientRect().height);
-            sidebar.onShown.removeListener(onShown);
-            nextTest();
-        }
-        sidebar.onShown.addListener(onShown);
-        var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-        sidebar.setPage(basePath + "extension-sidebar.html");
-        extension_showPanel(panelName, extension_expandSidebar.bind(null, panelName));
-    }
-    output("Call createSidebarPane for " + panelName);
-    webInspector.panels[panelName].createSidebarPane("Test Sidebar", onSidebarCreated);
-}
-
-function extension_testElementsSidebarSetPage(nextTest)
-{
-    extension_sidebarSetPage("elements", nextTest);
-}
-
-function extension_testSourcesSidebarSetPage(nextTest)
-{
-    extension_sidebarSetPage("sources", nextTest);
-}
-
-function extension_dumpSidebarContent(panelName, nextTest)
-{
-    evaluateOnFrontend("InspectorTest.dumpSidebarContent(\"" + panelName + "\", reply);", nextTest);
-}
-
-function extension_expandSidebar(panelName, callback)
-{
-    evaluateOnFrontend("InspectorTest.expandSidebar(\"" + panelName + "\", reply);", callback);
-}
-
-function extension_testElementsSidebarSetObject(nextTest)
-{
-    extension_sideBarSetObject("elements", nextTest);
-}
-
-function extension_testSourcesSidebarSetObject(nextTest)
-{
-    extension_sideBarSetObject("sources", nextTest);
-}
-
-function extension_sideBarSetObject (panelName, nextTest)
-{
-    function onSidebarCreated(sidebar)
-    {
-        output("Watch sidebar created, callback arguments dump follows:");
-        dumpObject(Array.prototype.slice.call(arguments));
-        sidebar.setObject({
-            f0: "object",
-            f1: undefined,
-            f2: null,
-            f3: {},
-            f4: [],
-            f5: ["aa", "bb", "cc"],
-            f6: { f60: 42, f61: "foo", f62: [] },
-            f7: 42
-        }, null, extension_dumpSidebarContent.bind(this, panelName, nextTest));
-    }
-    webInspector.panels[panelName].createSidebarPane("Watch Test: Object", onSidebarCreated);
-}
-
-function extension_testSourcesSidebarSetExpressionOnShown(nextTest)
-{
-    function onSidebarCreated(sidebar)
-    {
-        function onShown(frame)
-        {
-            output("setExpression onShown frame: " + frame);
-            sidebar.onShown.removeListener(onShown);
-            nextTest();
-        }
-        sidebar.onShown.addListener(onShown);
-        function onSetExpression()
-        {
-            extension_showPanel("elements", extension_expandSidebar.bind(null, "elements"));
-        }
-        sidebar.setExpression("(window.nothing_here)", "title", onSetExpression);
-    }
-    webInspector.panels.elements.createSidebarPane("OnShown without setExpression", onSidebarCreated);
-}
-
-function extension_testElementsSidebarSetExpression(nextTest)
-{
-    var panelName = "elements";
-    function onSidebarCreated(sidebar)
-    {
-        function expression()
-        {
-            document.body.testProperty = 'foo';
-            function Foo() {};
-            var fooInstance = new Foo();
-            fooInstance.bar = 1;
-            return {
-                f0: 'expression',
-                f1: undefined,
-                f2: null,
-                f3: {},
-                f4: [],
-                f5: ["aa", "bb", "cc"],
-                f6: { f60: 42, f61: "foo", f62: [] },
-                f7: 42,
-                f8: fooInstance,
-                f9: document.body.children,
-                f10: function() {},
-                f11: $0.testProperty
-            };
-        }
-        // Do an extra round-trip to the inspected page to assure inspect()'s round-trip to
-        // front-end is complete and $0 is properly updated with currently inspected node.
-        webInspector.inspectedWindow.eval("undefined", function() {
-            sidebar.setExpression("(" + expression.toString() + ")();", "title", extension_dumpSidebarContent.bind(this, panelName, nextTest));
-        });
-    }
-    webInspector.inspectedWindow.eval("inspect(document.body)", function() {
-        webInspector.panels.elements.createSidebarPane("Watch Test: Expression", onSidebarCreated);
-    });
-}
-
-function extension_testSourcesSidebarSetExpression(nextTest)
-{
-    var panelName = "sources";
-
-    function onSidebarExpanded(sidebar) {
-        function expression()
-        {
-            function Foo() {};
-            var fooInstance = new Foo();
-            fooInstance.bar = 1;
-            return {
-                f0: 'expression',
-                f1: undefined,
-                f2: null,
-                f3: {},
-                f4: [],
-                f5: ["aa", "bb", "cc"],
-                f6: { f60: 42, f61: "foo", f62: [] },
-                f7: 42,
-                f8: fooInstance,
-                f9: document.body.children,
-                f10: function() {},
-            };
-        }
-        sidebar.setExpression("(" + expression.toString() + ")();", "title", extension_dumpSidebarContent.bind(this, panelName, nextTest));
-    }
-
-    function onSidebarCreated(sidebar)
-    {
-        extension_showPanel(panelName, extension_expandSidebar.bind(this, panelName, onSidebarExpanded.bind(null, sidebar)));
-    }
-
-    webInspector.panels.sources.createSidebarPane("Watch Test: Expression", onSidebarCreated);
-}
-
-function extension_testElementsSidebarPageReplacedWithObject(nextTest)
-{
-    extension_sidebarPageReplacedWithObject("elements", nextTest);
-}
-
-function extension_testSourcesSidebarPageReplacedWithObject(nextTest)
-{
-    extension_sidebarPageReplacedWithObject("sources", nextTest);
-}
-
-function extension_sidebarPageReplacedWithObject(panelName, nextTest)
-{
-     var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-     var sidebar;
-
-     function onSidebarCreated(aSidebar)
-     {
-         sidebar = aSidebar;
-         sidebar.onShown.addListener(onShown);
-         sidebar.setPage(basePath + "extension-sidebar.html");
-         extension_showPanel(panelName, extension_expandSidebar.bind(this, panelName));
-     }
-     var didSetObject = false;
-     function onShown(frame)
-     {
-         output("Got onShown(), frame " + (frame ? "defined" : "not defined"));
-         if (!didSetObject) {
-             didSetObject = true;
-             sidebar.setObject({ foo: 'bar' });
-         } else {
-            sidebar.onShown.removeListener(onShown);
-            nextTest();
-         }
-     }
-     webInspector.panels[panelName].createSidebarPane("Sidebar Test: replace page with object", onSidebarCreated);
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests sidebars in WebInspector extensions API</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar.js
new file mode 100644
index 0000000..24074c95
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-sidebar.js
@@ -0,0 +1,211 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests sidebars in WebInspector extensions API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+
+  TestRunner.dumpSidebarContent = function(panelName, callback) {
+    var sidebar = TestRunner._extensionSidebar(panelName);
+    TestRunner.deprecatedRunAfterPendingDispatches(function() {
+      TestRunner.addResult(panelName + " sidebar content: " + TestRunner.textContentWithoutStyles(sidebar.element));
+      callback();
+    });
+  }
+
+  TestRunner.expandSidebar = function(panelName, callback) {
+    var sidebar = TestRunner._extensionSidebar(panelName);
+    TestRunner.deprecatedRunAfterPendingDispatches(function() {
+      sidebar.revealView();
+      callback();
+    });
+  }
+
+  TestRunner._extensionSidebar = function(panelName) {
+    var sidebarPanes = Extensions.extensionServer.sidebarPanes();
+    var result;
+    for (var i = 0; i < sidebarPanes.length; ++i) {
+      if (sidebarPanes[i].panelName() === panelName)
+        result = sidebarPanes[i];
+    }
+    return result;
+  }
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_sidebarSetPage(panelName, nextTest) {
+      function onSidebarCreated(sidebar) {
+        output("Sidebar created");
+        dumpObject(sidebar);
+        function onShown(win) {
+          if (panelName !== "elements")
+            output("sidebar height " + win.document.documentElement.getBoundingClientRect().height);
+          sidebar.onShown.removeListener(onShown);
+          nextTest();
+        }
+        sidebar.onShown.addListener(onShown);
+        var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+        sidebar.setPage(basePath + "extension-sidebar.html");
+        extension_showPanel(panelName, extension_expandSidebar.bind(null, panelName));
+      }
+      output("Call createSidebarPane for " + panelName);
+      webInspector.panels[panelName].createSidebarPane("Test Sidebar", onSidebarCreated);
+    },
+
+    function extension_testElementsSidebarSetPage(nextTest) {
+      extension_sidebarSetPage("elements", nextTest);
+    },
+
+    function extension_testSourcesSidebarSetPage(nextTest) {
+      extension_sidebarSetPage("sources", nextTest);
+    },
+
+    function extension_dumpSidebarContent(panelName, nextTest) {
+      evaluateOnFrontend("TestRunner.dumpSidebarContent(\"" + panelName + "\", reply);", nextTest);
+    },
+
+    function extension_expandSidebar(panelName, callback) {
+      evaluateOnFrontend("TestRunner.expandSidebar(\"" + panelName + "\", reply);", callback);
+    },
+
+    function extension_testElementsSidebarSetObject(nextTest) {
+      extension_sideBarSetObject("elements", nextTest);
+    },
+
+    function extension_testSourcesSidebarSetObject(nextTest) {
+      extension_sideBarSetObject("sources", nextTest);
+    },
+
+    function extension_sideBarSetObject (panelName, nextTest) {
+      function onSidebarCreated(sidebar) {
+        output("Watch sidebar created, callback arguments dump follows:");
+        dumpObject(Array.prototype.slice.call(arguments));
+        sidebar.setObject({
+          f0: "object",
+          f1: undefined,
+          f2: null,
+          f3: {},
+          f4: [],
+          f5: ["aa", "bb", "cc"],
+          f6: { f60: 42, f61: "foo", f62: [] },
+          f7: 42
+        }, null, extension_dumpSidebarContent.bind(this, panelName, nextTest));
+      }
+      webInspector.panels[panelName].createSidebarPane("Watch Test: Object", onSidebarCreated);
+    },
+
+    function extension_testSourcesSidebarSetExpressionOnShown(nextTest) {
+      function onSidebarCreated(sidebar) {
+        function onShown(frame) {
+          output("setExpression onShown frame: " + frame);
+          sidebar.onShown.removeListener(onShown);
+          nextTest();
+        }
+        sidebar.onShown.addListener(onShown);
+        function onSetExpression() {
+          extension_showPanel("elements", extension_expandSidebar.bind(null, "elements"));
+        }
+        sidebar.setExpression("(window.nothing_here)", "title", onSetExpression);
+      }
+      webInspector.panels.elements.createSidebarPane("OnShown without setExpression", onSidebarCreated);
+    },
+
+    function extension_testElementsSidebarSetExpression(nextTest) {
+      var panelName = "elements";
+      function onSidebarCreated(sidebar) {
+        function expression() {
+          document.body.testProperty = 'foo';
+          function Foo() {};
+          var fooInstance = new Foo();
+          fooInstance.bar = 1;
+          return {
+            f0: 'expression',
+            f1: undefined,
+            f2: null,
+            f3: {},
+            f4: [],
+            f5: ["aa", "bb", "cc"],
+            f6: { f60: 42, f61: "foo", f62: [] },
+            f7: 42,
+            f8: fooInstance,
+            f9: document.body.children,
+            f10: function() {},
+            f11: $0.testProperty
+          };
+        }
+        // Do an extra round-trip to the inspected page to assure inspect()'s round-trip to
+        // front-end is complete and $0 is properly updated with currently inspected node.
+        webInspector.inspectedWindow.eval("undefined", function() {
+          sidebar.setExpression("(" + expression.toString() + ")();", "title", extension_dumpSidebarContent.bind(this, panelName, nextTest));
+        });
+      }
+      webInspector.inspectedWindow.eval("inspect(document.body)", function() {
+        webInspector.panels.elements.createSidebarPane("Watch Test: Expression", onSidebarCreated);
+      });
+    },
+
+    function extension_testSourcesSidebarSetExpression(nextTest) {
+      var panelName = "sources";
+
+      function onSidebarExpanded(sidebar) {
+        function expression() {
+          function Foo() {};
+          var fooInstance = new Foo();
+          fooInstance.bar = 1;
+          return {
+            f0: 'expression',
+            f1: undefined,
+            f2: null,
+            f3: {},
+            f4: [],
+            f5: ["aa", "bb", "cc"],
+            f6: { f60: 42, f61: "foo", f62: [] },
+            f7: 42,
+            f8: fooInstance,
+            f9: document.body.children,
+            f10: function() {},
+          };
+        }
+        sidebar.setExpression("(" + expression.toString() + ")();", "title", extension_dumpSidebarContent.bind(this, panelName, nextTest));
+      }
+
+      function onSidebarCreated(sidebar) {
+        extension_showPanel(panelName, extension_expandSidebar.bind(this, panelName, onSidebarExpanded.bind(null, sidebar)));
+      }
+
+      webInspector.panels.sources.createSidebarPane("Watch Test: Expression", onSidebarCreated);
+    },
+
+    function extension_testElementsSidebarPageReplacedWithObject(nextTest) {
+      extension_sidebarPageReplacedWithObject("elements", nextTest);
+    },
+
+    function extension_testSourcesSidebarPageReplacedWithObject(nextTest) {
+      extension_sidebarPageReplacedWithObject("sources", nextTest);
+    },
+
+    function extension_sidebarPageReplacedWithObject(panelName, nextTest) {
+      var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+      var sidebar;
+
+      function onSidebarCreated(aSidebar) {
+        sidebar = aSidebar;
+        sidebar.onShown.addListener(onShown);
+        sidebar.setPage(basePath + "extension-sidebar.html");
+        extension_showPanel(panelName, extension_expandSidebar.bind(this, panelName));
+      }
+      var didSetObject = false;
+      function onShown(frame) {
+        output("Got onShown(), frame " + (frame ? "defined" : "not defined"));
+        if (!didSetObject) {
+          didSetObject = true;
+          sidebar.setObject({ foo: 'bar' });
+        } else {
+          sidebar.onShown.removeListener(onShown);
+          nextTest();
+        }
+      }
+      webInspector.panels[panelName].createSidebarPane("Sidebar Test: replace page with object", onSidebarCreated);
+    },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api-expected.txt
index d920e90..2f1b6db1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api-expected.txt
@@ -1,6 +1,4 @@
-Tests timeline support in WebInspector Extensions API
-
- Started extension.
+Started extension.
 Running tests...
 RUNNING TEST: extension_testTimeline
 TraceProvider:
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api.html
deleted file mode 100644
index 3fba3eb..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script src="../../inspector/timeline-test.js"></script>
-
-<script type="text/javascript">
-function initialize_timelineExtensionTest()
-{
-
-InspectorTest.enableTimelineExtensionAndStart = function(callback) {
-    const provider = Extensions.extensionServer.traceProviders().peekLast();
-    const timelinePanel = UI.panels.timeline;
-    const setting = Timeline.TimelinePanel._settingForTraceProvider(provider);
-    setting.set(true);
-    TestRunner.addResult(`Provider short display name: ${provider.shortDisplayName()}`);
-    TestRunner.addResult(`Provider long display name: ${provider.longDisplayName()}`);
-    PerformanceTestRunner.startTimeline().then(callback);
-}
-
-}
-
-function extension_testTimeline(nextTest)
-{
-    var session;
-    var sessionTimeOffset;
-    var startTime;
-
-    function onRecordingStarted(s)
-    {
-        sessionTimeOffset = (Date.now() - performance.now()) * 1000;
-        startTime = performance.now();
-        output("traceProvider.onRecordingStarted fired.");
-        output("TracingSession:");
-        dumpObject(s);
-        session = s;
-     }
-
-     function onRecordingStopped()
-     {
-        output("traceProvider.onRecordingStopped fired.");
-
-        const endTime = performance.now();
-        var pid = 1;
-        var tid = 1;
-        var step = (endTime - startTime) * 1000 / 10;
-        var start = startTime * 1000;
-        var data = { "traceEvents": [
-            {"name": "Extension record X 1", "ts": start, "dur": step * 4, "ph": "X", "args": {},  "tid": tid, "pid": pid, "cat":"" },
-            {"name": "Extension record X 2", "ts": start + step * 5, "dur": step * 5, "ph": "X", "args": {},  "tid": tid, "pid": pid, "cat":"" },
-            {"name": "Extension record I 1", "ts": start + step * 5.5, "ph": "I", "args": {},  "tid": tid, "pid": pid, "cat":"" },
-            {"name": "Extension record B+E", "ts": start + step * 6, "ph": "B", "args": {}, "tid": tid, "pid": pid, "cat":"" },
-            {"name": "Extension record B+E", "ts": start + step * 10, "ph": "E", "args": {}, "tid": tid, "pid": pid, "cat":"" }
-        ]};
-        var url = "data:application/json," + escape(JSON.stringify(data));
-        session.complete(url, sessionTimeOffset);
-    }
-
-    var traceProvider = webInspector.timeline.addTraceProvider("extension trace provider", "long extension name");
-    output("TraceProvider:");
-    dumpObject(traceProvider);
-    traceProvider.onRecordingStarted.addListener(onRecordingStarted);
-    traceProvider.onRecordingStopped.addListener(onRecordingStopped);
-    extension_startTimeline(
-        () => extension_stopTimeline(
-            () => extension_dumpFlameChart(nextTest)));
-}
-
-function extension_startTimeline(callback)
-{
-    evaluateOnFrontend("InspectorTest.enableTimelineExtensionAndStart(reply);", callback);
-}
-
-function extension_stopTimeline(callback)
-{
-    evaluateOnFrontend("PerformanceTestRunner.stopTimeline().then(reply);", callback);
-}
-
-function extension_dumpFlameChart(callback)
-{
-    evaluateOnFrontend("PerformanceTestRunner.dumpTimelineFlameChart(['long extension name']); reply()", callback);
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests timeline support in WebInspector Extensions API</p>
-<span id="test-element"><b></b></span>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api.js
new file mode 100644
index 0000000..493ddfe3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-timeline-api.js
@@ -0,0 +1,76 @@
+// 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.
+
+(async function() {
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.loadModule('performance_test_runner');
+  await TestRunner.showPanel('timeline');
+
+  TestRunner.enableTimelineExtensionAndStart = function(callback) {
+    const provider = Extensions.extensionServer.traceProviders().peekLast();
+    const timelinePanel = UI.panels.timeline;
+    const setting = Timeline.TimelinePanel._settingForTraceProvider(provider);
+    setting.set(true);
+    TestRunner.addResult(`Provider short display name: ${provider.shortDisplayName()}`);
+    TestRunner.addResult(`Provider long display name: ${provider.longDisplayName()}`);
+    PerformanceTestRunner.startTimeline().then(callback);
+  }
+
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testTimeline(nextTest) {
+      var session;
+      var sessionTimeOffset;
+      var startTime;
+
+      function onRecordingStarted(s) {
+        sessionTimeOffset = (Date.now() - performance.now()) * 1000;
+        startTime = performance.now();
+        output("traceProvider.onRecordingStarted fired.");
+        output("TracingSession:");
+        dumpObject(s);
+        session = s;
+       }
+
+      function onRecordingStopped() {
+        output("traceProvider.onRecordingStopped fired.");
+
+        const endTime = performance.now();
+        var pid = 1;
+        var tid = 1;
+        var step = (endTime - startTime) * 1000 / 10;
+        var start = startTime * 1000;
+        var data = { "traceEvents": [
+            {"name": "Extension record X 1", "ts": start, "dur": step * 4, "ph": "X", "args": {},  "tid": tid, "pid": pid, "cat":"" },
+            {"name": "Extension record X 2", "ts": start + step * 5, "dur": step * 5, "ph": "X", "args": {},  "tid": tid, "pid": pid, "cat":"" },
+            {"name": "Extension record I 1", "ts": start + step * 5.5, "ph": "I", "args": {},  "tid": tid, "pid": pid, "cat":"" },
+            {"name": "Extension record B+E", "ts": start + step * 6, "ph": "B", "args": {}, "tid": tid, "pid": pid, "cat":"" },
+            {"name": "Extension record B+E", "ts": start + step * 10, "ph": "E", "args": {}, "tid": tid, "pid": pid, "cat":"" }
+        ]};
+        var url = "data:application/json," + escape(JSON.stringify(data));
+        session.complete(url, sessionTimeOffset);
+      }
+
+      var traceProvider = webInspector.timeline.addTraceProvider("extension trace provider", "long extension name");
+      output("TraceProvider:");
+      dumpObject(traceProvider);
+      traceProvider.onRecordingStarted.addListener(onRecordingStarted);
+      traceProvider.onRecordingStopped.addListener(onRecordingStopped);
+      extension_startTimeline(
+          () => extension_stopTimeline(
+              () => extension_dumpFlameChart(nextTest)));
+    },
+
+    function extension_startTimeline(callback) {
+      evaluateOnFrontend("TestRunner.enableTimelineExtensionAndStart(reply);", callback);
+    },
+
+    function extension_stopTimeline(callback) {
+      evaluateOnFrontend("PerformanceTestRunner.stopTimeline().then(reply);", callback);
+    },
+
+    function extension_dumpFlameChart(callback) {
+      evaluateOnFrontend("PerformanceTestRunner.dumpTimelineFlameChart(['long extension name']); reply()", callback);
+    },
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-useragent-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-useragent-expected.txt
new file mode 100644
index 0000000..7ec07a2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-useragent-expected.txt
@@ -0,0 +1,10 @@
+Tests overriding user agent via WebInspector extension API
+
+Started extension.
+Running tests...
+RUNNING TEST: extension_testUserAgent
+user-agent header for extensions-useragent.html: Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)
+user-agent header for xhr-exists.html: Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)
+navigator.userAgent: Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)
+All tests done.
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-useragent.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-useragent.js
new file mode 100644
index 0000000..40890b256
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/extensions-useragent.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.
+
+(async function() {
+  TestRunner.addResult(`Tests overriding user agent via WebInspector extension API\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+  await TestRunner.navigatePromise('resources/extensions-useragent.html');
+  await ExtensionsTestRunner.runExtensionTests([
+    function extension_testUserAgent(nextTest)
+    {
+        const requestsToCheck = [
+            "extensions-useragent.html",
+            "xhr-exists.html"
+        ];
+        var requestCount = 0;
+        var queuedOutput = [];
+
+        function onRequestFinished(request)
+        {
+            var url = request.request.url.replace(/^.*[/]/, "");
+            if (requestsToCheck.indexOf(url) < 0)
+                return;
+
+            queuedOutput.push("user-agent header for " + url + ": " + getHeader(request.request.headers, "user-agent"));
+            if (++requestCount < requestsToCheck.length)
+                return;
+            webInspector.network.onRequestFinished.removeListener(onRequestFinished);
+            webInspector.inspectedWindow.eval("navigator.userAgent", onEval);
+        }
+        function getHeader(headers, name)
+        {
+            for (var i = 0; i < headers.length; ++i) {
+                if (headers[i].name.toLowerCase() === name)
+                    return headers[i].value;
+            }
+        }
+        function onEval(result)
+        {
+            queuedOutput.push("navigator.userAgent: " + result);
+            webInspector.inspectedWindow.eval("undefined", cleanUp);
+        }
+        function cleanUp()
+        {
+            evaluateOnFrontend("TestRunner.waitForPageLoad(reply)", onPageLoaded);
+            webInspector.inspectedWindow.reload({userAgent: ""});
+        }
+        function onPageLoaded()
+        {
+            for (var i = 0; i < queuedOutput.length; ++i)
+                output(queuedOutput[i]);
+            nextTest();
+        }
+
+        webInspector.network.onRequestFinished.addListener(onRequestFinished);
+        webInspector.inspectedWindow.reload({ignoreCache: true, userAgent: "Mozilla/4.0 (compatible; WebInspector Extension User-Agent override; RSX-11M)"});
+    }
+  ]);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/multiple-extensions.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/multiple-extensions.html
deleted file mode 100644
index d175a3ad..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/multiple-extensions.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<html>
-<head>
-<script src="../../inspector/inspector-test.js"></script>
-<script src="../../inspector/extensions-test.js"></script>
-<script type="text/javascript">
-function initialize_multipleExtensionsTest()
-{
-
-var pendingTestCount = 2;
-InspectorTest.extensionTestComplete = function()
-{
-    if (--pendingTestCount)
-        ExtensionsTestRunner.runExtensionTests();
-    else
-        TestRunner.completeTest();
-}
-
-}
-
-function extension_testCreatePanel(nextTest)
-{
-    function onPanelCreated(panel)
-    {
-        output("Panel created");
-        dumpObject(panel);
-        nextTest();
-    }
-    var basePath = location.pathname.replace(/\/[^/]*$/, "/");
-    webInspector.panels.create("Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
-}
-
-function extension_onTestsDone()
-{
-    evaluateOnFrontend("InspectorTest.extensionTestComplete();");
-}
-
-</script>
-</head>
-<body onload="runTest()">
-<p>Tests co-existance of multiple DevTools extensions</p>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/multiple-extensions.js b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/multiple-extensions.js
new file mode 100644
index 0000000..ec6650a4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/multiple-extensions.js
@@ -0,0 +1,28 @@
+// 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.
+
+(async function() {
+  TestRunner.addResult(`Tests co-existance of multiple DevTools extensions\n`);
+  await TestRunner.loadModule('extensions_test_runner');
+
+  const tests = [
+    function extension_testCreatePanel(nextTest) {
+      function onPanelCreated(panel) {
+        output("Panel created");
+        dumpObject(panel);
+        evaluateOnFrontend("TestRunner.extensionTestComplete();");
+      }
+      var basePath = location.pathname.replace(/\/[^/]*$/, "/");
+      webInspector.panels.create("Test Panel", basePath + "extension-panel.png", basePath + "extension-panel.html", onPanelCreated);
+    },
+  ];
+  var pendingTestCount = 2;
+  TestRunner.extensionTestComplete = function() {
+    if (--pendingTestCount)
+      ExtensionsTestRunner.runExtensionTests(tests);
+    else
+      TestRunner.completeTest();
+  }
+  await ExtensionsTestRunner.runExtensionTests(tests);
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-events.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-events.html
new file mode 100644
index 0000000..1d480b8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-events.html
@@ -0,0 +1,2 @@
+<script src="test-script.js"></script>
+<div></div>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-network-redirect.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-network-redirect.html
new file mode 100644
index 0000000..a9e297a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-network-redirect.html
@@ -0,0 +1,16 @@
+<script>
+var requestDone = false;
+
+function doRequest(force) {
+  // Only do request once per test suite, to make tests independent on each other.
+  // Returns true iff request is alredy done (so the caller shouldn't wait for onFinished).
+  if (requestDone && !force)
+    return true;
+  requestDone = true;
+  // We can't use XHR here -- the content for XHRs is pushed from back-end.
+  var iframe = document.createElement("iframe");
+  iframe.src = "/loading/resources/redirect-methods-result.php?status=302";
+  document.body.appendChild(iframe);
+  return false;
+}
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-network.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-network.html
new file mode 100644
index 0000000..d9d82da
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-network.html
@@ -0,0 +1,17 @@
+<style>
+@font-face {
+    font-family: 'test';
+    src: url('../../../resources/Ahem.ttf');
+}
+
+p { font-family: 'test'; }
+</style>
+<img src="abe.png">
+<img src="missing-image.png">
+<script>
+function doXHR() {
+  return fetch('extensions-network.html');
+}
+</script>
+<p>some text.</p>
+<link rel="stylesheet" href="audits-style1.css">
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-panel.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-panel.html
new file mode 100644
index 0000000..5b4cf65
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-panel.html
@@ -0,0 +1,17 @@
+<script>
+function loadResources() {
+  var xhr = new XMLHttpRequest();
+  xhr.open("GET", "./missing.txt", false);
+  xhr.send();
+  var xhr = new XMLHttpRequest();
+  xhr.open("GET", "../extensions-panel.js", false);
+  xhr.send();
+  var img = document.createElement("img");
+  img.src = "./abe.png";
+  document.body.appendChild(img);
+}
+
+function logMessage() {
+  console.log("hello");
+}
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-useragent.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-useragent.html
new file mode 100644
index 0000000..54f2d34
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/extensions-useragent.html
@@ -0,0 +1,7 @@
+<script>
+(function() {
+  var xhr = new XMLHttpRequest();
+  xhr.open("GET", "../../resources/xhr-exists.html", false);
+  xhr.send(null);
+})();
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/random-script.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/random-script.html
new file mode 100644
index 0000000..7abc073
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/random-script.html
@@ -0,0 +1 @@
+<script src="../../network/resources/random-script.php"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/reload.html b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/reload.html
new file mode 100644
index 0000000..afd29c0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/extensions/resources/reload.html
@@ -0,0 +1,3 @@
+<script>
+window.bar = "foo = " + window.foo;
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry-expected.txt
new file mode 100644
index 0000000..a9eecab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry-expected.txt
@@ -0,0 +1,22 @@
+Tests object store and index entry deletion.
+
+Dumping IndexedDB tree:
+    database: database1 - http://127.0.0.1:8000
+        Object store: objectStore1
+            Index: index1
+Dumping ObjectStore data:
+    Object store: objectStore1
+            Key = testKey1, value = {"injectedScriptId":2,"id":1}
+            Key = testKey2, value = {"injectedScriptId":2,"id":2}
+            Index: index1
+                Key = testKey1, value = {"injectedScriptId":2,"id":3}
+                Key = testKey2, value = {"injectedScriptId":2,"id":4}
+Dumping ObjectStore data:
+    Object store: objectStore1
+            Key = testKey2, value = {"injectedScriptId":2,"id":5}
+            Index: index1
+                Key = testKey2, value = {"injectedScriptId":2,"id":6}
+Dumping ObjectStore data:
+    Object store: objectStore1
+            Index: index1
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry.js b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry.js
new file mode 100644
index 0000000..f4a177a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry.js
@@ -0,0 +1,72 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.addResult(`Tests object store and index entry deletion.\n`);
+  await TestRunner.loadModule('application_test_runner');
+
+  function dumpObjectStore(treeElement) {
+    TestRunner.addResult(`            Index: ${treeElement.title}`);
+    treeElement.select();
+    for (var entry of treeElement._view._entries)
+      TestRunner.addResult(`                Key = ${entry.primaryKey.value}, value = ${entry.value.objectId}`);
+  }
+
+  function dumpObjectStores() {
+    TestRunner.addResult('Dumping ObjectStore data:');
+    var idbDatabaseTreeElement = UI.panels.resources._sidebar.indexedDBListTreeElement._idbDatabaseTreeElements[0];
+    for (var objectStoreTreeElement of idbDatabaseTreeElement.children()) {
+      objectStoreTreeElement.select();
+      TestRunner.addResult(`    Object store: ${objectStoreTreeElement.title}`);
+      for (var entry of objectStoreTreeElement._view._entries)
+        TestRunner.addResult(`            Key = ${entry.key.value}, value = ${entry.value.objectId}`);
+      for (var treeElement of objectStoreTreeElement.children())
+        dumpObjectStore(treeElement);
+    }
+  }
+
+  // Switch to resources panel.
+  await TestRunner.showPanel('resources');
+  var databaseAddedPromise = TestRunner.addSnifferPromise(Resources.IndexedDBTreeElement.prototype, '_addIndexedDB');
+  await ApplicationTestRunner.createDatabaseAsync('database1');
+  UI.panels.resources._sidebar.indexedDBListTreeElement.refreshIndexedDB();
+  await databaseAddedPromise;
+  UI.panels.resources._sidebar.indexedDBListTreeElement.expand();
+
+  var idbDatabaseTreeElement = UI.panels.resources._sidebar.indexedDBListTreeElement._idbDatabaseTreeElements[0];
+  await ApplicationTestRunner.createObjectStoreAsync('database1', 'objectStore1', 'index1');
+  idbDatabaseTreeElement._refreshIndexedDB();
+  await TestRunner.addSnifferPromise(Resources.IDBIndexTreeElement.prototype, '_updateTooltip');
+
+  await ApplicationTestRunner.addIDBValueAsync('database1', 'objectStore1', 'testKey1', 'testValue');
+  await ApplicationTestRunner.addIDBValueAsync('database1', 'objectStore1', 'testKey2', 'testValue');
+
+  idbDatabaseTreeElement._refreshIndexedDB();
+  await TestRunner.addSnifferPromise(Resources.IDBIndexTreeElement.prototype, '_updateTooltip');
+  ApplicationTestRunner.dumpIndexedDBTree();
+
+  var objectStoreTreeElement = idbDatabaseTreeElement.childAt(0);
+  objectStoreTreeElement.select();
+  await TestRunner.addSnifferPromise(Resources.IDBDataView.prototype, '_updatedDataForTests');
+  var indexTreeElement = objectStoreTreeElement.childAt(0);
+  indexTreeElement.select();
+  await TestRunner.addSnifferPromise(Resources.IDBDataView.prototype, '_updatedDataForTests');
+  dumpObjectStores();
+
+  var node = objectStoreTreeElement._view._dataGrid.rootNode().children[0];
+  node.select();
+  objectStoreTreeElement._view._deleteButtonClicked(node);
+  await TestRunner.addSnifferPromise(Resources.IDBDataView.prototype, '_updatedDataForTests');
+  await TestRunner.addSnifferPromise(Resources.IDBDataView.prototype, '_updatedDataForTests');
+  dumpObjectStores();
+
+  node = indexTreeElement._view._dataGrid.rootNode().children[0];
+  node.select();
+  indexTreeElement._view._deleteButtonClicked(node);
+  await TestRunner.addSnifferPromise(Resources.IDBDataView.prototype, '_updatedDataForTests');
+  await TestRunner.addSnifferPromise(Resources.IDBDataView.prototype, '_updatedDataForTests');
+  dumpObjectStores();
+
+  TestRunner.completeTest();
+})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/resources/extension-main.js b/third_party/WebKit/LayoutTests/http/tests/devtools/resources/extension-main.js
index 5416cdf..9602f6b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/resources/extension-main.js
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/resources/extension-main.js
@@ -52,31 +52,28 @@
 
 function invokePageFunctionAsync(functionName, callback)
 {
-    evaluateOnFrontend("InspectorTest.callFunctionInPageAsync('" + functionName + "').then(() => reply())", callback);
+    evaluateOnFrontend("TestRunner.callFunctionInPageAsync('" + functionName + "').then(() => reply())", callback);
 }
 
 function output(message)
 {
-    evaluateOnFrontend("InspectorTest.addResult(unescape('" + escape(message) + "'));");
+    evaluateOnFrontend("TestRunner.addResult(unescape('" + escape(message) + "'));");
 }
 
 function onError(event)
 {
     window.removeEventListener("error", onError);
     output("Uncaught exception in extension context: " + event.message + " [" + event.filename + ":" + event.lineno + "]\n");
-    evaluateOnFrontend("InspectorTest.completeTest();");
+    evaluateOnFrontend("TestRunner.completeTest();");
 }
 
 window.addEventListener("error", onError);
 
-function fetchTests()
-{
-    function callback(result)
-    {
-         window.eval(result);
-         runTests();
-    }
-    webInspector.inspectedWindow.eval("extensionFunctions()", callback);
+function fetchTests() {
+  evaluateOnFrontend('reply(ExtensionsTestRunner._pendingTests)', result => {
+    window.eval(result);
+    runTests();
+  });
 }
 
 function runTests()
@@ -97,7 +94,35 @@
 function extension_onTestsDone()
 {
     output("All tests done.");
-    evaluateOnFrontend("InspectorTest.completeTest();");
+    evaluateOnFrontend("TestRunner.completeTest();");
+}
+
+function extension_showPanel(panelId, callback)
+{
+    evaluateOnFrontend("ExtensionsTestRunner.showPanel(unescape('" + escape(panelId) + "')).then(function() { reply(); });", callback);
+}
+
+function extension_runAudits(callback) {
+    evaluateOnFrontend('ExtensionsTestRunner.startExtensionAudits(reply);', callback);
+}
+
+function extension_getRequestByUrl(urls, callback)
+{
+    function onHAR(response)
+    {
+        var entries = response.entries;
+        for (var i = 0; i < entries.length; ++i) {
+            for (var url = 0; url < urls.length; ++url) {
+                if (urls[url].test(entries[i].request.url)) {
+                    callback(entries[i]);
+                    return;
+                }
+            }
+        }
+        output("no item found");
+        callback(null);
+    }
+    webInspector.network.getHAR(onHAR);
 }
 
 function runTest(test, name)
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js
index 781d205..a9e0447c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js
@@ -60,7 +60,8 @@
     SourcesTestRunner.runTestFunctionAndWaitUntilPaused(step2);
   }
 
-  function step2(callFrames) {
+  async function step2(callFrames) {
+    await TestRunner.addSnifferPromise(Sources.CallStackSidebarPane.prototype, '_updatedForTest');
     SourcesTestRunner.captureStackTrace(callFrames);
     TestRunner.addResult('\n=== Evaluating on iframe ===');
     evaluateInConsoleAndDump(step3);
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/OWNERS b/third_party/WebKit/LayoutTests/http/tests/locks/OWNERS
new file mode 100644
index 0000000..5ca6cf5f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/OWNERS
@@ -0,0 +1,2 @@
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html b/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html
new file mode 100644
index 0000000..ca5cf61
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/acquire.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: navigator.locks.acquire method</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/get-host-info.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+  await promise_rejects(t, new TypeError(), navigator.locks.acquire());
+  await promise_rejects(t, new TypeError(), navigator.locks.acquire('scope'));
+}, 'navigator.locks.acquire requires a scope and a callback');
+
+promise_test(async t => {
+  await promise_rejects(
+    t, new TypeError(),
+    navigator.locks.acquire('scope', {mode: 'foo'}, lock => {}));
+  await promise_rejects(
+    t, new TypeError(),
+    navigator.locks.acquire('scope', {mode: null }, lock => {}));
+  assert_equals(await navigator.locks.acquire(
+    'scope', {mode: 'exclusive'}, lock => lock.mode), 'exclusive',
+                'mode is exclusive');
+  assert_equals(await navigator.locks.acquire(
+    'scope', {mode: 'shared'}, lock => lock.mode), 'shared',
+                'mode is shared');
+}, 'mode must be "shared" or "exclusive"');
+
+promise_test(async t => {
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire('scope', undefined));
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire('scope', null));
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire('scope', 123));
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire('scope', 'abc'));
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire('scope', []));
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire('scope', {}));
+  await promise_rejects(
+    t, new TypeError(), navigator.locks.acquire('scope', new Promise(r => {})));
+}, 'callback must be a function');
+
+promise_test(async t => {
+  let release;
+  const promise = new Promise(r => { release = r; });
+
+  let returned = navigator.locks.acquire('scope', lock => { return promise; });
+
+  const order = [];
+
+  returned.then(() => { order.push('returned'); });
+  promise.then(() => { order.push('holding'); });
+
+  release();
+
+  await Promise.all([returned, promise]);
+
+  assert_array_equals(order, ['holding', 'returned']);
+
+}, 'navigator.locks.acquire\'s returned promise resolves after' +
+   ' lock is released');
+
+promise_test(async t => {
+  const test_error = {name: 'test'};
+  const p = navigator.locks.acquire('resource', lock => {
+    throw test_error;
+  });
+  assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
+  await promise_rejects(t, test_error, p, 'result should reject');
+}, 'Returned Promise rejects if callback throws synchronously');
+
+promise_test(async t => {
+  const test_error = {name: 'test'};
+  const p = navigator.locks.acquire('resource', async lock => {
+    throw test_error;
+  });
+  assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
+  await promise_rejects(t, test_error, p, 'result should reject');
+}, 'Returned Promise rejects if callback throws asynchronously');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/frames.html b/third_party/WebKit/LayoutTests/http/tests/locks/frames.html
new file mode 100644
index 0000000..2475fa7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/frames.html
@@ -0,0 +1,290 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Frames</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>iframe { display: none; }</style>
+<script>
+'use strict';
+
+let res_num = 0;
+function uniqueName(testCase) {
+  return `${self.location.pathname}-${testCase.name}-${++res_num}`;
+}
+
+function iframe(url) {
+  return new Promise(resolve => {
+    const element = document.createElement('iframe');
+    element.addEventListener(
+      'load', () => { resolve(element); }, { once: true });
+    element.src = url;
+    document.documentElement.appendChild(element);
+  });
+}
+
+let next_request_id = 0;
+function postAndWait(frame, data) {
+  const iframe_window = frame.contentWindow;
+  iframe_window.postMessage(Object.assign(data, {rqid: next_request_id++}), '*');
+  return new Promise(resolve => {
+    const listener = event => {
+      if (event.source !== iframe_window || event.data.rqid !== data.rqid)
+        return;
+      self.removeEventListener('message', listener);
+      resolve(event.data);
+    };
+    self.addEventListener('message', listener);
+  });
+}
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  const frame = await iframe('resources/iframe.html');
+  t.add_cleanup(() => { frame.remove(); });
+
+  const data = await postAndWait(
+    frame, {op: 'request', lock_id: 1, scope: res, mode: 'shared'});
+
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  await navigator.locks.acquire(res, {mode: 'shared'}, async lock => {
+    const data = await postAndWait(frame, {op: 'release', lock_id: 1});
+    assert_equals(data.ack, 'release');
+    assert_equals(data.id, 1);
+  });
+
+}, 'Window and Frame - shared mode');
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  const frame = await iframe('resources/iframe.html');
+  t.add_cleanup(() => { frame.remove(); });
+
+  const data = await postAndWait(
+    frame, {op: 'request', lock_id: 1, scope: res});
+  // frame has the lock.
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // This request should be blocked.
+  let lock_granted = false;
+  const blocked = navigator.locks.acquire(res, lock => { lock_granted = true; });
+
+  // Verify that we can't get it.
+  let available = undefined;
+  await navigator.locks.acquire(
+    res, {ifAvailable: true}, lock => { available = lock !== null; });
+  assert_false(available);
+  assert_false(lock_granted);
+
+  // Ask the frame to release it.
+  const data2 = await postAndWait(frame, {op: 'release', lock_id: 1});
+
+  // Frame released it.
+  assert_equals(data2.ack, 'release');
+  assert_equals(data2.id, 1);
+  await blocked;
+  // Now we've got it.
+  assert_true(lock_granted);
+}, 'Window and Frame - exclusive mode');
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  const frame1 = await iframe('resources/iframe.html');
+  const frame2 = await iframe('resources/iframe.html');
+  const data = await postAndWait(
+    frame1, {op: 'request', lock_id: 1, scope: res});
+
+  // frame1 has the lock.
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // frame2's request should be blocked.
+  let lock_granted = false;
+  const blocked = postAndWait(
+    frame2, {op: 'request', lock_id: 1, scope: res});
+  blocked.then(f => { lock_granted = true; });
+
+  // Verify that frame2 can't get it.
+  assert_true((await postAndWait(frame2, {
+    op: 'request', scope: res, lock_id: 2, ifAvailable: true
+  })).failed, 'Lock request should have failed');
+  assert_false(lock_granted);
+
+  // Ask frame1 to release it.
+  const data2 = await postAndWait(frame1, {op: 'release', lock_id: 1});
+  assert_equals(data2.ack, 'release');
+  assert_equals(data2.id, 1);
+
+  await blocked;
+  // Now frame2 can get it.
+  assert_true(lock_granted);
+  frame1.parentElement.removeChild(frame1);
+  frame2.parentElement.removeChild(frame2);
+}, 'Frame and Frame - exclusive mode');
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  const frame = await iframe('resources/iframe.html');
+  const data = await postAndWait(
+    frame, {op: 'request', lock_id: 1, scope: res});
+  // Frame has the lock.
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // This request should be blocked.
+  let lock_granted = false;
+  const blocked = navigator.locks.acquire(
+    res, lock => { lock_granted = true; });
+
+  // Verify that we can't get it.
+  let available = undefined;
+  await navigator.locks.acquire(
+    res, {ifAvailable: true}, lock => { available = lock !== null; });
+  assert_false(available);
+  assert_false(lock_granted);
+
+  // Implicitly release it by terminating the frame.
+  frame.remove();
+  await blocked;
+  // Now we've got it.
+  assert_true(lock_granted);
+
+}, 'Terminated Frame with held lock');
+
+promise_test(async t => {
+  const res = uniqueName(t);
+
+  const frame = await iframe('resources/iframe.html');
+  const data = await postAndWait(
+    frame, {op: 'request', lock_id: 1, scope: res});
+  // Frame has the lock.
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // This request should be blocked.
+  let lock_granted = false;
+  const blocked = navigator.locks.acquire(
+    res, lock => { lock_granted = true; });
+
+  // Verify that we can't get it.
+  let available = undefined;
+  await navigator.locks.acquire(
+    res, {ifAvailable: true}, lock => { available = lock !== null; });
+  assert_false(available);
+  assert_false(lock_granted);
+
+  // Implicitly release it by navigating the frame.
+  frame.src = 'about:blank';
+  await blocked;
+  // Now we've got it.
+  assert_true(lock_granted);
+
+}, 'Navigated Frame with held lock');
+
+promise_test(async t => {
+  const res1 = uniqueName(t);
+  const res2 = uniqueName(t);
+
+  // frame1 requests and holds [r1] - should be granted immediately
+  // frame2 requests [r1, r2] - should be blocked
+  // frame3 requests [r2] - should be blocked
+  // frame2 is navigated
+  // frame3's request should be granted
+
+  const frame1 = await iframe('resources/iframe.html');
+  const frame2 = await iframe('resources/iframe.html');
+  const frame3 = await iframe('resources/iframe.html');
+  t.add_cleanup(() => { frame1.remove(); });
+  t.add_cleanup(() => { frame2.remove(); });
+  t.add_cleanup(() => { frame3.remove(); });
+
+  // frame1 requests and holds [r1] - should be granted immediately.
+  const data = await postAndWait(
+    frame1, {op: 'request', lock_id: 1, scope: res1});
+
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // frame2 requests [r1, r2] - should be blocked.
+  // (don't attach listeners as they will keep the frame alive)
+  frame2.contentWindow.postMessage(
+    {op: 'request', lock_id: 1, scope: [res1, res2]}, '*');
+
+  // frame3 requests [r2] - should be blocked.
+  let lock_granted = false;
+  const blocked = postAndWait(
+    frame3, {op: 'request', lock_id: 1, scope: res2});
+  blocked.then(f => { lock_granted = true; });
+
+  // Verify that frame3 can't get it.
+  assert_true((await postAndWait(frame3, {
+    op: 'request', scope: res2, lock_id: 2, ifAvailable: true
+  })).failed, 'Lock request should have failed');
+  assert_false(lock_granted);
+
+  // Navigate frame2.
+  frame2.src = 'about:blank';
+
+  // frame3's request should be granted.
+  await blocked;
+  assert_true(lock_granted);
+
+}, 'Navigated Frame with pending request');
+
+promise_test(async t => {
+  const res1 = uniqueName(t);
+  const res2 = uniqueName(t);
+
+  // frame1 requests and holds [r1] - should be granted immediately.
+  // frame2 requests [r1, r2] - should be blocked.
+  // frame3 requests [r2] - should be blocked.
+  // frame2 is navigated.
+  // frame3's request should be granted.
+
+  const frame1 = await iframe('resources/iframe.html');
+  const frame2 = await iframe('resources/iframe.html');
+  const frame3 = await iframe('resources/iframe.html');
+  t.add_cleanup(() => { frame1.remove(); });
+  t.add_cleanup(() => { frame3.remove(); });
+
+  // frame1 requests and holds [r1] - should be granted immediately.
+  const data = await postAndWait(
+    frame1, {op: 'request', lock_id: 1, scope: res1});
+
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // frame2 requests [r1, r2] - should be blocked.
+  // (don't attach listeners as they will keep the frame alive)
+  frame2.contentWindow.postMessage(
+    {op: 'request', lock_id: 1, scope: [res1, res2]}, '*');
+
+  // frame3 requests [r2] - should be blocked.
+  let lock_granted = false;
+  const blocked = postAndWait(
+    frame3, {op: 'request', lock_id: 1, scope: res2});
+  blocked.then(f => { lock_granted = true; });
+
+  // So frame3 can't get it
+  assert_true((await postAndWait(frame3, {
+    op: 'request', scope: res2, lock_id: 2, ifAvailable: true
+  })).failed, 'Lock request should have failed');
+  assert_false(lock_granted);
+
+  // Remove frame2.
+  frame2.remove();
+
+  // frame3's request should be granted.
+  await blocked;
+  assert_true(lock_granted);
+
+}, 'Removed Frame with pending request');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/held.html b/third_party/WebKit/LayoutTests/http/tests/locks/held.html
new file mode 100644
index 0000000..3c12668
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/held.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Lock held until callback result resolves</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+// For uncaught rejections.
+setup({allow_uncaught_exception: true});
+
+function snooze(t, ms) { return new Promise(r => t.step_timeout(r, ms)); }
+
+promise_test(async t => {
+  const p = navigator.locks.acquire('resource', lock => 123);
+  assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
+  assert_equals(await p, 123, 'promise resolves to the returned value');
+}, 'callback\'s result is promisified if not async');
+
+promise_test(async t => {
+  // Resolved when the lock is granted.
+  let granted;
+  const lock_granted_promise = new Promise(r => { granted = r; });
+
+  // Lock is held until this is resolved.
+  let resolve;
+  const lock_release_promise = new Promise(r => { resolve = r; });
+
+  const order = [];
+
+  navigator.locks.acquire('resource', lock => {
+    granted(lock);
+    return lock_release_promise;
+  });
+  await lock_granted_promise;
+
+  await Promise.all([
+    snooze(t, 50).then(() => {
+      order.push('1st lock released');
+      resolve();
+    }),
+    navigator.locks.acquire('resource', () => {
+      order.push('2nd lock granted');
+    })
+  ]);
+
+  assert_array_equals(order, ['1st lock released', '2nd lock granted']);
+}, 'lock is held until callback\'s returned promise resolves');
+
+promise_test(async t => {
+  // Resolved when the lock is granted.
+  let granted;
+  const lock_granted_promise = new Promise(r => { granted = r; });
+
+  // Lock is held until this is rejected.
+  let reject;
+  const lock_release_promise = new Promise((_, r) => { reject = r; });
+
+  const order = [];
+
+  navigator.locks.acquire('resource', lock => {
+    granted(lock);
+    return lock_release_promise;
+  });
+  await lock_granted_promise;
+
+  await Promise.all([
+    snooze(t, 50).then(() => {
+      order.push('reject');
+      reject(new Error('this uncaught rejection is expected'));
+    }),
+    navigator.locks.acquire('resource', () => {
+      order.push('2nd lock granted');
+    })
+  ]);
+
+  assert_array_equals(order, ['reject', '2nd lock granted']);
+}, 'lock is held until callback\'s returned promise rejects');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/ifAvailable.html b/third_party/WebKit/LayoutTests/http/tests/locks/ifAvailable.html
new file mode 100644
index 0000000..a8951c0e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/ifAvailable.html
@@ -0,0 +1,133 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: ifAvailable option</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', {ifAvailable: true}, async lock => {
+    callback_called = true;
+    assert_not_equals(lock, null, 'lock should be granted');
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - lock available');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', async lock => {
+    // Request would time out if |ifAvailable| was not specified.
+    const result = await navigator.locks.acquire(
+      'resource', {ifAvailable: true}, async lock => {
+        callback_called = true;
+        assert_equals(lock, null, 'lock should not be granted');
+        return 123;
+      });
+    assert_equals(result, 123, 'result should be value returned by callback');
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - lock not available');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', async lock => {
+    try {
+      // Request would time out if |ifAvailable| was not specified.
+      await navigator.locks.acquire('resource', {ifAvailable: true}, async lock => {
+        callback_called = true;
+        assert_equals(lock, null, 'lock should not be granted');
+        throw 123;
+      });
+      assert_unreached('call should throw');
+    } catch (ex) {
+      assert_equals(ex, 123, 'ex should be value thrown by callback');
+    }
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - lock not available, callback throws');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', async lock => {
+    // Request with a different scope - should be grantable.
+    await navigator.locks.acquire('different', {ifAvailable: true}, async lock => {
+      callback_called = true;
+      assert_not_equals(lock, null, 'lock should be granted');
+    });
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - unrelated lock held');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', {mode: 'shared'}, async lock => {
+    await navigator.locks.acquire(
+      'resource', {mode: 'shared', ifAvailable: true}, async lock => {
+        callback_called = true;
+        assert_not_equals(lock, null, 'lock should be granted');
+      });
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Shared lock request with ifAvailable - shared lock held');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', {mode: 'shared'}, async lock => {
+    // Request would time out if |ifAvailable| was not specified.
+    await navigator.locks.acquire('resource', {ifAvailable: true}, async lock => {
+      callback_called = true;
+      assert_equals(lock, null, 'lock should not be granted');
+    });
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Exclusive lock request with ifAvailable - shared lock held');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', async lock => {
+    // Request would time out if |ifAvailable| was not specified.
+    await navigator.locks.acquire(
+      'resource', {mode: 'shared', ifAvailable: true}, async lock => {
+        callback_called = true;
+        assert_equals(lock, null, 'lock should not be granted');
+      });
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Shared lock request with ifAvailable - exclusive lock held');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', async lock => {
+    callback_called = true;
+    const test_error = {name: 'test'};
+    const p = navigator.locks.acquire(
+      'resource', {ifAvailable: true}, lock => {
+        assert_equals(lock, null, 'lock should not be available');
+        throw test_error;
+      });
+    assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
+    await promise_rejects(t, test_error, p, 'result should reject');
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Returned Promise rejects if callback throws synchronously');
+
+promise_test(async t => {
+  let callback_called = false;
+  await navigator.locks.acquire('resource', async lock => {
+    callback_called = true;
+    const test_error = {name: 'test'};
+    const p = navigator.locks.acquire(
+      'resource', {ifAvailable: true}, async lock => {
+        assert_equals(lock, null, 'lock should not be available');
+        throw test_error;
+      });
+    assert_equals(Promise.resolve(p), p, 'acquire() result is a Promise');
+    await promise_rejects(t, test_error, p, 'result should reject');
+  });
+  assert_true(callback_called, 'callback should be called');
+}, 'Returned Promise rejects if async callback yields rejected promise');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/interfaces-worker.html b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces-worker.html
new file mode 100644
index 0000000..d0b5db3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces-worker.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: WebIDL tests in worker</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/get-host-info.js"></script>
+<script>
+// TODO(jsbell): When migrated to WPT: remove block, rename with .https infix.
+if (location.origin != get_host_info().AUTHENTICATED_ORIGIN) {
+  location = get_host_info().AUTHENTICATED_ORIGIN + location.pathname;
+  throw new Error('Reloading with appropriate origin for desired context...');
+}
+
+fetch_tests_from_worker(new Worker('resources/interfaces-worker.js'));
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.html b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.html
new file mode 100644
index 0000000..9e9cdabb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: WebIDL tests</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/w3c/resources/webidl2.js"></script>
+<script src="/w3c/resources/idlharness.js"></script>
+<script src="/resources/get-host-info.js"></script>
+<script>
+'use strict';
+
+// TODO(jsbell): When migrated to WPT: remove block, rename with .https infix.
+if (location.origin != get_host_info().AUTHENTICATED_ORIGIN) {
+  location = get_host_info().AUTHENTICATED_ORIGIN + location.pathname;
+  throw new Error('Reloading with appropriate origin for desired context...');
+}
+
+promise_test(async t => {
+  const response = await fetch('interfaces.idl');
+  const idls = await response.text();
+
+  const idl_array = new IdlArray();
+
+  idl_array.add_untested_idls('interface Navigator {};');
+  idl_array.add_untested_idls('interface WorkerNavigator {};');
+
+  idl_array.add_idls(idls);
+
+  let lock;
+  await navigator.locks.acquire('scope', async l => { lock = l; });
+
+  idl_array.add_objects({
+    LockManager: [navigator.locks],
+    Lock: [lock],
+  });
+
+  idl_array.test();
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.idl b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.idl
new file mode 100644
index 0000000..26c61431
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/interfaces.idl
@@ -0,0 +1,36 @@
+
+typedef (DOMString or sequence<DOMString>) LockScope;
+
+enum LockMode { "shared", "exclusive" };
+
+dictionary LockOptions {
+  LockMode mode = "exclusive";
+  boolean ifAvailable = false;
+};
+
+callback LockGrantedCallback = any (Lock lock);
+
+[Exposed=Window]
+partial interface Navigator {
+  [SecureContext] readonly attribute LockManager locks;
+};
+
+[Exposed=Worker]
+partial interface WorkerNavigator {
+  [SecureContext] readonly attribute LockManager locks;
+};
+
+[Exposed=(Window,Worker), SecureContext]
+interface LockManager {
+  Promise<any> acquire(LockScope scope,
+                       LockRequestCallback callback);
+  Promise<any> acquire(LockScope scope,
+                       LockOptions options,
+                       LockRequestCallback callback);
+};
+
+[Exposed=(Window,Worker), SecureContext]
+interface Lock {
+  readonly attribute FrozenArray<DOMString> scope;
+  readonly attribute LockMode mode;
+};
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/lock-attributes.html b/third_party/WebKit/LayoutTests/http/tests/locks/lock-attributes.html
new file mode 100644
index 0000000..1adbe2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/lock-attributes.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Lock Attributes</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+  await navigator.locks.acquire(['r1', 'r2'], lock => {
+    assert_array_equals(lock.scope, ['r1', 'r2']);
+    assert_equals(lock.mode, 'exclusive');
+  });
+}, 'Lock attributes reflect requested properties (exclusive)');
+
+promise_test(async t => {
+  await navigator.locks.acquire(['r1', 'r2'], {mode: 'shared'}, lock => {
+    assert_array_equals(lock.scope, ['r1', 'r2']);
+    assert_equals(lock.mode, 'shared');
+  });
+}, 'Lock attributes reflect requested properties (shared)');
+
+promise_test(async t => {
+  await navigator.locks.acquire(['r2', 'r1'], lock => {
+    assert_array_equals(lock.scope, ['r1', 'r2']);
+  });
+}, 'Lock.scope is in sorted order');
+
+promise_test(async t => {
+  await navigator.locks.acquire(['r1', 'r2', 'r1', 'r2'], lock => {
+    assert_array_equals(lock.scope, ['r1', 'r2']);
+  });
+}, 'Lock.scope has no duplicates');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/mode-exclusive.html b/third_party/WebKit/LayoutTests/http/tests/locks/mode-exclusive.html
new file mode 100644
index 0000000..05e65e9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/mode-exclusive.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Exclusive Mode</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+  const granted = [];
+  function log_grant(n) { return () => { granted.push(n); }; }
+
+  await Promise.all([
+    navigator.locks.acquire(['a', 'b'], log_grant(1)),
+    navigator.locks.acquire(['b', 'c'], log_grant(2)),
+    navigator.locks.acquire(['c'], log_grant(3))
+  ]);
+  assert_array_equals(granted, [1, 2, 3]);
+}, 'Lock requests are granted in order');
+
+promise_test(async t => {
+  const granted = [];
+  function log_grant(n) { return () => { granted.push(n); }; }
+
+  let inner_promise;
+  await navigator.locks.acquire('a', async lock => {
+    inner_promise = Promise.all([
+      // This will be blocked.
+      navigator.locks.acquire(['a', 'b'], log_grant(1)),
+      // But this should be grantable immediately.
+      navigator.locks.acquire(['c', 'd'], log_grant(2))
+    ]);
+  });
+
+  await inner_promise;
+  assert_array_equals(granted, [2, 1]);
+}, 'Requests with non-overlapping scopes can be granted');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/mode-mixed.html b/third_party/WebKit/LayoutTests/http/tests/locks/mode-mixed.html
new file mode 100644
index 0000000..8327f11
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/mode-mixed.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Mixed Modes</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+  let unblock;
+  const blocked = new Promise(r => { unblock = r; });
+
+  const granted = [];
+
+  // These should be granted immediately, and held until unblocked.
+  navigator.locks.acquire('a', {mode: 'shared'}, async lock => {
+    granted.push('a-shared-1'); await blocked; });
+  navigator.locks.acquire('a', {mode: 'shared'}, async lock => {
+    granted.push('a-shared-2'); await blocked; });
+  navigator.locks.acquire('a', {mode: 'shared'}, async lock => {
+    granted.push('a-shared-3'); await blocked; });
+
+  // This should be blocked.
+  let exclusive_lock;
+  const exclusive_request = navigator.locks.acquire('a', async lock => {
+    granted.push('a-exclusive');
+    exclusive_lock = lock;
+  });
+
+  // This should be granted immediately (different scope).
+  await navigator.locks.acquire('b', {mode: 'exclusive'}, lock => {
+    granted.push('b-exclusive'); });
+
+  assert_array_equals(
+    granted, ['a-shared-1', 'a-shared-2', 'a-shared-3', 'b-exclusive']);
+
+  // Release the shared locks granted above.
+  unblock();
+
+  // Now the blocked request can be granted.
+  await exclusive_request;
+  assert_equals(exclusive_lock.mode, 'exclusive');
+
+  assert_array_equals(
+    granted,
+    ['a-shared-1', 'a-shared-2', 'a-shared-3', 'b-exclusive', 'a-exclusive']);
+
+}, 'Lock requests are granted in order');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/mode-shared.html b/third_party/WebKit/LayoutTests/http/tests/locks/mode-shared.html
new file mode 100644
index 0000000..3a6ff8d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/mode-shared.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Shared Mode</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+  const granted = [];
+  function log_grant(n) { return () => { granted.push(n); }; }
+
+  await Promise.all([
+    navigator.locks.acquire('a', {mode: 'shared'}, log_grant(1)),
+    navigator.locks.acquire('b', {mode: 'shared'}, log_grant(2)),
+    navigator.locks.acquire('c', {mode: 'shared'}, log_grant(3)),
+    navigator.locks.acquire('a', {mode: 'shared'}, log_grant(4)),
+    navigator.locks.acquire('b', {mode: 'shared'}, log_grant(5)),
+    navigator.locks.acquire('c', {mode: 'shared'}, log_grant(6)),
+  ]);
+
+  assert_array_equals(granted, [1, 2, 3, 4, 5, 6]);
+}, 'Lock requests are granted in order');
+
+promise_test(async t => {
+  let ab_acquired = false, a_acquired = false, b_acquired = false;
+
+  await navigator.locks.acquire(['a', 'b'], {mode: 'shared'}, async lock => {
+    ab_acquired = true;
+
+    // Since lock over [a, b] is held, these requests would be blocked if the
+    // locks were not all 'shared', causing this test to time out.
+
+    await navigator.locks.acquire('a', {mode: 'shared'}, lock => {
+      a_acquired = true;
+    });
+
+    await navigator.locks.acquire('b', {mode: 'shared'}, lock => {
+      b_acquired = true;
+    });
+  });
+
+  assert_true(ab_acquired, 'requested lock was acquired');
+  assert_true(a_acquired, 'first lock with overlapping scope acquired');
+  assert_true(a_acquired, 'second lock with overlapping scope acquired');
+}, 'Shared locks are not exclusive');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/non-secure-context.html b/third_party/WebKit/LayoutTests/http/tests/locks/non-secure-context.html
new file mode 100644
index 0000000..4059e7f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/non-secure-context.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: API not available in non-secure context</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/get-host-info.js"></script>
+<script>
+'use strict';
+
+// TODO(jsbell): When migrated to WPT: remove block.
+if (location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) {
+  location = get_host_info().UNAUTHENTICATED_ORIGIN + location.pathname;
+  throw new Error('Reloading with appropriate origin for desired context...');
+}
+
+test(t => {
+  assert_false(window.isSecureContext);
+  assert_false('locks' in navigator,
+               'navigator.locks is only present in secure contexts');
+  assert_false('LockManager' in self,
+               'LockManager is only present in secure contexts');
+  assert_false('Lock' in self,
+               'Lock interface is only present in secure contexts');
+}, 'API presence in non-secure contexts');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/opaque-origin.html b/third_party/WebKit/LayoutTests/http/tests/locks/opaque-origin.html
new file mode 100644
index 0000000..abcc12eb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/opaque-origin.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Opaque origins</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+function load_iframe(src, sandbox) {
+  return new Promise(resolve => {
+    const iframe = document.createElement('iframe');
+    iframe.onload = () => { resolve(iframe); };
+    if (sandbox)
+      iframe.sandbox = sandbox;
+    iframe.srcdoc = src;
+    iframe.style.display = 'none';
+    document.documentElement.appendChild(iframe);
+  });
+}
+
+function wait_for_message(iframe) {
+  return new Promise(resolve => {
+    self.addEventListener('message', function listener(e) {
+      if (e.source === iframe.contentWindow) {
+        resolve(e.data);
+        self.removeEventListener('message', listener);
+      }
+    });
+  });
+}
+
+const script = `
+<script>
+  "use strict";
+  window.onmessage = async () => {
+    try {
+      await navigator.locks.acquire('scope', lock => {});
+      window.parent.postMessage({result: "no exception"}, "*");
+    } catch (ex) {
+      window.parent.postMessage({result: ex.name}, "*");
+    };
+  };
+<\/script>
+`;
+
+promise_test(async t => {
+  const iframe = await load_iframe(script);
+  iframe.contentWindow.postMessage({}, '*');
+  const message = await wait_for_message(iframe);
+  assert_equals(message.result, 'no exception',
+                'navigator.locks.acquire() should not throw');
+}, 'navigator.locks.acquire() in non-sandboxed iframe should not throw');
+
+promise_test(async t => {
+  const iframe = await load_iframe(script, 'allow-scripts');
+  iframe.contentWindow.postMessage({}, '*');
+  const message = await wait_for_message(iframe);
+  assert_equals(message.result, 'SecurityError',
+                'Exception should be SecurityError');
+}, 'navigator.locks.acquire() in sandboxed iframe should throw SecurityError');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resource-names.html b/third_party/WebKit/LayoutTests/http/tests/locks/resource-names.html
new file mode 100644
index 0000000..46830b98
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/resource-names.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Resources DOMString edge cases</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+function code_points(s) {
+  return [...s]
+    .map(c => '0x' + c.charCodeAt(0).toString(16).toUpperCase())
+    .join(' ');
+}
+
+[
+  '', // Empty strings
+  'abc\x00def', // Embedded NUL
+  '\uD800', // Unpaired low surrogage
+  '\uDC00', // Unpaired high surrogage
+  '\uDC00\uD800', // Swapped surrogate pair
+  '\uFFFF' // Non-character
+].forEach(string => {
+  promise_test(async t => {
+    await navigator.locks.acquire(string, lock => {
+      assert_array_equals(lock.scope, [string],
+                          'Requested name matches granted name');
+    });
+  }, 'DOMString: ' + code_points(string));
+});
+
+promise_test(async t => {
+  // '\uD800' treated as a USVString would become '\uFFFD'.
+  await navigator.locks.acquire('\uD800', async lock => {
+    assert_array_equals(lock.scope, ['\uD800']);
+
+    // |lock| is held for the duration of this scope. It
+    // Should not block acquiring |lock2| with a distinct
+    // DOMString.
+    await navigator.locks.acquire('\uFFFD', lock2 => {
+      assert_array_equals(lock2.scope, ['\uFFFD']);
+    });
+
+    // If we did not time out, this passed.
+  });
+}, 'Resource names that are not valid UTF-16 are not mangled');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resources/iframe.html b/third_party/WebKit/LayoutTests/http/tests/locks/resources/iframe.html
new file mode 100644
index 0000000..eddea2de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/resources/iframe.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<title>Helper IFrame</title>
+<script>
+'use strict';
+
+// Map of lock_id => function that releases a lock.
+
+const held = new Map();
+self.addEventListener('message', e => {
+  function respond(data) {
+    parent.postMessage(Object.assign(data, {rqid: e.data.rqid}), '*');
+  }
+
+  switch (e.data.op) {
+    case 'request':
+      navigator.locks.acquire(
+        e.data.scope, {
+          mode: e.data.mode || 'exclusive',
+          ifAvailable: e.data.ifAvailable || false
+        }, lock => {
+          if (lock === null) {
+            respond({ack: 'request', id: e.data.lock_id, failed: true});
+            return;
+          }
+          let release;
+          const promise = new Promise(r => { release = r; });
+          held.set(e.data.lock_id, release);
+          respond({ack: 'request', id: e.data.lock_id});
+          return promise
+        });
+      break;
+
+    case 'release':
+      held.get(e.data.lock_id)();
+      held.delete(e.data.lock_id);
+      respond({ack: 'release', id: e.data.lock_id});
+      break;
+  }
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resources/interfaces-worker.js b/third_party/WebKit/LayoutTests/http/tests/locks/resources/interfaces-worker.js
new file mode 100644
index 0000000..2c9704c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/resources/interfaces-worker.js
@@ -0,0 +1,29 @@
+'use strict';
+
+importScripts('/resources/testharness.js',
+              '/w3c/resources/webidl2.js',
+              '/w3c/resources/idlharness.js');
+
+promise_test(async t => {
+  const response = await fetch('../interfaces.idl');
+  const idls = await response.text();
+
+  const idl_array = new IdlArray();
+
+  idl_array.add_untested_idls('interface Navigator {};');
+  idl_array.add_untested_idls('interface WorkerNavigator {};');
+
+  idl_array.add_idls(idls);
+
+  let lock;
+  await navigator.locks.acquire('scope', async l => { lock = l; });
+
+  idl_array.add_objects({
+    LockManager: [navigator.locks],
+    Lock: [lock],
+  });
+
+  idl_array.test();
+});
+
+done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/resources/worker.js b/third_party/WebKit/LayoutTests/http/tests/locks/resources/worker.js
new file mode 100644
index 0000000..be10504
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/resources/worker.js
@@ -0,0 +1,37 @@
+'use strict';
+
+// Map of id => function that releases a lock.
+
+const held = new Map();
+
+self.addEventListener('message', e => {
+  function respond(data) {
+    self.postMessage(Object.assign(data, {rqid: e.data.rqid}));
+  }
+
+  switch (e.data.op) {
+  case 'request':
+    navigator.locks.acquire(
+      e.data.scope, {
+        mode: e.data.mode || 'exclusive',
+        ifAvailable: e.data.ifAvailable || false
+      }, lock => {
+        if (lock === null) {
+          respond({ack: 'request', id: e.data.lock_id, failed: true});
+          return;
+        }
+        let release;
+        const promise = new Promise(r => { release = r; });
+        held.set(e.data.lock_id, release);
+        respond({ack: 'request', id: e.data.lock_id});
+        return promise;
+      });
+    break;
+
+  case 'release':
+    held.get(e.data.lock_id)();
+    held.delete(e.data.lock_id);
+    respond({ack: 'release', id: e.data.lock_id});
+    break;
+  }
+});
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/secure-context.html b/third_party/WebKit/LayoutTests/http/tests/locks/secure-context.html
new file mode 100644
index 0000000..95b97626
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/secure-context.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: API requires secure context</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/get-host-info.js"></script>
+<script>
+'use strict';
+
+// TODO(jsbell): When migrated to WPT: remove block, rename with .https infix.
+if (location.origin != get_host_info().AUTHENTICATED_ORIGIN) {
+  location = get_host_info().AUTHENTICATED_ORIGIN + location.pathname;
+  throw new Error('Reloading with appropriate origin for desired context...');
+}
+
+test(t => {
+  assert_true(window.isSecureContext);
+  assert_idl_attribute(navigator, 'locks',
+                       'navigator.locks exists in secure context');
+  assert_true('LockManager' in self,
+              'LockManager is present in secure contexts');
+  assert_true('Lock' in self,
+              'Lock interface is present in secure contexts');
+}, 'API presence in secure contexts');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/locks/workers.html b/third_party/WebKit/LayoutTests/http/tests/locks/workers.html
new file mode 100644
index 0000000..4c82c0a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/locks/workers.html
@@ -0,0 +1,153 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Web Locks API: Workers</title>
+<link rel=help href="https://github.com/inexorabletash/web-locks">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+let next_request_id = 0;
+function postAndWait(worker, data) {
+  return new Promise(resolve => {
+    worker.postMessage(Object.assign(data, {rqid: next_request_id++}));
+    const listener = event => {
+      if (event.data.rqid !== data.rqid)
+        return;
+      worker.removeEventListener('message', listener);
+      resolve(event.data);
+    };
+    worker.addEventListener('message', listener);
+  });
+}
+
+promise_test(async t => {
+  const worker = new Worker('resources/worker.js');
+  t.add_cleanup(() => { worker.terminate(); });
+
+  const res = 'shared resource 1';
+
+  const data = await postAndWait(
+    worker, {op: 'request', lock_id: 1, scope: res, mode: 'shared'})
+
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+  await navigator.locks.acquire(res, {mode: 'shared'}, async lock => {
+    const data = await postAndWait(worker, {op: 'release', lock_id: 1});
+    assert_equals(data.ack, 'release');
+    assert_equals(data.id, 1);
+  });
+
+}, 'Window and Worker - shared mode');
+
+promise_test(async t => {
+  const worker = new Worker('resources/worker.js');
+  t.add_cleanup(() => { worker.terminate(); });
+
+  const res = 'exclusive resource 1';
+
+  const data = await postAndWait(
+    worker, {op: 'request', lock_id: 1, scope: res})
+
+  // worker has the lock.
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // This request should be blocked.
+  let lock_granted = false;
+  const blocked = navigator.locks.acquire(
+    res, lock => { lock_granted = true; });
+
+  // Verify we can't get it.
+  let available = undefined;
+  await navigator.locks.acquire(
+    res, {ifAvailable: true}, lock => { available = lock !== null; });
+  assert_false(available);
+  assert_false(lock_granted);
+
+  // Ask the worker to release it.
+  const data2 = await postAndWait(worker, {op: 'release', lock_id: 1});
+
+  // worker released it.
+  assert_equals(data2.ack, 'release');
+  assert_equals(data2.id, 1);
+
+  // Now we've got it.
+  const lock2 = await blocked;
+  assert_true(lock_granted);
+
+}, 'Window and Worker - exclusive mode');
+
+promise_test(async t => {
+  const worker1 = new Worker('resources/worker.js');
+  const worker2 = new Worker('resources/worker.js');
+  t.add_cleanup(() => { worker1.terminate(); worker2.terminate(); });
+
+  const res = 'exclusive resource 2';
+
+  const data = await postAndWait(
+    worker1, {op: 'request', lock_id: 1, scope: res})
+
+  // worker1 has the lock.
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // This request should be blocked.
+  let lock_granted = false;
+  const blocked = postAndWait(
+    worker2, {op: 'request', lock_id: 1, scope: res});
+  blocked.then(f => { lock_granted = true; });
+
+  // Verify worker2 can't get it.
+  assert_true((await postAndWait(worker2, {
+    op: 'request', scope: res, lock_id: 2, ifAvailable: true
+  })).failed, 'Lock request should have failed');
+  assert_false(lock_granted);
+
+  // Ask worker1 to release it.
+  const data2 = await postAndWait(worker1, {op: 'release', lock_id: 1});
+
+  // worker1 released it.
+  assert_equals(data2.ack, 'release');
+  assert_equals(data2.id, 1);
+
+  // Now worker2 can get it.
+  const lock = await blocked;
+  assert_true(lock_granted);
+
+}, 'Worker and Worker - exclusive mode');
+
+promise_test(async t => {
+  const worker = new Worker('resources/worker.js');
+
+  const res = 'exclusive resource 3';
+
+  const data = await postAndWait(
+    worker, {op: 'request', lock_id: 1, scope: res})
+
+  // Worker has the lock.
+  assert_equals(data.ack, 'request');
+  assert_equals(data.id, 1);
+
+  // This request should be blocked.
+  let lock_granted = false;
+  const blocked = navigator.locks.acquire(
+    res, lock => { lock_granted = true; });
+
+  // Verify we can't get it.
+  let available = undefined;
+  await navigator.locks.acquire(
+    res, {ifAvailable: true}, lock => { available = lock !== null; });
+  assert_false(available);
+  assert_false(lock_granted);
+
+  // Implicitly release it by terminating the worker.
+  worker.terminate();
+
+  // Now we've got it.
+  const lock = await blocked;
+  assert_true(lock_granted);
+
+}, 'Terminated Worker - exclusive mode');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/notifications/notification-creation-detached-context.html b/third_party/WebKit/LayoutTests/http/tests/notifications/notification-creation-detached-context.html
new file mode 100644
index 0000000..600d7b3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/notifications/notification-creation-detached-context.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Notifications: Creating a notification in a detached context should
+      throw a TypeError.</title>
+    <script src="../resources/testharness.js"></script>
+    <script src="../resources/testharnessreport.js"></script>
+    <script src="resources/test-helpers.js"></script>
+  </head>
+  <body>
+    <script>
+      if (window.testRunner) {
+          testRunner.setPermission('notifications', 'granted', location.origin, location.origin);
+          testRunner.setCanOpenWindows();
+      }
+
+      async_test(test => {
+          const remoteWindow = window.open('resources/window-detached-context.html');
+          let remoteNotificationObj = null;
+
+          window.addEventListener('message', test.step_func(event => {
+              switch (event.data) {
+                  case 'opened':
+                      assert_own_property(remoteWindow, 'Notification');
+                      remoteNotificationObj = remoteWindow.Notification;
+                      remoteWindow.close();
+                      break;
+
+                  case 'closed':
+                      try {
+                          new remoteNotificationObj('Title');
+                          assert_unreached('Expected a TypeError but no error thrown.');
+                      } catch (e) {
+                          assert_equals(e.name, 'TypeError');
+                          assert_equals(
+                              e.message, "Failed to construct 'Notification': Illegal invocation.");
+                      }
+                      test.done();
+                      break;
+                  default:
+                      assert_unreached('Unrecognized message from the opened window.');
+                      break;
+              }
+          }));
+
+      }, 'Creating a notification in a detached context should throw.');
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/notifications/request-permission-detached-context.html b/third_party/WebKit/LayoutTests/http/tests/notifications/request-permission-detached-context.html
index 7e38c89..d57ea9e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/notifications/request-permission-detached-context.html
+++ b/third_party/WebKit/LayoutTests/http/tests/notifications/request-permission-detached-context.html
@@ -16,7 +16,7 @@
       }
 
       async_test(test => {
-          const remoteWindow = window.open('resources/window-permission-detached-context.html');
+          const remoteWindow = window.open('resources/window-detached-context.html');
           let remoteNotificationObj = null;
 
           window.addEventListener('message', test.step_func(event => {
diff --git a/third_party/WebKit/LayoutTests/http/tests/notifications/resources/window-permission-detached-context.html b/third_party/WebKit/LayoutTests/http/tests/notifications/resources/window-detached-context.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/notifications/resources/window-permission-detached-context.html
rename to third_party/WebKit/LayoutTests/http/tests/notifications/resources/window-detached-context.html
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/cross-origin-createImageBitmap-structured-clone.html b/third_party/WebKit/LayoutTests/http/tests/security/cross-origin-createImageBitmap-structured-clone.html
index 776fa17..f38db0f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/cross-origin-createImageBitmap-structured-clone.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/cross-origin-createImageBitmap-structured-clone.html
@@ -39,7 +39,7 @@
         canvas.height = 10;
         var context = canvas.getContext("2d");
         context.drawImage(imageBitmap, 0, 0, 10, 10);
-        assert_throws(null, function () { context.getImageData(0, 0, 10, 10); }, 'ImageBitmap should be tainted');
+        assert_throws('SecurityError', function () { context.getImageData(0, 0, 10, 10); }, 'ImageBitmap should be tainted');
     }
 }, 'Transfer and structured-clone an ImageBitmap should preserve the originClean flag.');
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index fb14276..ea79d00 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -695,6 +695,15 @@
 interface InstallEvent : ExtendableEvent
     attribute @@toStringTag
     method constructor
+interface Lock
+    attribute @@toStringTag
+    getter mode
+    getter scope
+    method constructor
+interface LockManager
+    attribute @@toStringTag
+    method acquire
+    method constructor
 interface MessageChannel
     attribute @@toStringTag
     getter port1
@@ -2546,6 +2555,7 @@
     getter budget
     getter connection
     getter hardwareConcurrency
+    getter locks
     getter onLine
     getter permissions
     getter platform
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/animation-worklet-csp-eval-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/animation-worklet-csp-eval-expected.txt
new file mode 100644
index 0000000..53e750b7d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/animation-worklet-csp-eval-expected.txt
@@ -0,0 +1,7 @@
+CONSOLE ERROR: line 1: Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+
+This is a testharness.js-based test.
+PASS eval() call on the worklet should be blocked because the script-src unsafe-eval directive is not specified.
+PASS eval() call on the worklet should not be blocked because the script-src unsafe-eval directive allows it.
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/animation-worklet-csp-eval.html b/third_party/WebKit/LayoutTests/http/tests/worklet/animation-worklet-csp-eval.html
new file mode 100644
index 0000000..707fc527
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/animation-worklet-csp-eval.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/resources/get-host-info.sub.js"></script>
+    <script src="resources/csp-eval-tests.js"></script>
+</head>
+<body>
+<script>
+    runContentSecurityPolicyEvalTests("animation");
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/paint-worklet-csp-eval-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/paint-worklet-csp-eval-expected.txt
new file mode 100644
index 0000000..55bc307
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/paint-worklet-csp-eval-expected.txt
@@ -0,0 +1,9 @@
+CONSOLE ERROR: line 1: Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+
+CONSOLE ERROR: line 1: Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+
+This is a testharness.js-based test.
+PASS eval() call on the worklet should be blocked because the script-src unsafe-eval directive is not specified.
+PASS eval() call on the worklet should not be blocked because the script-src unsafe-eval directive allows it.
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/paint-worklet-csp-eval.html b/third_party/WebKit/LayoutTests/http/tests/worklet/paint-worklet-csp-eval.html
new file mode 100644
index 0000000..2c921ca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/paint-worklet-csp-eval.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/resources/get-host-info.sub.js"></script>
+    <script src="resources/csp-eval-tests.js"></script>
+</head>
+<body>
+<script>
+    runContentSecurityPolicyEvalTests("paint");
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/resources/addmodule-window-with-unsafe-eval.html b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/addmodule-window-with-unsafe-eval.html
new file mode 100644
index 0000000..4fca2d8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/addmodule-window-with-unsafe-eval.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Worklet: Content-Security-Policy unsafe-eval</title>
+  <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval'">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="worklet-test-utils.js"></script>
+</head>
+<body>
+<script>
+// Calls addModule() on a given worklet type with a script url.
+//
+// [Message Format]
+//   - type: 'paint' (worklet types defined in get_worklet())
+//   - script_url: 'worklet-script.js'
+window.onmessage = e => {
+  const worklet_type = e.data.type;
+  const script_url = e.data.script_url;
+  get_worklet(worklet_type).addModule(script_url)
+      .then(() => window.opener.postMessage('RESOLVED', '*'))
+      .catch(e => window.opener.postMessage('REJECTED', '*'));
+};
+
+window.opener.postMessage('LOADED', '*');
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/resources/addmodule-window.html b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/addmodule-window.html
new file mode 100644
index 0000000..bbff8ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/addmodule-window.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Worklet: Content-Security-Policy unsafe-eval</title>
+  <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
+  <script src="../../resources/testharness.js"></script>
+  <script src="../../resources/testharnessreport.js"></script>
+  <script src="worklet-test-utils.js"></script>
+</head>
+<body>
+<script>
+// Calls addModule() on a given worklet type with a script url.
+//
+// [Message Format]
+//   - type: 'paint' (worklet types defined in get_worklet())
+//   - script_url: 'worklet-script.js'
+window.onmessage = e => {
+  const worklet_type = e.data.type;
+  const script_url = e.data.script_url;
+  get_worklet(worklet_type).addModule(script_url)
+      .then(() => window.opener.postMessage('RESOLVED', '*'))
+      .catch(e => window.opener.postMessage('REJECTED', '*'));
+};
+
+window.opener.postMessage('LOADED', '*');
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/resources/csp-eval-tests.js b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/csp-eval-tests.js
new file mode 100644
index 0000000..2228d27
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/csp-eval-tests.js
@@ -0,0 +1,46 @@
+function openWindow(url) {
+  return new Promise(resolve => {
+    const win = window.open(url, '_blank');
+    add_result_callback(() => win.close());
+    window.onmessage = e => {
+      assert_equals(e.data, 'LOADED');
+      resolve(win);
+    };
+  });
+}
+
+function openWindowAndExpectResult(windowURL, scriptURL, type, expectation) {
+  return openWindow(windowURL).then(win => {
+    const promise = new Promise(r => window.onmessage = r);
+    win.postMessage({ type: type, script_url: scriptURL }, '*');
+    return promise;
+  }).then(msg_event => assert_equals(msg_event.data, expectation));
+}
+
+// Runs a series of tests related to content security policy for eval() on a
+// worklet.
+//
+// Usage:
+// runContentSecurityPolicyEvalTests("paint");
+//
+// These tests should not be upstreamed to WPT because this tests console
+// outputs.
+function runContentSecurityPolicyEvalTests(workletType) {
+  promise_test(t => {
+    const kWindowURL = 'resources/addmodule-window.html';
+    const kScriptURL = 'eval-worklet-script.js';
+    // Note that evaluation failure by disallowed eval() call does not reject
+    // the addModule() promise.
+    return openWindowAndExpectResult(
+        kWindowURL, kScriptURL, workletType, 'RESOLVED');
+  }, 'eval() call on the worklet should be blocked because the script-src ' +
+     'unsafe-eval directive is not specified.');
+
+  promise_test(t => {
+    const kWindowURL = 'resources/addmodule-window-with-unsafe-eval.html';
+    const kScriptURL = 'eval-worklet-script.js';
+    return openWindowAndExpectResult(
+        kWindowURL, kScriptURL, workletType, 'RESOLVED');
+  }, 'eval() call on the worklet should not be blocked because the ' +
+     'script-src unsafe-eval directive allows it.');
+}
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/resources/eval-worklet-script.js b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/eval-worklet-script.js
new file mode 100644
index 0000000..a21e169
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/eval-worklet-script.js
@@ -0,0 +1 @@
+eval('const kImportantNumber = 42;');
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/resources/worklet-test-utils.js b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/worklet-test-utils.js
new file mode 100644
index 0000000..4912dadb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/resources/worklet-test-utils.js
@@ -0,0 +1,8 @@
+// Returns a reference to a worklet object corresponding to a given type.
+function get_worklet(type) {
+  if (type == 'paint')
+    return CSS.paintWorklet;
+  if (type == 'animation')
+    return window.animationWorklet;
+  return undefined;
+}
diff --git a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc002-bom.html b/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc002-bom.html
deleted file mode 100644
index ced7e486..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc002-bom.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<title>Tests that the parser properly ignores a UTF-8 BOM character at the beginning of a file and all other cues are properly parsed.</title>
-<script src="track-helpers.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-    <track src="captions-webvtt/tc002-bom.vtt" default>
-</video>
-<script>
-async_test(function(t) {
-    var track = document.querySelector("track");
-
-    track.onload = t.step_func_done(function() {
-        var expected = [
-            {
-                id : "1",
-                startTime : 0,
-                endTime : 30.5,
-                text : "Bear is Coming!!!!!"
-            },
-            {
-                id : "2",
-                startTime : 31,
-                endTime : 1200.5,
-                text : "I said Bear is coming!!!!"
-            }
-        ];
-
-        var cues = track.track.cues;
-        assert_equals(cues.length, 2);
-        assert_cues_equal(cues, expected);
-    });
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc003-newlines.html b/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc003-newlines.html
deleted file mode 100644
index dd9a118e..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-webvtt-tc003-newlines.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<title>Tests that a cue with no newline at eof is properly parsed.</title>
-<script src="track-helpers.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-    <track src="captions-webvtt/tc003-no-newline-at-eof.vtt" default>
-</video>
-<script>
-async_test(function(t) {
-    var track = document.querySelector("track");
-
-    track.onload = t.step_func_done(function() {
-        var expected = [
-            {
-                id : "1",
-                startTime : 0,
-                endTime : 30.5,
-                text : "Bear is Coming!!!!!"
-            }
-        ];
-
-        assert_cues_equal(track.track.cues, expected);
-    });
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
index 7b3d3c5..88f7e9d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/border-radius-composited-subframe-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/border-radius-composited-subframe-expected.png
new file mode 100644
index 0000000..7f12c54
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/border-radius-composited-subframe-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/border-radius-composited-subframe-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/border-radius-composited-subframe-expected.txt
new file mode 100644
index 0000000..baa393318
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overflow/border-radius-composited-subframe-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x210
+  LayoutBlockFlow {HTML} at (0,0) size 800x210
+    LayoutBlockFlow {BODY} at (8,8) size 784x194
+      LayoutText {#text} at (290,176) size 4x18
+        text run at (290,176) width 4: " "
+      LayoutText {#text} at (0,0) size 0x0
+layer at (18,18) size 270x170 clip at (28,28) size 250x150
+  LayoutIFrame {IFRAME} at (10,10) size 270x170 [bgcolor=#0000FF] [border: (10px solid #808080)]
+    layer at (0,0) size 250x150
+      LayoutView at (0,0) size 250x150
+    layer at (0,0) size 250x8
+      LayoutBlockFlow {HTML} at (0,0) size 250x8
+        LayoutBlockFlow {BODY} at (8,8) size 234x0
+    layer at (0,5) size 250x140
+      LayoutBlockFlow (positioned) {DIV} at (0,5) size 250x140 [bgcolor=#008000]
+layer at (312,18) size 270x170 clip at (322,28) size 250x150
+  LayoutIFrame {IFRAME} at (304,10) size 270x170 [bgcolor=#0000FF] [border: (10px solid #808080)]
+    layer at (0,0) size 250x150
+      LayoutView at (0,0) size 250x150
+    layer at (0,0) size 250x8
+      LayoutBlockFlow {HTML} at (0,0) size 250x8
+        LayoutBlockFlow {BODY} at (8,8) size 234x0
+    layer at (0,5) size 250x140
+      LayoutBlockFlow (positioned) {DIV} at (0,5) size 250x140 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
index f1b87c9d..75b31122 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-composited-subframe-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-composited-subframe-expected.png
new file mode 100644
index 0000000..1b7b5f0a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-composited-subframe-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-composited-subframe-expected.txt b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-composited-subframe-expected.txt
new file mode 100644
index 0000000..38a5bb2a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-composited-subframe-expected.txt
@@ -0,0 +1,26 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x211
+  LayoutBlockFlow {HTML} at (0,0) size 800x211
+    LayoutBlockFlow {BODY} at (8,8) size 784x195
+      LayoutText {#text} at (290,175) size 4x19
+        text run at (290,175) width 4: " "
+      LayoutText {#text} at (0,0) size 0x0
+layer at (18,18) size 270x170 clip at (28,28) size 250x150
+  LayoutIFrame {IFRAME} at (10,10) size 270x170 [bgcolor=#0000FF] [border: (10px solid #808080)]
+    layer at (0,0) size 250x150
+      LayoutView at (0,0) size 250x150
+    layer at (0,0) size 250x8
+      LayoutBlockFlow {HTML} at (0,0) size 250x8
+        LayoutBlockFlow {BODY} at (8,8) size 234x0
+    layer at (0,5) size 250x140
+      LayoutBlockFlow (positioned) {DIV} at (0,5) size 250x140 [bgcolor=#008000]
+layer at (312,18) size 270x170 clip at (322,28) size 250x150
+  LayoutIFrame {IFRAME} at (304,10) size 270x170 [bgcolor=#0000FF] [border: (10px solid #808080)]
+    layer at (0,0) size 250x150
+      LayoutView at (0,0) size 250x150
+    layer at (0,0) size 250x8
+      LayoutBlockFlow {HTML} at (0,0) size 250x8
+        LayoutBlockFlow {BODY} at (8,8) size 234x0
+    layer at (0,5) size 250x140
+      LayoutBlockFlow (positioned) {DIV} at (0,5) size 250x140 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
index 877f319..d106386a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe-expected.txt
deleted file mode 100644
index 49f9954..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-Test that evaluation on call frame works across all inspected windows in the call stack.
-
-Set timer for test function.
-Call stack:
-    0) pauseInsideIframe (:6)
-    1) testFunction (debugger-eval-on-call-frame-inside-iframe.html:35)
-
-=== Evaluating on iframe ===
-dir() = "overridden dir() in iframe"
-dirxml() = undefined
-table = "local in iframe"
-clear = 
-x: = VM:1 Uncaught SyntaxError {message: "Unexpected end of input"}pauseInsideIframe @ VM:6testFunction @ debugger-eval-on-call-frame-inside-iframe.html:35
-
-=== Evaluating on top frame ===
-dir() = undefined
-dirxml() = "overridden dirxml() in top frame"
-table = 
-clear = "local in top frame"
-x: = VM:1 Uncaught SyntaxError: Unexpected end of input(…)pauseInsideIframe @ VM:6testFunction @ debugger-eval-on-call-frame-inside-iframe.html:35
-
diff --git a/third_party/WebKit/LayoutTests/platform/win7/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/win7/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
index 380301d..6a4680ee 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/numbers-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/computedstyle/numbers-expected.txt
deleted file mode 100644
index 55d01120..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/computedstyle/numbers-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Single valued CSSUnitValues can be retrieved from Computed StyleMap assert_equals: expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Can retrieve list of CSSUnitValues from list-valued property assert_equals: expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/numbers-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/numbers-expected.txt
deleted file mode 100644
index fb42d3f..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/numbers-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Single valued CSSUnitValues can be retrieved from Inline StyleMap assert_equals: result from undefined expected "CSSUnitValue" but got "CSSStyleValue"
-FAIL Can retrieve list of CSSUnitValues from list-valued property assert_equals: expected 3 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-numeric.html b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-numeric.html
new file mode 100644
index 0000000..dbaa7ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-numeric.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Numeric normalization tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#normalize-numeric">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../resources/testhelper.js"></script>
+<script>
+'use strict';
+
+function test_numeric_normalization(property, cssText, expected) {
+  assert_style_value_equals(CSSStyleValue.parse(property, cssText), expected);
+  assert_style_value_equals(
+      newDivWithStyle(property + ': ' + cssText).attributeStyleMap.get(property),
+      expected);
+}
+
+test(() => {
+  test_numeric_normalization('line-height', '3.14', CSS.number(3.14));
+}, 'Normalizing a <number> returns a number CSSUnitValue');
+
+test(() => {
+  test_numeric_normalization('width', '3.14%', CSS.percent(3.14));
+}, 'Normalizing a <percentage> returns a percent CSSUnitValue');
+
+test(() => {
+  test_numeric_normalization('width', '3.14px', CSS.px(3.14));
+}, 'Normalizing a <dimension> returns a CSSUnitValue with the correct unit');
+
+test(() => {
+  test_numeric_normalization('width', '0', CSS.px(0));
+}, 'Normalizing a <dimension> with a unitless zero returns 0px');
+
+test(() => {
+  test_numeric_normalization('z-index', '0', CSS.number(0));
+}, 'Normalizing a <number> with a unitless zero returns 0');
+
+test(() => {
+  test_numeric_normalization('width',
+      'calc(1px + calc(1px) + calc(1px * 2) + 1%)',
+      new CSSMathSum(CSS.px(4), CSS.percent(1)));
+}, 'Normalizing a <calc> returns simplified expression');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/inline/README.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/inline/README.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/inline/README.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/inline/README.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/inline/absolute-positioned-block-in-centred-block-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/inline/absolute-positioned-block-in-centred-block-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/inline/absolute-positioned-block-in-centred-block-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/inline/absolute-positioned-block-in-centred-block-expected.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlinesWithWS-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/inline/drawStyledEmptyInlinesWithWS-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlinesWithWS-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/inline/drawStyledEmptyInlinesWithWS-expected.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/README.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/README.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/README.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/README.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/floats-in-block-layout-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/floats-in-block-layout-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/floats-in-block-layout-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/floats-in-block-layout-expected.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/inline-direction-positioning-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/inline-direction-positioning-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/inline-direction-positioning-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/inline-direction-positioning-expected.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/margin-collapse-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/margin-collapse-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/margin-collapse-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/margin-collapse-expected.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/root-lr-basic-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/root-lr-basic-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/root-lr-basic-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/root-lr-basic-expected.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/self-collapsing-block-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/self-collapsing-block-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/self-collapsing-block-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/self-collapsing-block-expected.txt
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/table-percent-width-quirk-expected.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/table-percent-width-quirk-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/virtual/layout_ng_paint/fast/writing-mode/table-percent-width-quirk-expected.txt
rename to third_party/WebKit/LayoutTests/virtual/layout_ng/fast/writing-mode/table-percent-width-quirk-expected.txt
diff --git a/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html b/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html
index f8d5f45..63cbea4 100644
--- a/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html
+++ b/third_party/WebKit/LayoutTests/vr/getEyeParameters_match.html
@@ -10,7 +10,7 @@
 <script src="resources/presentation-setup.js"></script>
 <script>
 let fakeDisplays = fakeVRDisplays();
-let fakeDisplay = fakeDisplays["FakeMagicWindowOnly"];
+let fakeDisplay = fakeDisplays["Pixel"];
 
 vr_test( (t) => {
   return navigator.getVRDisplays().then( (displays) => {
@@ -20,7 +20,7 @@
       t.step( () => {
         assert_equals(actual.offset.length, expected.offset.length);
         for (let i = 0; i < expected.offset.length; i++) {
-          assert_approx_equals(actual.offset[i], actual.offset[i],
+          assert_approx_equals(actual.offset[i], expected.offset[i],
               FLOAT_EPSILON);
         }
 
diff --git a/third_party/WebKit/LayoutTests/vr/getEyeParameters_null.html b/third_party/WebKit/LayoutTests/vr/getEyeParameters_null.html
new file mode 100644
index 0000000..44c854e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/vr/getEyeParameters_null.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="resources/fake-vr-displays.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/device/vr/vr_service.mojom.js"></script>
+<script src="resources/mock-vr-service.js"></script>
+<script src="resources/test-constants.js"></script>
+<canvas id="webgl-canvas"></canvas>
+<script src="resources/presentation-setup.js"></script>
+<script>
+let fakeDisplays = fakeVRDisplays();
+let fakeDisplay = fakeDisplays["FakeMagicWindowOnly"];
+
+vr_test( (t) => {
+  return navigator.getVRDisplays().then( (displays) => {
+    let display = displays[0];
+
+    t.step( () => {
+      console.log(display.getEyeParameters);
+      assert_equals(display.getEyeParameters("left"), null);
+      assert_equals(display.getEyeParameters("right"), null);
+    }, "Eye parameters are null");
+
+    t.done();
+  }, (err) => {
+    t.step( () => {
+      assert_unreached(err);
+    }, "getVRDisplays rejected");
+    t.done();
+  });
+}, [fakeDisplay],
+"Test that device which doesn't present has no eye parameters");
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js b/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js
index a5cc8884..c65733a 100644
--- a/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js
+++ b/third_party/WebKit/LayoutTests/vr/resources/fake-vr-displays.js
@@ -38,8 +38,8 @@
         canPresent : false
       },
       stageParameters : null,
-      leftEye : generic_left_eye,
-      rightEye : generic_right_eye,
+      leftEye : null,
+      rightEye : null,
     },
 
     FakeRoomScale: {
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 8c083674..55837ba 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -642,6 +642,15 @@
 [Worker]     getter width
 [Worker]     method constructor
 [Worker]     method getColorSettings
+[Worker] interface Lock
+[Worker]     attribute @@toStringTag
+[Worker]     getter mode
+[Worker]     getter scope
+[Worker]     method constructor
+[Worker] interface LockManager
+[Worker]     attribute @@toStringTag
+[Worker]     method acquire
+[Worker]     method constructor
 [Worker] interface MessageChannel
 [Worker]     attribute @@toStringTag
 [Worker]     getter port1
@@ -2457,6 +2466,7 @@
 [Worker]     getter budget
 [Worker]     getter connection
 [Worker]     getter hardwareConcurrency
+[Worker]     getter locks
 [Worker]     getter onLine
 [Worker]     getter permissions
 [Worker]     getter platform
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 4d3e3e5..3b8a815 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3958,6 +3958,15 @@
 interface Location
     attribute @@toStringTag
     method constructor
+interface Lock
+    attribute @@toStringTag
+    getter mode
+    getter scope
+    method constructor
+interface LockManager
+    attribute @@toStringTag
+    method acquire
+    method constructor
 interface MIDIAccess : EventTarget
     attribute @@toStringTag
     getter inputs
@@ -4462,6 +4471,7 @@
     getter hardwareConcurrency
     getter language
     getter languages
+    getter locks
     getter maxTouchPoints
     getter mediaCapabilities
     getter mediaDevices
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index a30a0e11..1dd2fe5 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -637,6 +637,15 @@
 [Worker]     getter width
 [Worker]     method constructor
 [Worker]     method getColorSettings
+[Worker] interface Lock
+[Worker]     attribute @@toStringTag
+[Worker]     getter mode
+[Worker]     getter scope
+[Worker]     method constructor
+[Worker] interface LockManager
+[Worker]     attribute @@toStringTag
+[Worker]     method acquire
+[Worker]     method constructor
 [Worker] interface MessageChannel
 [Worker]     attribute @@toStringTag
 [Worker]     getter port1
@@ -2457,6 +2466,7 @@
 [Worker]     getter budget
 [Worker]     getter connection
 [Worker]     getter hardwareConcurrency
+[Worker]     getter locks
 [Worker]     getter onLine
 [Worker]     getter permissions
 [Worker]     getter platform
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
index 2b8a2e3..edd9aada 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -50,6 +50,8 @@
   "$bindings_core_v8_output_dir/html_element_or_long.h",
   "$bindings_core_v8_output_dir/image_bitmap_source.cc",
   "$bindings_core_v8_output_dir/image_bitmap_source.h",
+  "$bindings_core_v8_output_dir/internal_enum_or_internal_enum_sequence.cc",
+  "$bindings_core_v8_output_dir/internal_enum_or_internal_enum_sequence.h",
   "$bindings_core_v8_output_dir/html_option_element_or_html_opt_group_element.cc",
   "$bindings_core_v8_output_dir/html_option_element_or_html_opt_group_element.h",
   "$bindings_core_v8_output_dir/html_script_element_or_svg_script_element.cc",
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
index c34ed7e7..de29490d 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
@@ -85,7 +85,7 @@
 
 namespace {
 
-V8CacheOptions CacheOptions(const ScriptResource* resource,
+V8CacheOptions CacheOptions(const CachedMetadataHandler* cache_handler,
                             const Settings* settings) {
   V8CacheOptions v8_cache_options(kV8CacheOptionsDefault);
   if (settings) {
@@ -95,7 +95,7 @@
   }
   // If the resource is served from CacheStorage, generate the V8 code cache in
   // the first load.
-  if (resource && !resource->GetResponse().CacheStorageCacheName().IsNull())
+  if (cache_handler && cache_handler->IsServedFromCacheStorage())
     return kV8CacheOptionsCodeWithoutHeatCheck;
   return v8_cache_options;
 }
@@ -113,8 +113,11 @@
                                          source.StartPosition()));
   v8::Local<v8::Value> result;
   {
+    CachedMetadataHandler* cache_handler =
+        source.GetResource() ? source.GetResource()->CacheHandler() : nullptr;
+
     V8CacheOptions v8_cache_options =
-        CacheOptions(source.GetResource(), GetFrame()->GetSettings());
+        CacheOptions(cache_handler, GetFrame()->GetSettings());
 
     // Isolate exceptions that occur when compiling and executing
     // the code. These exceptions should not interfere with
@@ -123,9 +126,6 @@
     v8::TryCatch try_catch(GetIsolate());
     try_catch.SetVerbose(true);
 
-    CachedMetadataHandler* cache_handler =
-        source.GetResource() ? source.GetResource()->CacheHandler() : nullptr;
-
     const ReferrerScriptInfo referrer_info(fetch_options.CredentialsMode(),
                                            fetch_options.Nonce(),
                                            fetch_options.ParserState());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp
index adfb391..573ba67 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp
@@ -6,62 +6,9 @@
 
 namespace blink {
 
-ScriptSourceCode::ScriptSourceCode(
-    const String& source,
-    ScriptSourceLocationType source_location_type,
-    const KURL& url,
-    const TextPosition& start_position)
-    : source_(source),
-      url_(url),
-      start_position_(start_position),
-      source_location_type_(source_location_type) {
-  // External files should use a ScriptResource.
-  DCHECK(source_location_type != ScriptSourceLocationType::kExternalFile);
+namespace {
 
-  TreatNullSourceAsEmpty();
-  if (!url_.IsEmpty())
-    url_.RemoveFragmentIdentifier();
-}
-
-ScriptSourceCode::ScriptSourceCode(ScriptStreamer* streamer,
-                                   ScriptResource* resource)
-    : source_(resource->SourceText()),
-      resource_(resource),
-      streamer_(streamer),
-      start_position_(TextPosition::MinimumPosition()),
-      source_location_type_(ScriptSourceLocationType::kExternalFile) {
-  TreatNullSourceAsEmpty();
-}
-
-ScriptSourceCode::~ScriptSourceCode() {}
-
-void ScriptSourceCode::Trace(blink::Visitor* visitor) {
-  visitor->Trace(resource_);
-  visitor->Trace(streamer_);
-}
-
-const KURL& ScriptSourceCode::Url() const {
-  if (url_.IsEmpty() && resource_) {
-    url_ = resource_->GetResponse().Url();
-    if (!url_.IsEmpty())
-      url_.RemoveFragmentIdentifier();
-  }
-  return url_;
-}
-
-String ScriptSourceCode::SourceMapUrl() const {
-  if (!resource_)
-    return String();
-  const ResourceResponse& response = resource_->GetResponse();
-  String source_map_url = response.HttpHeaderField(HTTPNames::SourceMap);
-  if (source_map_url.IsEmpty()) {
-    // Try to get deprecated header.
-    source_map_url = response.HttpHeaderField(HTTPNames::X_SourceMap);
-  }
-  return source_map_url;
-}
-
-void ScriptSourceCode::TreatNullSourceAsEmpty() {
+String TreatNullSourceAsEmpty(const String& source) {
   // ScriptSourceCode allows for the representation of the null/not-there-really
   // ScriptSourceCode value.  Encoded by way of a m_source.isNull() being true,
   // with the nullary constructor to be used to construct such a value.
@@ -70,8 +17,71 @@
   // as representing the empty script. Consequently, we need to disambiguate
   // between such null string occurrences.  Do that by converting the latter
   // case's null strings into empty ones.
-  if (source_.IsNull())
-    source_ = "";
+  if (source.IsNull())
+    return "";
+
+  return source;
+}
+
+KURL StripFragmentIdentifier(const KURL& url) {
+  if (url.IsEmpty())
+    return KURL();
+
+  if (!url.HasFragmentIdentifier())
+    return url;
+
+  KURL copy = url;
+  copy.RemoveFragmentIdentifier();
+  return copy;
+}
+
+String SourceMapUrlFromResponse(const ResourceResponse& response) {
+  String source_map_url = response.HttpHeaderField(HTTPNames::SourceMap);
+  if (!source_map_url.IsEmpty())
+    return source_map_url;
+
+  // Try to get deprecated header.
+  return response.HttpHeaderField(HTTPNames::X_SourceMap);
+}
+
+}  // namespace
+
+ScriptSourceCode::ScriptSourceCode(
+    const String& source,
+    ScriptSourceLocationType source_location_type,
+    const KURL& url,
+    const TextPosition& start_position)
+    : source_(TreatNullSourceAsEmpty(source)),
+      url_(StripFragmentIdentifier(url)),
+      start_position_(start_position),
+      source_location_type_(source_location_type) {
+  // External files should use a ScriptResource.
+  DCHECK(source_location_type != ScriptSourceLocationType::kExternalFile);
+}
+
+ScriptSourceCode::ScriptSourceCode(ScriptStreamer* streamer,
+                                   ScriptResource* resource)
+    : source_(TreatNullSourceAsEmpty(resource->SourceText())),
+      resource_(resource),
+      streamer_(streamer),
+      url_(StripFragmentIdentifier(resource->GetResponse().Url())),
+      source_map_url_(SourceMapUrlFromResponse(resource->GetResponse())),
+      start_position_(TextPosition::MinimumPosition()),
+      source_location_type_(ScriptSourceLocationType::kExternalFile) {}
+
+ScriptSourceCode::~ScriptSourceCode() {}
+
+void ScriptSourceCode::Trace(blink::Visitor* visitor) {
+  visitor->Trace(resource_);
+  visitor->Trace(streamer_);
+}
+
+KURL ScriptSourceCode::Url() const {
+  return url_;
+}
+
+String ScriptSourceCode::SourceMapUrl() const {
+  return source_map_url_;
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h
index 52bb2bfd..30e8775 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h
@@ -68,7 +68,7 @@
 
   const String& Source() const { return source_; }
   ScriptResource* GetResource() const { return resource_; }
-  const KURL& Url() const;
+  KURL Url() const;
   int StartLine() const { return start_position_.line_.OneBasedInt(); }
   const TextPosition& StartPosition() const { return start_position_; }
   ScriptSourceLocationType SourceLocationType() const {
@@ -79,14 +79,13 @@
   ScriptStreamer* Streamer() const { return streamer_; }
 
  private:
-  void TreatNullSourceAsEmpty();
-
-  String source_;
+  const String source_;
   Member<ScriptResource> resource_;
   Member<ScriptStreamer> streamer_;
-  mutable KURL url_;
-  TextPosition start_position_;
-  ScriptSourceLocationType source_location_type_;
+  const KURL url_;
+  const String source_map_url_;
+  const TextPosition start_position_;
+  const ScriptSourceLocationType source_location_type_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8IdleTaskRunner.h b/third_party/WebKit/Source/bindings/core/v8/V8IdleTaskRunner.h
index 8f6479c..4c722e5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8IdleTaskRunner.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8IdleTaskRunner.h
@@ -38,19 +38,6 @@
 
 namespace blink {
 
-class V8IdleTaskAdapter : public WebThread::IdleTask {
-  USING_FAST_MALLOC(V8IdleTaskAdapter);
-  WTF_MAKE_NONCOPYABLE(V8IdleTaskAdapter);
-
- public:
-  V8IdleTaskAdapter(v8::IdleTask* task) : task_(WTF::WrapUnique(task)) {}
-  ~V8IdleTaskAdapter() override {}
-  void Run(double delay_seconds) override { task_->Run(delay_seconds); }
-
- private:
-  std::unique_ptr<v8::IdleTask> task_;
-};
-
 class V8IdleTaskRunner : public gin::V8IdleTaskRunner {
   USING_FAST_MALLOC(V8IdleTaskRunner);
   WTF_MAKE_NONCOPYABLE(V8IdleTaskRunner);
@@ -60,7 +47,8 @@
   ~V8IdleTaskRunner() override {}
   void PostIdleTask(v8::IdleTask* task) override {
     DCHECK(RuntimeEnabledFeatures::V8IdleTasksEnabled());
-    scheduler_->PostIdleTask(BLINK_FROM_HERE, new V8IdleTaskAdapter(task));
+    scheduler_->PostIdleTask(
+        BLINK_FROM_HERE, WTF::Bind(&v8::IdleTask::Run, WTF::WrapUnique(task)));
   }
 
  private:
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
index e0d6b7fa..8c51a14e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
@@ -278,7 +278,7 @@
   return script;
 }
 
-typedef Function<v8::MaybeLocal<v8::Script>(
+typedef base::OnceCallback<v8::MaybeLocal<v8::Script>(
     v8::Isolate*,
     v8::Local<v8::String>,
     v8::ScriptOrigin,
diff --git a/third_party/WebKit/Source/bindings/modules/BUILD.gn b/third_party/WebKit/Source/bindings/modules/BUILD.gn
index 9515aeb..cc39640 100644
--- a/third_party/WebKit/Source/bindings/modules/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/modules/BUILD.gn
@@ -75,7 +75,6 @@
   ]
   deps = make_core_generated_deps + [ "//third_party/WebKit/Source/bindings/modules:modules_bindings_generated_event_interfaces" ]
   deps += [
-    "//device/vr:mojo_bindings_blink",
     "//media/midi:mojo_blink",
     "//services/device/public/interfaces:generic_sensor_blink",
   ]
diff --git a/third_party/WebKit/Source/bindings/modules/v8/generated.gni b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
index 2d2836c..356d873e8 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/generated.gni
+++ b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
@@ -87,6 +87,8 @@
   "$bindings_modules_v8_output_dir/v8_database_callback.h",
   "$bindings_modules_v8_output_dir/v8_idb_observer_callback.cc",
   "$bindings_modules_v8_output_dir/v8_idb_observer_callback.h",
+  "$bindings_modules_v8_output_dir/v8_lock_granted_callback.cc",
+  "$bindings_modules_v8_output_dir/v8_lock_granted_callback.h",
   "$bindings_modules_v8_output_dir/v8_media_session_action_handler.cc",
   "$bindings_modules_v8_output_dir/v8_media_session_action_handler.h",
   "$bindings_modules_v8_output_dir/v8_position_callback.cc",
diff --git a/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueSerializerForModulesTest.cpp b/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueSerializerForModulesTest.cpp
index c1aabc4..421b694 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueSerializerForModulesTest.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueSerializerForModulesTest.cpp
@@ -253,7 +253,7 @@
 class WebCryptoResultAdapter : public ScriptFunction {
  private:
   WebCryptoResultAdapter(ScriptState* script_state,
-                         WTF::RepeatingFunction<void(T)> function)
+                         base::RepeatingCallback<void(T)> function)
       : ScriptFunction(script_state), function_(std::move(function)) {}
 
   ScriptValue Call(ScriptValue value) final {
@@ -261,15 +261,15 @@
     return ScriptValue::From(GetScriptState(), ToV8UndefinedGenerator());
   }
 
-  WTF::RepeatingFunction<void(T)> function_;
+  base::RepeatingCallback<void(T)> function_;
   template <typename U>
   friend WebCryptoResult ToWebCryptoResult(ScriptState*,
-                                           WTF::RepeatingFunction<void(U)>);
+                                           base::RepeatingCallback<void(U)>);
 };
 
 template <typename T>
 WebCryptoResult ToWebCryptoResult(ScriptState* script_state,
-                                  WTF::RepeatingFunction<void(T)> function) {
+                                  base::RepeatingCallback<void(T)> function) {
   CryptoResultImpl* result = CryptoResultImpl::Create(script_state);
   result->Promise().Then(
       (new WebCryptoResultAdapter<T>(script_state, std::move(function)))
diff --git a/third_party/WebKit/Source/bindings/modules/v8/wasm/WasmResponseExtensions.cpp b/third_party/WebKit/Source/bindings/modules/v8/wasm/WasmResponseExtensions.cpp
index cfc8d63..c8acf82 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/wasm/WasmResponseExtensions.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/wasm/WasmResponseExtensions.cpp
@@ -13,6 +13,7 @@
 #include "modules/fetch/BodyStreamBuffer.h"
 #include "modules/fetch/FetchDataLoader.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/bindings/V8PerIsolateData.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -171,13 +172,23 @@
 
 // See https://crbug.com/708238 for tracking avoiding the hand-generated code.
 void WasmCompileStreamingImpl(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  v8::Isolate* isolate = args.GetIsolate();
   ScriptState* script_state = ScriptState::ForCurrentRealm(args);
+  V8PerIsolateData* per_isolate_data =
+      V8PerIsolateData::From(script_state->GetIsolate());
 
-  // TODO(yukishiino): The following code creates a new v8::FunctionTemplate
-  // for every call, and leaks it.  Should reuse the same v8::FunctionTemplate.
-  v8::Local<v8::Function> compile_callback =
-      v8::Function::New(isolate, CompileFromResponseCallback);
+  // An unique key of the v8::FunctionTemplate cache in V8PerIsolateData.
+  // Everyone uses address of something as a key, so the address of |unique_key|
+  // is guaranteed to be unique for the function template cache.
+  static const int unique_key = 0;
+  v8::Local<v8::FunctionTemplate> function_template =
+      per_isolate_data->FindOrCreateOperationTemplate(
+          script_state->World(), &unique_key, CompileFromResponseCallback,
+          v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 1);
+  v8::Local<v8::Function> compile_callback;
+  if (!function_template->GetFunction(script_state->GetContext())
+           .ToLocal(&compile_callback)) {
+    return;  // Throw an exception.
+  }
 
   // treat either case of parameter as
   // Promise.resolve(parameter)
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_types.py b/third_party/WebKit/Source/bindings/scripts/v8_types.py
index 16191434..c5959bc 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_types.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -657,7 +657,11 @@
     elif idl_type.is_union_type:
         nullable = 'UnionTypeConversionMode::kNullable' if idl_type.includes_nullable_type \
             else 'UnionTypeConversionMode::kNotNullable'
-        cpp_expression_format = 'V8{idl_type}::ToImpl({isolate}, {v8_value}, {variable_name}, %s, exceptionState)' % nullable
+        # We need to consider the moving of the null through the union in order
+        # to generate the correct V8* class name.
+        this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes)
+        cpp_expression_format = '%s::ToImpl({isolate}, {v8_value}, {variable_name}, %s, exceptionState)' % \
+            (v8_type(this_cpp_type), nullable)
     elif idl_type.use_output_parameter_for_result:
         cpp_expression_format = 'V8{idl_type}::ToImpl({isolate}, {v8_value}, {variable_name}, exceptionState)'
     elif idl_type.is_callback_function:
@@ -1039,7 +1043,7 @@
     else:
         raise ValueError('Unsupported literal type: ' + idl_literal.idl_type)
 
-    return '%s::From%s(%s)' % (idl_type.name, member_type.name,
+    return '%s::From%s(%s)' % (idl_type.cpp_type_args(), member_type.name,
                                member_type.literal_cpp_value(idl_literal))
 
 
diff --git a/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl
index 15538fd..7bf5836f 100644
--- a/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl
@@ -111,6 +111,11 @@
   {# 11.1, 11.2. Sequences and frozen arrays #}
   if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) {
     {{v8_value_to_local_cpp_value(array_or_sequence_type) | indent}}
+    {% if array_or_sequence_type.enum_values %}
+    {{declare_enum_validation_variable(array_or_sequence_type.enum_values) | indent(4)}}
+    if (!IsValidEnum(cppValue, validValues, WTF_ARRAY_LENGTH(validValues), "{{array_or_sequence_type.type_name}}", exceptionState))
+      return;
+    {% endif %}
     impl.Set{{array_or_sequence_type.type_name}}(cppValue);
     return;
   }
diff --git a/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl b/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl
index 8432d04..da5b741 100644
--- a/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl
+++ b/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl
@@ -49,4 +49,5 @@
     [Clamp] long applicableToTypeLongMember;
     [TreatNullAs=EmptyString] DOMString applicableToTypeStringMember;
     (double or sequence<double>) unionMemberWithSequenceDefault = [];
+    (TestEnum or sequence<TestEnum>) testEnumOrTestEnumSequenceMember;
 };
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp
index 649bbe22..e509923f 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp
@@ -102,6 +102,10 @@
   has_string_sequence_member_ = true;
 }
 
+void TestDictionary::setTestEnumOrTestEnumSequenceMember(const TestEnumOrTestEnumSequence& value) {
+  test_enum_or_test_enum_sequence_member_ = value;
+}
+
 void TestDictionary::setTestInterface2OrUint8ArrayMember(const TestInterface2OrUint8Array& value) {
   test_interface_2_or_uint8_array_member_ = value;
 }
@@ -147,6 +151,7 @@
   visitor->Trace(garbage_collected_record_member_);
   visitor->Trace(internal_dictionary_sequence_member_);
   visitor->Trace(other_double_or_string_member_);
+  visitor->Trace(test_enum_or_test_enum_sequence_member_);
   visitor->Trace(test_interface_2_or_uint8_array_member_);
   visitor->Trace(test_interface_garbage_collected_member_);
   visitor->Trace(test_interface_garbage_collected_or_null_member_);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
index 8f694146..02f22cec 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
@@ -18,6 +18,7 @@
 #include "bindings/core/v8/double_or_string.h"
 #include "bindings/core/v8/float_or_boolean.h"
 #include "bindings/core/v8/long_or_boolean.h"
+#include "bindings/core/v8/test_enum_or_test_enum_sequence.h"
 #include "bindings/core/v8/test_interface_2_or_uint8_array.h"
 #include "bindings/tests/idls/core/TestInterface2.h"
 #include "core/CoreExport.h"
@@ -246,6 +247,12 @@
   }
   void setStringSequenceMember(const Vector<String>&);
 
+  bool hasTestEnumOrTestEnumSequenceMember() const { return !test_enum_or_test_enum_sequence_member_.IsNull(); }
+  const TestEnumOrTestEnumSequence& testEnumOrTestEnumSequenceMember() const {
+    return test_enum_or_test_enum_sequence_member_;
+  }
+  void setTestEnumOrTestEnumSequenceMember(const TestEnumOrTestEnumSequence&);
+
   bool hasTestInterface2OrUint8ArrayMember() const { return !test_interface_2_or_uint8_array_member_.IsNull(); }
   const TestInterface2OrUint8Array& testInterface2OrUint8ArrayMember() const {
     return test_interface_2_or_uint8_array_member_;
@@ -397,6 +404,7 @@
   String string_member_;
   String string_or_null_member_;
   Vector<String> string_sequence_member_;
+  TestEnumOrTestEnumSequence test_enum_or_test_enum_sequence_member_;
   TestInterface2OrUint8Array test_interface_2_or_uint8_array_member_;
   Member<TestInterfaceGarbageCollected> test_interface_garbage_collected_member_;
   Member<TestInterfaceGarbageCollected> test_interface_garbage_collected_or_null_member_;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
index c1bfc8a5..fca47ee6 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
@@ -65,6 +65,7 @@
     "stringMember",
     "stringOrNullMember",
     "stringSequenceMember",
+    "testEnumOrTestEnumSequenceMember",
     "testInterface2OrUint8ArrayMember",
     "testInterfaceGarbageCollectedMember",
     "testInterfaceGarbageCollectedOrNullMember",
@@ -515,8 +516,23 @@
     impl.setStringSequenceMember(stringSequenceMemberCppValue);
   }
 
+  v8::Local<v8::Value> testEnumOrTestEnumSequenceMemberValue;
+  if (!v8Object->Get(context, keys[31].Get(isolate)).ToLocal(&testEnumOrTestEnumSequenceMemberValue)) {
+    exceptionState.RethrowV8Exception(block.Exception());
+    return;
+  }
+  if (testEnumOrTestEnumSequenceMemberValue.IsEmpty() || testEnumOrTestEnumSequenceMemberValue->IsUndefined()) {
+    // Do nothing.
+  } else {
+    TestEnumOrTestEnumSequence testEnumOrTestEnumSequenceMemberCppValue;
+    V8TestEnumOrTestEnumSequence::ToImpl(isolate, testEnumOrTestEnumSequenceMemberValue, testEnumOrTestEnumSequenceMemberCppValue, UnionTypeConversionMode::kNotNullable, exceptionState);
+    if (exceptionState.HadException())
+      return;
+    impl.setTestEnumOrTestEnumSequenceMember(testEnumOrTestEnumSequenceMemberCppValue);
+  }
+
   v8::Local<v8::Value> testInterface2OrUint8ArrayMemberValue;
-  if (!v8Object->Get(context, keys[31].Get(isolate)).ToLocal(&testInterface2OrUint8ArrayMemberValue)) {
+  if (!v8Object->Get(context, keys[32].Get(isolate)).ToLocal(&testInterface2OrUint8ArrayMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -531,7 +547,7 @@
   }
 
   v8::Local<v8::Value> testInterfaceGarbageCollectedMemberValue;
-  if (!v8Object->Get(context, keys[32].Get(isolate)).ToLocal(&testInterfaceGarbageCollectedMemberValue)) {
+  if (!v8Object->Get(context, keys[33].Get(isolate)).ToLocal(&testInterfaceGarbageCollectedMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -547,7 +563,7 @@
   }
 
   v8::Local<v8::Value> testInterfaceGarbageCollectedOrNullMemberValue;
-  if (!v8Object->Get(context, keys[33].Get(isolate)).ToLocal(&testInterfaceGarbageCollectedOrNullMemberValue)) {
+  if (!v8Object->Get(context, keys[34].Get(isolate)).ToLocal(&testInterfaceGarbageCollectedOrNullMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -565,7 +581,7 @@
   }
 
   v8::Local<v8::Value> testInterfaceGarbageCollectedSequenceMemberValue;
-  if (!v8Object->Get(context, keys[34].Get(isolate)).ToLocal(&testInterfaceGarbageCollectedSequenceMemberValue)) {
+  if (!v8Object->Get(context, keys[35].Get(isolate)).ToLocal(&testInterfaceGarbageCollectedSequenceMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -579,7 +595,7 @@
   }
 
   v8::Local<v8::Value> testInterfaceMemberValue;
-  if (!v8Object->Get(context, keys[35].Get(isolate)).ToLocal(&testInterfaceMemberValue)) {
+  if (!v8Object->Get(context, keys[36].Get(isolate)).ToLocal(&testInterfaceMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -595,7 +611,7 @@
   }
 
   v8::Local<v8::Value> testInterfaceOrNullMemberValue;
-  if (!v8Object->Get(context, keys[36].Get(isolate)).ToLocal(&testInterfaceOrNullMemberValue)) {
+  if (!v8Object->Get(context, keys[37].Get(isolate)).ToLocal(&testInterfaceOrNullMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -613,7 +629,7 @@
   }
 
   v8::Local<v8::Value> testInterfaceSequenceMemberValue;
-  if (!v8Object->Get(context, keys[37].Get(isolate)).ToLocal(&testInterfaceSequenceMemberValue)) {
+  if (!v8Object->Get(context, keys[38].Get(isolate)).ToLocal(&testInterfaceSequenceMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -627,7 +643,7 @@
   }
 
   v8::Local<v8::Value> testObjectSequenceMemberValue;
-  if (!v8Object->Get(context, keys[38].Get(isolate)).ToLocal(&testObjectSequenceMemberValue)) {
+  if (!v8Object->Get(context, keys[39].Get(isolate)).ToLocal(&testObjectSequenceMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -641,7 +657,7 @@
   }
 
   v8::Local<v8::Value> treatNullAsStringSequenceMemberValue;
-  if (!v8Object->Get(context, keys[39].Get(isolate)).ToLocal(&treatNullAsStringSequenceMemberValue)) {
+  if (!v8Object->Get(context, keys[40].Get(isolate)).ToLocal(&treatNullAsStringSequenceMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -655,7 +671,7 @@
   }
 
   v8::Local<v8::Value> uint8ArrayMemberValue;
-  if (!v8Object->Get(context, keys[40].Get(isolate)).ToLocal(&uint8ArrayMemberValue)) {
+  if (!v8Object->Get(context, keys[41].Get(isolate)).ToLocal(&uint8ArrayMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -673,7 +689,7 @@
   }
 
   v8::Local<v8::Value> unionInRecordMemberValue;
-  if (!v8Object->Get(context, keys[41].Get(isolate)).ToLocal(&unionInRecordMemberValue)) {
+  if (!v8Object->Get(context, keys[42].Get(isolate)).ToLocal(&unionInRecordMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -687,7 +703,7 @@
   }
 
   v8::Local<v8::Value> unionMemberWithSequenceDefaultValue;
-  if (!v8Object->Get(context, keys[42].Get(isolate)).ToLocal(&unionMemberWithSequenceDefaultValue)) {
+  if (!v8Object->Get(context, keys[43].Get(isolate)).ToLocal(&unionMemberWithSequenceDefaultValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -702,7 +718,7 @@
   }
 
   v8::Local<v8::Value> unionWithTypedefsValue;
-  if (!v8Object->Get(context, keys[43].Get(isolate)).ToLocal(&unionWithTypedefsValue)) {
+  if (!v8Object->Get(context, keys[44].Get(isolate)).ToLocal(&unionWithTypedefsValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -717,7 +733,7 @@
   }
 
   v8::Local<v8::Value> unrestrictedDoubleMemberValue;
-  if (!v8Object->Get(context, keys[44].Get(isolate)).ToLocal(&unrestrictedDoubleMemberValue)) {
+  if (!v8Object->Get(context, keys[45].Get(isolate)).ToLocal(&unrestrictedDoubleMemberValue)) {
     exceptionState.RethrowV8Exception(block.Exception());
     return;
   }
@@ -1138,6 +1154,17 @@
     return false;
   }
 
+  v8::Local<v8::Value> testEnumOrTestEnumSequenceMemberValue;
+  bool testEnumOrTestEnumSequenceMemberHasValueOrDefault = false;
+  if (impl.hasTestEnumOrTestEnumSequenceMember()) {
+    testEnumOrTestEnumSequenceMemberValue = ToV8(impl.testEnumOrTestEnumSequenceMember(), creationContext, isolate);
+    testEnumOrTestEnumSequenceMemberHasValueOrDefault = true;
+  }
+  if (testEnumOrTestEnumSequenceMemberHasValueOrDefault &&
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[31].Get(isolate), testEnumOrTestEnumSequenceMemberValue))) {
+    return false;
+  }
+
   v8::Local<v8::Value> testInterface2OrUint8ArrayMemberValue;
   bool testInterface2OrUint8ArrayMemberHasValueOrDefault = false;
   if (impl.hasTestInterface2OrUint8ArrayMember()) {
@@ -1145,7 +1172,7 @@
     testInterface2OrUint8ArrayMemberHasValueOrDefault = true;
   }
   if (testInterface2OrUint8ArrayMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[31].Get(isolate), testInterface2OrUint8ArrayMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[32].Get(isolate), testInterface2OrUint8ArrayMemberValue))) {
     return false;
   }
 
@@ -1156,7 +1183,7 @@
     testInterfaceGarbageCollectedMemberHasValueOrDefault = true;
   }
   if (testInterfaceGarbageCollectedMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[32].Get(isolate), testInterfaceGarbageCollectedMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[33].Get(isolate), testInterfaceGarbageCollectedMemberValue))) {
     return false;
   }
 
@@ -1170,7 +1197,7 @@
     testInterfaceGarbageCollectedOrNullMemberHasValueOrDefault = true;
   }
   if (testInterfaceGarbageCollectedOrNullMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[33].Get(isolate), testInterfaceGarbageCollectedOrNullMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[34].Get(isolate), testInterfaceGarbageCollectedOrNullMemberValue))) {
     return false;
   }
 
@@ -1184,7 +1211,7 @@
     testInterfaceGarbageCollectedSequenceMemberHasValueOrDefault = true;
   }
   if (testInterfaceGarbageCollectedSequenceMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[34].Get(isolate), testInterfaceGarbageCollectedSequenceMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[35].Get(isolate), testInterfaceGarbageCollectedSequenceMemberValue))) {
     return false;
   }
 
@@ -1195,7 +1222,7 @@
     testInterfaceMemberHasValueOrDefault = true;
   }
   if (testInterfaceMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[35].Get(isolate), testInterfaceMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[36].Get(isolate), testInterfaceMemberValue))) {
     return false;
   }
 
@@ -1209,7 +1236,7 @@
     testInterfaceOrNullMemberHasValueOrDefault = true;
   }
   if (testInterfaceOrNullMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[36].Get(isolate), testInterfaceOrNullMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[37].Get(isolate), testInterfaceOrNullMemberValue))) {
     return false;
   }
 
@@ -1223,7 +1250,7 @@
     testInterfaceSequenceMemberHasValueOrDefault = true;
   }
   if (testInterfaceSequenceMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[37].Get(isolate), testInterfaceSequenceMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[38].Get(isolate), testInterfaceSequenceMemberValue))) {
     return false;
   }
 
@@ -1234,7 +1261,7 @@
     testObjectSequenceMemberHasValueOrDefault = true;
   }
   if (testObjectSequenceMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[38].Get(isolate), testObjectSequenceMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[39].Get(isolate), testObjectSequenceMemberValue))) {
     return false;
   }
 
@@ -1248,7 +1275,7 @@
     treatNullAsStringSequenceMemberHasValueOrDefault = true;
   }
   if (treatNullAsStringSequenceMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[39].Get(isolate), treatNullAsStringSequenceMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[40].Get(isolate), treatNullAsStringSequenceMemberValue))) {
     return false;
   }
 
@@ -1259,7 +1286,7 @@
     uint8ArrayMemberHasValueOrDefault = true;
   }
   if (uint8ArrayMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[40].Get(isolate), uint8ArrayMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[41].Get(isolate), uint8ArrayMemberValue))) {
     return false;
   }
 
@@ -1270,7 +1297,7 @@
     unionInRecordMemberHasValueOrDefault = true;
   }
   if (unionInRecordMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[41].Get(isolate), unionInRecordMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[42].Get(isolate), unionInRecordMemberValue))) {
     return false;
   }
 
@@ -1284,7 +1311,7 @@
     unionMemberWithSequenceDefaultHasValueOrDefault = true;
   }
   if (unionMemberWithSequenceDefaultHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[42].Get(isolate), unionMemberWithSequenceDefaultValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[43].Get(isolate), unionMemberWithSequenceDefaultValue))) {
     return false;
   }
 
@@ -1295,7 +1322,7 @@
     unionWithTypedefsHasValueOrDefault = true;
   }
   if (unionWithTypedefsHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[43].Get(isolate), unionWithTypedefsValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[44].Get(isolate), unionWithTypedefsValue))) {
     return false;
   }
 
@@ -1309,7 +1336,7 @@
     unrestrictedDoubleMemberHasValueOrDefault = true;
   }
   if (unrestrictedDoubleMemberHasValueOrDefault &&
-      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[44].Get(isolate), unrestrictedDoubleMemberValue))) {
+      !V8CallBoolean(dictionary->CreateDataProperty(context, keys[45].Get(isolate), unrestrictedDoubleMemberValue))) {
     return false;
   }
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
index fb9bbcae..6ce6bc5 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -1728,7 +1728,7 @@
 
   // Prepare the value to be set.
   DoubleOrString cppValue;
-  V8DoubleOrNullOrString::ToImpl(info.GetIsolate(), v8Value, cppValue, UnionTypeConversionMode::kNullable, exceptionState);
+  V8DoubleOrString::ToImpl(info.GetIsolate(), v8Value, cppValue, UnionTypeConversionMode::kNullable, exceptionState);
   if (exceptionState.HadException())
     return;
 
@@ -5443,7 +5443,7 @@
   }
 
   DoubleOrString arg;
-  V8DoubleOrNullOrString::ToImpl(info.GetIsolate(), info[0], arg, UnionTypeConversionMode::kNullable, exceptionState);
+  V8DoubleOrString::ToImpl(info.GetIsolate(), info[0], arg, UnionTypeConversionMode::kNullable, exceptionState);
   if (exceptionState.HadException())
     return;
 
@@ -6455,7 +6455,7 @@
     defaultLongArg.SetDouble(10);
   }
   if (!info[1]->IsUndefined()) {
-    V8DoubleOrStringOrNull::ToImpl(info.GetIsolate(), info[1], defaultStringArg, UnionTypeConversionMode::kNullable, exceptionState);
+    V8DoubleOrString::ToImpl(info.GetIsolate(), info[1], defaultStringArg, UnionTypeConversionMode::kNullable, exceptionState);
     if (exceptionState.HadException())
       return;
   } else {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
index 948c5968c..ab9fe2b 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
@@ -350,7 +350,7 @@
   }
 
   NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord arg;
-  V8NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrNullOrStringByteStringOrNodeListRecord::ToImpl(info.GetIsolate(), info[0], arg, UnionTypeConversionMode::kNullable, exceptionState);
+  V8NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord::ToImpl(info.GetIsolate(), info[0], arg, UnionTypeConversionMode::kNullable, exceptionState);
   if (exceptionState.HadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/test_enum_or_test_enum_sequence.cc b/third_party/WebKit/Source/bindings/tests/results/core/test_enum_or_test_enum_sequence.cc
new file mode 100644
index 0000000..cdcc0ef6
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/tests/results/core/test_enum_or_test_enum_sequence.cc
@@ -0,0 +1,144 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file has been auto-generated from the Jinja2 template
+// third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl
+// by the script code_generator_v8.py.
+// DO NOT MODIFY!
+
+// clang-format off
+#include "test_enum_or_test_enum_sequence.h"
+
+#include "bindings/core/v8/IDLTypes.h"
+#include "bindings/core/v8/NativeValueTraitsImpl.h"
+#include "bindings/core/v8/ToV8ForCore.h"
+
+namespace blink {
+
+TestEnumOrTestEnumSequence::TestEnumOrTestEnumSequence() : type_(SpecificType::kNone) {}
+
+const String& TestEnumOrTestEnumSequence::GetAsTestEnum() const {
+  DCHECK(IsTestEnum());
+  return test_enum_;
+}
+
+void TestEnumOrTestEnumSequence::SetTestEnum(const String& value) {
+  DCHECK(IsNull());
+  NonThrowableExceptionState exceptionState;
+  const char* validValues[] = {
+      "",
+      "EnumValue1",
+      "EnumValue2",
+      "EnumValue3",
+  };
+  if (!IsValidEnum(value, validValues, WTF_ARRAY_LENGTH(validValues), "TestEnum", exceptionState)) {
+    NOTREACHED();
+    return;
+  }
+  test_enum_ = value;
+  type_ = SpecificType::kTestEnum;
+}
+
+TestEnumOrTestEnumSequence TestEnumOrTestEnumSequence::FromTestEnum(const String& value) {
+  TestEnumOrTestEnumSequence container;
+  container.SetTestEnum(value);
+  return container;
+}
+
+const Vector<String>& TestEnumOrTestEnumSequence::GetAsTestEnumSequence() const {
+  DCHECK(IsTestEnumSequence());
+  return test_enum_sequence_;
+}
+
+void TestEnumOrTestEnumSequence::SetTestEnumSequence(const Vector<String>& value) {
+  DCHECK(IsNull());
+  NonThrowableExceptionState exceptionState;
+  const char* validValues[] = {
+      "",
+      "EnumValue1",
+      "EnumValue2",
+      "EnumValue3",
+  };
+  if (!IsValidEnum(value, validValues, WTF_ARRAY_LENGTH(validValues), "TestEnumSequence", exceptionState)) {
+    NOTREACHED();
+    return;
+  }
+  test_enum_sequence_ = value;
+  type_ = SpecificType::kTestEnumSequence;
+}
+
+TestEnumOrTestEnumSequence TestEnumOrTestEnumSequence::FromTestEnumSequence(const Vector<String>& value) {
+  TestEnumOrTestEnumSequence container;
+  container.SetTestEnumSequence(value);
+  return container;
+}
+
+TestEnumOrTestEnumSequence::TestEnumOrTestEnumSequence(const TestEnumOrTestEnumSequence&) = default;
+TestEnumOrTestEnumSequence::~TestEnumOrTestEnumSequence() = default;
+TestEnumOrTestEnumSequence& TestEnumOrTestEnumSequence::operator=(const TestEnumOrTestEnumSequence&) = default;
+
+void TestEnumOrTestEnumSequence::Trace(blink::Visitor* visitor) {
+}
+
+void V8TestEnumOrTestEnumSequence::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, TestEnumOrTestEnumSequence& impl, UnionTypeConversionMode conversionMode, ExceptionState& exceptionState) {
+  if (v8Value.IsEmpty())
+    return;
+
+  if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value))
+    return;
+
+  if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) {
+    Vector<String> cppValue = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(isolate, v8Value, exceptionState);
+    if (exceptionState.HadException())
+      return;
+    const char* validValues[] = {
+        "",
+        "EnumValue1",
+        "EnumValue2",
+        "EnumValue3",
+    };
+    if (!IsValidEnum(cppValue, validValues, WTF_ARRAY_LENGTH(validValues), "TestEnumSequence", exceptionState))
+      return;
+    impl.SetTestEnumSequence(cppValue);
+    return;
+  }
+
+  {
+    V8StringResource<> cppValue = v8Value;
+    if (!cppValue.Prepare(exceptionState))
+      return;
+    const char* validValues[] = {
+        "",
+        "EnumValue1",
+        "EnumValue2",
+        "EnumValue3",
+    };
+    if (!IsValidEnum(cppValue, validValues, WTF_ARRAY_LENGTH(validValues), "TestEnum", exceptionState))
+      return;
+    impl.SetTestEnum(cppValue);
+    return;
+  }
+}
+
+v8::Local<v8::Value> ToV8(const TestEnumOrTestEnumSequence& impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) {
+  switch (impl.type_) {
+    case TestEnumOrTestEnumSequence::SpecificType::kNone:
+      return v8::Null(isolate);
+    case TestEnumOrTestEnumSequence::SpecificType::kTestEnum:
+      return V8String(isolate, impl.GetAsTestEnum());
+    case TestEnumOrTestEnumSequence::SpecificType::kTestEnumSequence:
+      return ToV8(impl.GetAsTestEnumSequence(), creationContext, isolate);
+    default:
+      NOTREACHED();
+  }
+  return v8::Local<v8::Value>();
+}
+
+TestEnumOrTestEnumSequence NativeValueTraits<TestEnumOrTestEnumSequence>::NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exceptionState) {
+  TestEnumOrTestEnumSequence impl;
+  V8TestEnumOrTestEnumSequence::ToImpl(isolate, value, impl, UnionTypeConversionMode::kNotNullable, exceptionState);
+  return impl;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/test_enum_or_test_enum_sequence.h b/third_party/WebKit/Source/bindings/tests/results/core/test_enum_or_test_enum_sequence.h
new file mode 100644
index 0000000..09f4ccf6
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/tests/results/core/test_enum_or_test_enum_sequence.h
@@ -0,0 +1,93 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file has been auto-generated from the Jinja2 template
+// third_party/WebKit/Source/bindings/templates/union_container.h.tmpl
+// by the script code_generator_v8.py.
+// DO NOT MODIFY!
+
+// clang-format off
+#ifndef TestEnumOrTestEnumSequence_h
+#define TestEnumOrTestEnumSequence_h
+
+#include "bindings/core/v8/Dictionary.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/NativeValueTraits.h"
+#include "bindings/core/v8/V8BindingForCore.h"
+#include "core/CoreExport.h"
+#include "platform/heap/Handle.h"
+
+namespace blink {
+
+class CORE_EXPORT TestEnumOrTestEnumSequence final {
+  DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ public:
+  TestEnumOrTestEnumSequence();
+  bool IsNull() const { return type_ == SpecificType::kNone; }
+
+  bool IsTestEnum() const { return type_ == SpecificType::kTestEnum; }
+  const String& GetAsTestEnum() const;
+  void SetTestEnum(const String&);
+  static TestEnumOrTestEnumSequence FromTestEnum(const String&);
+
+  bool IsTestEnumSequence() const { return type_ == SpecificType::kTestEnumSequence; }
+  const Vector<String>& GetAsTestEnumSequence() const;
+  void SetTestEnumSequence(const Vector<String>&);
+  static TestEnumOrTestEnumSequence FromTestEnumSequence(const Vector<String>&);
+
+  TestEnumOrTestEnumSequence(const TestEnumOrTestEnumSequence&);
+  ~TestEnumOrTestEnumSequence();
+  TestEnumOrTestEnumSequence& operator=(const TestEnumOrTestEnumSequence&);
+  void Trace(blink::Visitor*);
+
+ private:
+  enum class SpecificType {
+    kNone,
+    kTestEnum,
+    kTestEnumSequence,
+  };
+  SpecificType type_;
+
+  String test_enum_;
+  Vector<String> test_enum_sequence_;
+
+  friend CORE_EXPORT v8::Local<v8::Value> ToV8(const TestEnumOrTestEnumSequence&, v8::Local<v8::Object>, v8::Isolate*);
+};
+
+class V8TestEnumOrTestEnumSequence final {
+ public:
+  CORE_EXPORT static void ToImpl(v8::Isolate*, v8::Local<v8::Value>, TestEnumOrTestEnumSequence&, UnionTypeConversionMode, ExceptionState&);
+};
+
+CORE_EXPORT v8::Local<v8::Value> ToV8(const TestEnumOrTestEnumSequence&, v8::Local<v8::Object>, v8::Isolate*);
+
+template <class CallbackInfo>
+inline void V8SetReturnValue(const CallbackInfo& callbackInfo, TestEnumOrTestEnumSequence& impl) {
+  V8SetReturnValue(callbackInfo, ToV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
+}
+
+template <class CallbackInfo>
+inline void V8SetReturnValue(const CallbackInfo& callbackInfo, TestEnumOrTestEnumSequence& impl, v8::Local<v8::Object> creationContext) {
+  V8SetReturnValue(callbackInfo, ToV8(impl, creationContext, callbackInfo.GetIsolate()));
+}
+
+template <>
+struct NativeValueTraits<TestEnumOrTestEnumSequence> : public NativeValueTraitsBase<TestEnumOrTestEnumSequence> {
+  CORE_EXPORT static TestEnumOrTestEnumSequence NativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
+};
+
+template <>
+struct V8TypeOf<TestEnumOrTestEnumSequence> {
+  typedef V8TestEnumOrTestEnumSequence Type;
+};
+
+}  // namespace blink
+
+// We need to set canInitializeWithMemset=true because HeapVector supports
+// items that can initialize with memset or have a vtable. It is safe to
+// set canInitializeWithMemset=true for a union type object in practice.
+// See https://codereview.chromium.org/1118993002/#msg5 for more details.
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrTestEnumSequence);
+
+#endif  // TestEnumOrTestEnumSequence_h
diff --git a/third_party/WebKit/Source/build/scripts/core/style/templates/ComputedStyleInitialValues.h.tmpl b/third_party/WebKit/Source/build/scripts/core/style/templates/ComputedStyleInitialValues.h.tmpl
index ac09de8b..c1364b5 100644
--- a/third_party/WebKit/Source/build/scripts/core/style/templates/ComputedStyleInitialValues.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/core/style/templates/ComputedStyleInitialValues.h.tmpl
@@ -35,8 +35,8 @@
   // Hand-written methods.
 
   static StyleContentAlignmentData InitialContentAlignment() {
-    return StyleContentAlignmentData(kContentPositionNormal,
-                                     kContentDistributionDefault,
+    return StyleContentAlignmentData(ContentPosition::kNormal,
+                                     ContentDistributionType::kDefault,
                                      kOverflowAlignmentDefault);
   }
   static StyleSelfAlignmentData InitialDefaultAlignment() {
diff --git a/third_party/WebKit/Source/controller/DevToolsFrontendImpl.cpp b/third_party/WebKit/Source/controller/DevToolsFrontendImpl.cpp
index eb30034..e9d31b8 100644
--- a/third_party/WebKit/Source/controller/DevToolsFrontendImpl.cpp
+++ b/third_party/WebKit/Source/controller/DevToolsFrontendImpl.cpp
@@ -104,8 +104,8 @@
   DCHECK(GetSupplementable()->IsMainFrame());
   api_script_ = api_script;
   host_.Bind(std::move(host));
-  host_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-      &DevToolsFrontendImpl::DestroyOnHostGone, WrapWeakPersistent(this))));
+  host_.set_connection_error_handler(WTF::Bind(
+      &DevToolsFrontendImpl::DestroyOnHostGone, WrapWeakPersistent(this)));
   GetSupplementable()->GetPage()->SetDefaultPageScaleLimits(1.f, 1.f);
 }
 
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.h b/third_party/WebKit/Source/core/animation/StringKeyframe.h
index acc9943..a4e0995 100644
--- a/third_party/WebKit/Source/core/animation/StringKeyframe.h
+++ b/third_party/WebKit/Source/core/animation/StringKeyframe.h
@@ -6,7 +6,7 @@
 #define StringKeyframe_h
 
 #include "core/animation/Keyframe.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 
 #include "platform/wtf/HashMap.h"
 
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index b46a354f..66812ea 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -207,6 +207,8 @@
     "FontSizeFunctions.cpp",
     "FontSizeFunctions.h",
     "HashTools.h",
+    "ImmutableCSSPropertyValueSet.cpp",
+    "ImmutableCSSPropertyValueSet.h",
     "KeyframeStyleRuleCSSStyleDeclaration.cpp",
     "KeyframeStyleRuleCSSStyleDeclaration.h",
     "LocalFontFaceSource.cpp",
@@ -234,6 +236,8 @@
     "MediaValuesDynamic.h",
     "MediaValuesInitialViewport.cpp",
     "MediaValuesInitialViewport.h",
+    "MutableCSSPropertyValueSet.cpp",
+    "MutableCSSPropertyValueSet.h",
     "OffscreenFontSelector.cpp",
     "OffscreenFontSelector.h",
     "PageRuleCollector.cpp",
@@ -374,6 +378,7 @@
     "parser/CSSAtRuleID.h",
     "parser/CSSLazyParsingState.cpp",
     "parser/CSSLazyParsingState.h",
+    "parser/CSSLazyPropertyParser.h",
     "parser/CSSLazyPropertyParserImpl.cpp",
     "parser/CSSLazyPropertyParserImpl.h",
     "parser/CSSParser.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp b/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
index 28e08f5..c8514098 100644
--- a/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
@@ -31,8 +31,8 @@
 #include "core/css/CSSCalculationValue.h"
 
 #include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSPropertyValueSet.h"
 #include "core/css/CSSToLengthConversionData.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/layout/api/LayoutViewItem.h"
 #include "core/style/ComputedStyle.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index 33a0446..3e4e9e66 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -1643,34 +1643,34 @@
 inline CSSIdentifierValue::CSSIdentifierValue(ContentPosition content_position)
     : CSSValue(kIdentifierClass) {
   switch (content_position) {
-    case kContentPositionNormal:
+    case ContentPosition::kNormal:
       value_id_ = CSSValueNormal;
       break;
-    case kContentPositionBaseline:
+    case ContentPosition::kBaseline:
       value_id_ = CSSValueBaseline;
       break;
-    case kContentPositionLastBaseline:
+    case ContentPosition::kLastBaseline:
       value_id_ = CSSValueLastBaseline;
       break;
-    case kContentPositionCenter:
+    case ContentPosition::kCenter:
       value_id_ = CSSValueCenter;
       break;
-    case kContentPositionStart:
+    case ContentPosition::kStart:
       value_id_ = CSSValueStart;
       break;
-    case kContentPositionEnd:
+    case ContentPosition::kEnd:
       value_id_ = CSSValueEnd;
       break;
-    case kContentPositionFlexStart:
+    case ContentPosition::kFlexStart:
       value_id_ = CSSValueFlexStart;
       break;
-    case kContentPositionFlexEnd:
+    case ContentPosition::kFlexEnd:
       value_id_ = CSSValueFlexEnd;
       break;
-    case kContentPositionLeft:
+    case ContentPosition::kLeft:
       value_id_ = CSSValueLeft;
       break;
-    case kContentPositionRight:
+    case ContentPosition::kRight:
       value_id_ = CSSValueRight;
       break;
   }
@@ -1680,32 +1680,32 @@
 inline ContentPosition CSSIdentifierValue::ConvertTo() const {
   switch (value_id_) {
     case CSSValueNormal:
-      return kContentPositionNormal;
+      return ContentPosition::kNormal;
     case CSSValueBaseline:
-      return kContentPositionBaseline;
+      return ContentPosition::kBaseline;
     case CSSValueFirstBaseline:
-      return kContentPositionBaseline;
+      return ContentPosition::kBaseline;
     case CSSValueLastBaseline:
-      return kContentPositionLastBaseline;
+      return ContentPosition::kLastBaseline;
     case CSSValueCenter:
-      return kContentPositionCenter;
+      return ContentPosition::kCenter;
     case CSSValueStart:
-      return kContentPositionStart;
+      return ContentPosition::kStart;
     case CSSValueEnd:
-      return kContentPositionEnd;
+      return ContentPosition::kEnd;
     case CSSValueFlexStart:
-      return kContentPositionFlexStart;
+      return ContentPosition::kFlexStart;
     case CSSValueFlexEnd:
-      return kContentPositionFlexEnd;
+      return ContentPosition::kFlexEnd;
     case CSSValueLeft:
-      return kContentPositionLeft;
+      return ContentPosition::kLeft;
     case CSSValueRight:
-      return kContentPositionRight;
+      return ContentPosition::kRight;
     default:
       break;
   }
   NOTREACHED();
-  return kContentPositionNormal;
+  return ContentPosition::kNormal;
 }
 
 template <>
@@ -1713,19 +1713,19 @@
     ContentDistributionType content_distribution)
     : CSSValue(kIdentifierClass) {
   switch (content_distribution) {
-    case kContentDistributionDefault:
+    case ContentDistributionType::kDefault:
       value_id_ = CSSValueDefault;
       break;
-    case kContentDistributionSpaceBetween:
+    case ContentDistributionType::kSpaceBetween:
       value_id_ = CSSValueSpaceBetween;
       break;
-    case kContentDistributionSpaceAround:
+    case ContentDistributionType::kSpaceAround:
       value_id_ = CSSValueSpaceAround;
       break;
-    case kContentDistributionSpaceEvenly:
+    case ContentDistributionType::kSpaceEvenly:
       value_id_ = CSSValueSpaceEvenly;
       break;
-    case kContentDistributionStretch:
+    case ContentDistributionType::kStretch:
       value_id_ = CSSValueStretch;
       break;
   }
@@ -1735,18 +1735,18 @@
 inline ContentDistributionType CSSIdentifierValue::ConvertTo() const {
   switch (value_id_) {
     case CSSValueSpaceBetween:
-      return kContentDistributionSpaceBetween;
+      return ContentDistributionType::kSpaceBetween;
     case CSSValueSpaceAround:
-      return kContentDistributionSpaceAround;
+      return ContentDistributionType::kSpaceAround;
     case CSSValueSpaceEvenly:
-      return kContentDistributionSpaceEvenly;
+      return ContentDistributionType::kSpaceEvenly;
     case CSSValueStretch:
-      return kContentDistributionStretch;
+      return ContentDistributionType::kStretch;
     default:
       break;
   }
   NOTREACHED();
-  return kContentDistributionStretch;
+  return ContentDistributionType::kStretch;
 }
 
 template <>
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index c174c0fb..d61935e2 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -706,7 +706,7 @@
       field_group: "*",
       field_template: "external",
       include_paths: ["core/style/StyleContentAlignmentData.h"],
-      default_value: "StyleContentAlignmentData(kContentPositionNormal, kContentDistributionDefault, kOverflowAlignmentDefault)",
+      default_value: "StyleContentAlignmentData(ContentPosition::kNormal, ContentDistributionType::kDefault, kOverflowAlignmentDefault)",
       type_name: "StyleContentAlignmentData",
       converter: "ConvertContentAlignmentData",
     },
@@ -1657,7 +1657,7 @@
       field_group: "*",
       field_template: "external",
       include_paths: ["core/style/StyleContentAlignmentData.h"],
-      default_value: "StyleContentAlignmentData(kContentPositionNormal, kContentDistributionDefault, kOverflowAlignmentDefault)",
+      default_value: "StyleContentAlignmentData(ContentPosition::kNormal, ContentDistributionType::kDefault, kOverflowAlignmentDefault)",
       type_name: "StyleContentAlignmentData",
       converter: "ConvertContentAlignmentData",
     },
diff --git a/third_party/WebKit/Source/core/css/CSSPropertyValueSet.cpp b/third_party/WebKit/Source/core/css/CSSPropertyValueSet.cpp
index 25b21e64..15e78c1 100644
--- a/third_party/WebKit/Source/core/css/CSSPropertyValueSet.cpp
+++ b/third_party/WebKit/Source/core/css/CSSPropertyValueSet.cpp
@@ -26,13 +26,10 @@
 #include "core/StylePropertyShorthand.h"
 #include "core/css/CSSCustomPropertyDeclaration.h"
 #include "core/css/CSSIdentifierValue.h"
+#include "core/css/ImmutableCSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StylePropertySerializer.h"
-#include "core/css/StyleSheetContents.h"
-#include "core/css/parser/CSSParser.h"
-#include "core/css/parser/CSSParserContext.h"
 #include "core/css/properties/CSSProperty.h"
-#include "core/frame/UseCounter.h"
-#include "platform/wtf/text/StringBuilder.h"
 
 #ifndef NDEBUG
 #include <stdio.h>
@@ -41,170 +38,27 @@
 
 namespace blink {
 
-static size_t SizeForImmutableCSSPropertyValueSetWithPropertyCount(
-    unsigned count) {
-  return sizeof(ImmutableCSSPropertyValueSet) - sizeof(void*) +
-         sizeof(Member<CSSValue>) * count +
-         sizeof(CSSPropertyValueMetadata) * count;
-}
+namespace {
 
-ImmutableCSSPropertyValueSet* ImmutableCSSPropertyValueSet::Create(
-    const CSSPropertyValue* properties,
-    unsigned count,
-    CSSParserMode css_parser_mode) {
-  DCHECK_LE(count, static_cast<unsigned>(kMaxArraySize));
-  void* slot = ThreadHeap::Allocate<CSSPropertyValueSet>(
-      SizeForImmutableCSSPropertyValueSetWithPropertyCount(count));
-  return new (slot)
-      ImmutableCSSPropertyValueSet(properties, count, css_parser_mode);
-}
-
-ImmutableCSSPropertyValueSet* CSSPropertyValueSet::ImmutableCopyIfNeeded()
-    const {
-  if (!IsMutable()) {
-    return ToImmutableCSSPropertyValueSet(
-        const_cast<CSSPropertyValueSet*>(this));
-  }
-  const MutableCSSPropertyValueSet* mutable_this =
-      ToMutableCSSPropertyValueSet(this);
-  return ImmutableCSSPropertyValueSet::Create(
-      mutable_this->property_vector_.data(),
-      mutable_this->property_vector_.size(), CssParserMode());
-}
-
-MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
-    CSSParserMode css_parser_mode)
-    : CSSPropertyValueSet(css_parser_mode) {}
-
-MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
-    const CSSPropertyValue* properties,
-    unsigned length)
-    : CSSPropertyValueSet(kHTMLStandardMode) {
-  property_vector_.ReserveInitialCapacity(length);
-  for (unsigned i = 0; i < length; ++i)
-    property_vector_.UncheckedAppend(properties[i]);
-}
-
-ImmutableCSSPropertyValueSet::ImmutableCSSPropertyValueSet(
-    const CSSPropertyValue* properties,
-    unsigned length,
-    CSSParserMode css_parser_mode)
-    : CSSPropertyValueSet(css_parser_mode, length) {
-  CSSPropertyValueMetadata* metadata_array =
-      const_cast<CSSPropertyValueMetadata*>(this->MetadataArray());
-  Member<const CSSValue>* value_array =
-      const_cast<Member<const CSSValue>*>(this->ValueArray());
-  for (unsigned i = 0; i < array_size_; ++i) {
-    metadata_array[i] = properties[i].Metadata();
-    value_array[i] = properties[i].Value();
-  }
-}
-
-ImmutableCSSPropertyValueSet::~ImmutableCSSPropertyValueSet() = default;
-
-// Convert property into an uint16_t for comparison with metadata's property id
-// to avoid the compiler converting it to an int multiple times in a loop.
-static uint16_t GetConvertedCSSPropertyID(CSSPropertyID property_id) {
-  return static_cast<uint16_t>(property_id);
-}
-
-static uint16_t GetConvertedCSSPropertyID(const AtomicString&) {
-  return static_cast<uint16_t>(CSSPropertyVariable);
-}
-
-static uint16_t GetConvertedCSSPropertyID(AtRuleDescriptorID descriptor_id) {
-  return static_cast<uint16_t>(
-      AtRuleDescriptorIDAsCSSPropertyID(descriptor_id));
-}
-
-static bool IsPropertyMatch(const CSSPropertyValueMetadata& metadata,
-                            const CSSValue&,
-                            uint16_t id,
-                            CSSPropertyID property_id) {
-  DCHECK_EQ(id, property_id);
-  bool result = metadata.Property().PropertyID() == id;
-// Only enabled properties should be part of the style.
-#if DCHECK_IS_ON()
-  DCHECK(!result ||
-         CSSProperty::Get(resolveCSSPropertyID(property_id)).IsEnabled());
-#endif
-  return result;
-}
-
-static bool IsPropertyMatch(const CSSPropertyValueMetadata& metadata,
-                            const CSSValue& value,
-                            uint16_t id,
-                            const AtomicString& custom_property_name) {
-  DCHECK_EQ(id, CSSPropertyVariable);
-  return metadata.Property().PropertyID() == id &&
-         ToCSSCustomPropertyDeclaration(value).GetName() ==
-             custom_property_name;
-}
-
-static bool IsPropertyMatch(const CSSPropertyValueMetadata& metadata,
-                            const CSSValue& css_value,
-                            uint16_t id,
-                            AtRuleDescriptorID descriptor_id) {
-  return IsPropertyMatch(metadata, css_value, id,
-                         AtRuleDescriptorIDAsCSSPropertyID(descriptor_id));
-}
-
-template <typename T>
-int ImmutableCSSPropertyValueSet::FindPropertyIndex(T property) const {
-  uint16_t id = GetConvertedCSSPropertyID(property);
-  for (int n = array_size_ - 1; n >= 0; --n) {
-    if (IsPropertyMatch(MetadataArray()[n], *ValueArray()[n], id, property))
-      return n;
-  }
-
-  return -1;
-}
-template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
-    CSSPropertyID) const;
-template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
-    AtomicString) const;
-template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
-    AtRuleDescriptorID) const;
-
-void ImmutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
-  const Member<const CSSValue>* values = ValueArray();
-  for (unsigned i = 0; i < array_size_; i++)
-    visitor->Trace(values[i]);
-  CSSPropertyValueSet::TraceAfterDispatch(visitor);
-}
-
-MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
-    const CSSPropertyValueSet& other)
-    : CSSPropertyValueSet(other.CssParserMode()) {
-  if (other.IsMutable()) {
-    property_vector_ = ToMutableCSSPropertyValueSet(other).property_vector_;
-  } else {
-    property_vector_.ReserveInitialCapacity(other.PropertyCount());
-    for (unsigned i = 0; i < other.PropertyCount(); ++i) {
-      property_vector_.UncheckedAppend(
-          other.PropertyAt(i).ToCSSPropertyValue());
-    }
-  }
-}
-
-static String SerializeShorthand(const CSSPropertyValueSet& property_set,
-                                 CSSPropertyID property_id) {
+String SerializeShorthand(const CSSPropertyValueSet& property_set,
+                          CSSPropertyID property_id) {
   return StylePropertySerializer(property_set).GetPropertyValue(property_id);
 }
 
-static String SerializeShorthand(const CSSPropertyValueSet&,
-                                 const AtomicString& custom_property_name) {
+String SerializeShorthand(const CSSPropertyValueSet&,
+                          const AtomicString& custom_property_name) {
   // Custom properties are never shorthands.
   return "";
 }
 
-static String SerializeShorthand(const CSSPropertyValueSet& property_set,
-                                 AtRuleDescriptorID atrule_id) {
+String SerializeShorthand(const CSSPropertyValueSet& property_set,
+                          AtRuleDescriptorID atrule_id) {
   return StylePropertySerializer(property_set)
       .GetPropertyValue(AtRuleDescriptorIDAsCSSPropertyID(atrule_id));
-  ;
 }
 
+}  // namespace
+
 template <typename T>
 String CSSPropertyValueSet::GetPropertyValue(T property) const {
   const CSSValue* value = GetPropertyCSSValue(property);
@@ -248,53 +102,6 @@
     ToImmutableCSSPropertyValueSet(this)->~ImmutableCSSPropertyValueSet();
 }
 
-bool MutableCSSPropertyValueSet::RemoveShorthandProperty(
-    CSSPropertyID property_id) {
-  StylePropertyShorthand shorthand = shorthandForProperty(property_id);
-  if (!shorthand.length())
-    return false;
-
-  return RemovePropertiesInSet(shorthand.properties(), shorthand.length());
-}
-
-bool MutableCSSPropertyValueSet::RemovePropertyAtIndex(int property_index,
-                                                       String* return_text) {
-  if (property_index == -1) {
-    if (return_text)
-      *return_text = "";
-    return false;
-  }
-
-  if (return_text)
-    *return_text = PropertyAt(property_index).Value().CssText();
-
-  // A more efficient removal strategy would involve marking entries as empty
-  // and sweeping them when the vector grows too big.
-  property_vector_.EraseAt(property_index);
-
-  return true;
-}
-
-template <typename T>
-bool MutableCSSPropertyValueSet::RemoveProperty(T property,
-                                                String* return_text) {
-  if (RemoveShorthandProperty(property)) {
-    // FIXME: Return an equivalent shorthand when possible.
-    if (return_text)
-      *return_text = "";
-    return true;
-  }
-
-  int found_property_index = FindPropertyIndex(property);
-  return RemovePropertyAtIndex(found_property_index, return_text);
-}
-template CORE_EXPORT bool MutableCSSPropertyValueSet::RemoveProperty(
-    CSSPropertyID,
-    String*);
-template CORE_EXPORT bool MutableCSSPropertyValueSet::RemoveProperty(
-    AtomicString,
-    String*);
-
 template <typename T>
 bool CSSPropertyValueSet::PropertyIsImportant(T property) const {
   int found_property_index = FindPropertyIndex(property);
@@ -341,246 +148,10 @@
   return PropertyAt(found_property_index).IsImplicit();
 }
 
-MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
-    CSSPropertyID unresolved_property,
-    const String& value,
-    bool important,
-    SecureContextMode secure_context_mode,
-    StyleSheetContents* context_style_sheet) {
-  DCHECK_GE(unresolved_property, firstCSSProperty);
-
-  // Setting the value to an empty string just removes the property in both IE
-  // and Gecko. Setting it to null seems to produce less consistent results, but
-  // we treat it just the same.
-  if (value.IsEmpty()) {
-    bool did_parse = true;
-    bool did_change = RemoveProperty(resolveCSSPropertyID(unresolved_property));
-    return SetResult{did_parse, did_change};
-  }
-
-  // When replacing an existing property value, this moves the property to the
-  // end of the list. Firefox preserves the position, and MSIE moves the
-  // property to the beginning.
-  return CSSParser::ParseValue(this, unresolved_property, value, important,
-                               secure_context_mode, context_style_sheet);
-}
-
-MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
-    const AtomicString& custom_property_name,
-    const PropertyRegistry* registry,
-    const String& value,
-    bool important,
-    SecureContextMode secure_context_mode,
-    StyleSheetContents* context_style_sheet,
-    bool is_animation_tainted) {
-  if (value.IsEmpty()) {
-    bool did_parse = true;
-    bool did_change = RemoveProperty(custom_property_name);
-    return MutableCSSPropertyValueSet::SetResult{did_parse, did_change};
-  }
-  return CSSParser::ParseValueForCustomProperty(
-      this, custom_property_name, registry, value, important,
-      secure_context_mode, context_style_sheet, is_animation_tainted);
-}
-
-void MutableCSSPropertyValueSet::SetProperty(CSSPropertyID property_id,
-                                             const CSSValue& value,
-                                             bool important) {
-  StylePropertyShorthand shorthand = shorthandForProperty(property_id);
-  if (!shorthand.length()) {
-    SetProperty(
-        CSSPropertyValue(CSSProperty::Get(property_id), value, important));
-    return;
-  }
-
-  RemovePropertiesInSet(shorthand.properties(), shorthand.length());
-
-  for (unsigned i = 0; i < shorthand.length(); ++i) {
-    property_vector_.push_back(
-        CSSPropertyValue(*shorthand.properties()[i], value, important));
-  }
-}
-
-bool MutableCSSPropertyValueSet::SetProperty(const CSSPropertyValue& property,
-                                             CSSPropertyValue* slot) {
-  const AtomicString& name =
-      (property.Id() == CSSPropertyVariable)
-          ? ToCSSCustomPropertyDeclaration(property.Value())->GetName()
-          : g_null_atom;
-  CSSPropertyValue* to_replace =
-      slot ? slot : FindCSSPropertyWithID(property.Id(), name);
-  if (to_replace && *to_replace == property)
-    return false;
-  if (to_replace) {
-    *to_replace = property;
-    return true;
-  }
-  property_vector_.push_back(property);
-  return true;
-}
-
-bool MutableCSSPropertyValueSet::SetProperty(CSSPropertyID property_id,
-                                             CSSValueID identifier,
-                                             bool important) {
-  SetProperty(CSSPropertyValue(CSSProperty::Get(property_id),
-                               *CSSIdentifierValue::Create(identifier),
-                               important));
-  return true;
-}
-
-void MutableCSSPropertyValueSet::ParseDeclarationList(
-    const String& style_declaration,
-    SecureContextMode secure_context_mode,
-    StyleSheetContents* context_style_sheet) {
-  property_vector_.clear();
-
-  CSSParserContext* context;
-  if (context_style_sheet) {
-    context = CSSParserContext::CreateWithStyleSheetContents(
-        context_style_sheet->ParserContext(), context_style_sheet);
-    context->SetMode(CssParserMode());
-  } else {
-    context = CSSParserContext::Create(CssParserMode(), secure_context_mode);
-  }
-
-  CSSParser::ParseDeclarationList(context, this, style_declaration);
-}
-
-bool MutableCSSPropertyValueSet::AddParsedProperties(
-    const HeapVector<CSSPropertyValue, 256>& properties) {
-  bool changed = false;
-  property_vector_.ReserveCapacity(property_vector_.size() + properties.size());
-  for (unsigned i = 0; i < properties.size(); ++i)
-    changed |= SetProperty(properties[i]);
-  return changed;
-}
-
-bool MutableCSSPropertyValueSet::AddRespectingCascade(
-    const CSSPropertyValue& property) {
-  // Only add properties that have no !important counterpart present
-  if (!PropertyIsImportant(property.Id()) || property.IsImportant())
-    return SetProperty(property);
-  return false;
-}
-
 String CSSPropertyValueSet::AsText() const {
   return StylePropertySerializer(*this).AsText();
 }
 
-void MutableCSSPropertyValueSet::MergeAndOverrideOnConflict(
-    const CSSPropertyValueSet* other) {
-  unsigned size = other->PropertyCount();
-  for (unsigned n = 0; n < size; ++n) {
-    PropertyReference to_merge = other->PropertyAt(n);
-    // TODO(leviw): This probably doesn't work correctly with Custom Properties
-    CSSPropertyValue* old = FindCSSPropertyWithID(to_merge.Id());
-    if (old)
-      SetProperty(to_merge.ToCSSPropertyValue(), old);
-    else
-      property_vector_.push_back(to_merge.ToCSSPropertyValue());
-  }
-}
-
-bool CSSPropertyValueSet::HasFailedOrCanceledSubresources() const {
-  unsigned size = PropertyCount();
-  for (unsigned i = 0; i < size; ++i) {
-    if (PropertyAt(i).Value().HasFailedOrCanceledSubresources())
-      return true;
-  }
-  return false;
-}
-
-void MutableCSSPropertyValueSet::Clear() {
-  property_vector_.clear();
-}
-
-inline bool ContainsId(const CSSProperty** set,
-                       unsigned length,
-                       CSSPropertyID id) {
-  for (unsigned i = 0; i < length; ++i) {
-    if (set[i]->IDEquals(id))
-      return true;
-  }
-  return false;
-}
-
-bool MutableCSSPropertyValueSet::RemovePropertiesInSet(const CSSProperty** set,
-                                                       unsigned length) {
-  if (property_vector_.IsEmpty())
-    return false;
-
-  CSSPropertyValue* properties = property_vector_.data();
-  unsigned old_size = property_vector_.size();
-  unsigned new_index = 0;
-  for (unsigned old_index = 0; old_index < old_size; ++old_index) {
-    const CSSPropertyValue& property = properties[old_index];
-    if (ContainsId(set, length, property.Id()))
-      continue;
-    // Modify property_vector_ in-place since this method is
-    // performance-sensitive.
-    properties[new_index++] = properties[old_index];
-  }
-  if (new_index != old_size) {
-    property_vector_.Shrink(new_index);
-    return true;
-  }
-  return false;
-}
-
-CSSPropertyValue* MutableCSSPropertyValueSet::FindCSSPropertyWithID(
-    CSSPropertyID property_id,
-    const AtomicString& custom_property_name) {
-  int found_property_index = -1;
-  if (property_id == CSSPropertyVariable && !custom_property_name.IsNull()) {
-    // TODO(shanestephens): fix call sites so we always have a
-    // customPropertyName here.
-    found_property_index = FindPropertyIndex(custom_property_name);
-  } else {
-    DCHECK(custom_property_name.IsNull());
-    found_property_index = FindPropertyIndex(property_id);
-  }
-  if (found_property_index == -1)
-    return nullptr;
-  return &property_vector_.at(found_property_index);
-}
-
-bool CSSPropertyValueSet::PropertyMatches(
-    CSSPropertyID property_id,
-    const CSSValue& property_value) const {
-  int found_property_index = FindPropertyIndex(property_id);
-  if (found_property_index == -1)
-    return false;
-  return PropertyAt(found_property_index).Value() == property_value;
-}
-
-void MutableCSSPropertyValueSet::RemoveEquivalentProperties(
-    const CSSPropertyValueSet* style) {
-  Vector<CSSPropertyID> properties_to_remove;
-  unsigned size = property_vector_.size();
-  for (unsigned i = 0; i < size; ++i) {
-    PropertyReference property = PropertyAt(i);
-    if (style->PropertyMatches(property.Id(), property.Value()))
-      properties_to_remove.push_back(property.Id());
-  }
-  // FIXME: This should use mass removal.
-  for (unsigned i = 0; i < properties_to_remove.size(); ++i)
-    RemoveProperty(properties_to_remove[i]);
-}
-
-void MutableCSSPropertyValueSet::RemoveEquivalentProperties(
-    const CSSStyleDeclaration* style) {
-  Vector<CSSPropertyID> properties_to_remove;
-  unsigned size = property_vector_.size();
-  for (unsigned i = 0; i < size; ++i) {
-    PropertyReference property = PropertyAt(i);
-    if (style->CssPropertyMatches(property.Id(), &property.Value()))
-      properties_to_remove.push_back(property.Id());
-  }
-  // FIXME: This should use mass removal.
-  for (unsigned i = 0; i < properties_to_remove.size(); ++i)
-    RemoveProperty(properties_to_remove[i]);
-}
-
 MutableCSSPropertyValueSet* CSSPropertyValueSet::MutableCopy() const {
   return new MutableCSSPropertyValueSet(*this);
 }
@@ -598,49 +169,10 @@
   return MutableCSSPropertyValueSet::Create(list.data(), list.size());
 }
 
-CSSStyleDeclaration* MutableCSSPropertyValueSet::EnsureCSSStyleDeclaration() {
-  // FIXME: get rid of this weirdness of a CSSStyleDeclaration inside of a
-  // style property set.
-  if (cssom_wrapper_) {
-    DCHECK(
-        !static_cast<CSSStyleDeclaration*>(cssom_wrapper_.Get())->parentRule());
-    DCHECK(!cssom_wrapper_->ParentElement());
-    return cssom_wrapper_.Get();
-  }
-  cssom_wrapper_ = new PropertySetCSSStyleDeclaration(*this);
-  return cssom_wrapper_.Get();
-}
-
-template <typename T>
-int MutableCSSPropertyValueSet::FindPropertyIndex(T property) const {
-  const CSSPropertyValue* begin = property_vector_.data();
-  const CSSPropertyValue* end = begin + property_vector_.size();
-
-  uint16_t id = GetConvertedCSSPropertyID(property);
-
-  const CSSPropertyValue* it = std::find_if(
-      begin, end, [property, id](const CSSPropertyValue& css_property) -> bool {
-        return IsPropertyMatch(css_property.Metadata(), *css_property.Value(),
-                               id, property);
-      });
-
-  return (it == end) ? -1 : it - begin;
-}
-template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
-    CSSPropertyID) const;
-template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
-    AtomicString) const;
-
-void MutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
-  visitor->Trace(cssom_wrapper_);
-  visitor->Trace(property_vector_);
-  CSSPropertyValueSet::TraceAfterDispatch(visitor);
-}
-
 unsigned CSSPropertyValueSet::AverageSizeInBytes() {
   // Please update this if the storage scheme changes so that this longer
   // reflects the actual size.
-  return SizeForImmutableCSSPropertyValueSetWithPropertyCount(4);
+  return ImmutableCSSPropertyValueSet::SizeWithPropertyCount(4);
 }
 
 // See the function above if you need to update this.
@@ -658,17 +190,107 @@
 }
 #endif
 
-MutableCSSPropertyValueSet* MutableCSSPropertyValueSet::Create(
-    CSSParserMode css_parser_mode) {
-  return new MutableCSSPropertyValueSet(css_parser_mode);
+const CSSPropertyValueMetadata&
+CSSPropertyValueSet::PropertyReference::PropertyMetadata() const {
+  if (property_set_->IsMutable()) {
+    return ToMutableCSSPropertyValueSet(*property_set_)
+        .property_vector_.at(index_)
+        .Metadata();
+  }
+  return ToImmutableCSSPropertyValueSet(*property_set_).MetadataArray()[index_];
 }
 
-MutableCSSPropertyValueSet* MutableCSSPropertyValueSet::Create(
-    const CSSPropertyValue* properties,
-    unsigned count) {
-  return new MutableCSSPropertyValueSet(properties, count);
+const CSSValue& CSSPropertyValueSet::PropertyReference::PropertyValue() const {
+  if (property_set_->IsMutable()) {
+    return *ToMutableCSSPropertyValueSet(*property_set_)
+                .property_vector_.at(index_)
+                .Value();
+  }
+  return *ToImmutableCSSPropertyValueSet(*property_set_).ValueArray()[index_];
 }
 
-void CSSLazyPropertyParser::Trace(blink::Visitor* visitor) {}
+unsigned CSSPropertyValueSet::PropertyCount() const {
+  if (is_mutable_)
+    return ToMutableCSSPropertyValueSet(this)->property_vector_.size();
+  return array_size_;
+}
+
+bool CSSPropertyValueSet::IsEmpty() const {
+  return !PropertyCount();
+}
+
+template <typename T>
+int CSSPropertyValueSet::FindPropertyIndex(T property) const {
+  if (is_mutable_)
+    return ToMutableCSSPropertyValueSet(this)->FindPropertyIndex(property);
+  return ToImmutableCSSPropertyValueSet(this)->FindPropertyIndex(property);
+}
+template CORE_EXPORT int CSSPropertyValueSet::FindPropertyIndex(
+    CSSPropertyID) const;
+template CORE_EXPORT int CSSPropertyValueSet::FindPropertyIndex(
+    AtomicString) const;
+template CORE_EXPORT int CSSPropertyValueSet::FindPropertyIndex(
+    AtRuleDescriptorID) const;
+
+// Convert property into an uint16_t for comparison with metadata's property id
+// to avoid the compiler converting it to an int multiple times in a loop.
+uint16_t CSSPropertyValueSet::GetConvertedCSSPropertyID(
+    CSSPropertyID property_id) {
+  return static_cast<uint16_t>(property_id);
+}
+
+uint16_t CSSPropertyValueSet::GetConvertedCSSPropertyID(const AtomicString&) {
+  return static_cast<uint16_t>(CSSPropertyVariable);
+}
+
+uint16_t CSSPropertyValueSet::GetConvertedCSSPropertyID(
+    AtRuleDescriptorID descriptor_id) {
+  return static_cast<uint16_t>(
+      AtRuleDescriptorIDAsCSSPropertyID(descriptor_id));
+}
+
+bool CSSPropertyValueSet::IsPropertyMatch(
+    const CSSPropertyValueMetadata& metadata,
+    const CSSValue&,
+    uint16_t id,
+    CSSPropertyID property_id) {
+  DCHECK_EQ(id, property_id);
+  bool result = metadata.Property().PropertyID() == id;
+// Only enabled properties should be part of the style.
+#if DCHECK_IS_ON()
+  DCHECK(!result ||
+         CSSProperty::Get(resolveCSSPropertyID(property_id)).IsEnabled());
+#endif
+  return result;
+}
+
+bool CSSPropertyValueSet::IsPropertyMatch(
+    const CSSPropertyValueMetadata& metadata,
+    const CSSValue& value,
+    uint16_t id,
+    const AtomicString& custom_property_name) {
+  DCHECK_EQ(id, CSSPropertyVariable);
+  return metadata.Property().PropertyID() == id &&
+         ToCSSCustomPropertyDeclaration(value).GetName() ==
+             custom_property_name;
+}
+
+bool CSSPropertyValueSet::IsPropertyMatch(
+    const CSSPropertyValueMetadata& metadata,
+    const CSSValue& css_value,
+    uint16_t id,
+    AtRuleDescriptorID descriptor_id) {
+  return IsPropertyMatch(metadata, css_value, id,
+                         AtRuleDescriptorIDAsCSSPropertyID(descriptor_id));
+}
+
+bool CSSPropertyValueSet::HasFailedOrCanceledSubresources() const {
+  unsigned size = PropertyCount();
+  for (unsigned i = 0; i < size; ++i) {
+    if (PropertyAt(i).Value().HasFailedOrCanceledSubresources())
+      return true;
+  }
+  return false;
+}
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/CSSPropertyValueSet.h b/third_party/WebKit/Source/core/css/CSSPropertyValueSet.h
index 5a01dc07..42926ee 100644
--- a/third_party/WebKit/Source/core/css/CSSPropertyValueSet.h
+++ b/third_party/WebKit/Source/core/css/CSSPropertyValueSet.h
@@ -27,6 +27,7 @@
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSPropertyValue.h"
 #include "core/css/PropertySetCSSStyleDeclaration.h"
+#include "core/css/parser/AtRuleDescriptors.h"
 #include "core/css/parser/CSSParserMode.h"
 #include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/Vector.h"
@@ -34,11 +35,8 @@
 
 namespace blink {
 
-class CSSStyleDeclaration;
 class ImmutableCSSPropertyValueSet;
 class MutableCSSPropertyValueSet;
-class PropertyRegistry;
-class StyleSheetContents;
 enum class SecureContextMode;
 
 class CORE_EXPORT CSSPropertyValueSet
@@ -92,20 +90,20 @@
     return PropertyReference(*this, index);
   }
 
-  template <typename T>  // CSSPropertyID or AtomicString
+  template <typename T>  // CSSPropertyID, AtRuleDescriptorID or AtomicString
   int FindPropertyIndex(T property) const;
 
   bool HasProperty(CSSPropertyID property) const {
     return FindPropertyIndex(property) != -1;
   }
 
-  template <typename T>  // CSSPropertyID or AtomicString
+  template <typename T>  // CSSPropertyID, AtRuleDescriptorID or AtomicString
   const CSSValue* GetPropertyCSSValue(T property) const;
 
-  template <typename T>  // CSSPropertyID or AtomicString
+  template <typename T>  // CSSPropertyID, AtRuleDescriptorID or AtomicString
   String GetPropertyValue(T property) const;
 
-  template <typename T>  // CSSPropertyID or AtomicString
+  template <typename T>  // CSSPropertyID, AtRuleDescriptorID or AtomicString
   bool PropertyIsImportant(T property) const;
 
   bool ShorthandIsImportant(CSSPropertyID) const;
@@ -158,6 +156,22 @@
       array_size_ = unsigned(kMaxArraySize);
   }
 
+  static uint16_t GetConvertedCSSPropertyID(CSSPropertyID);
+  static uint16_t GetConvertedCSSPropertyID(const AtomicString&);
+  static uint16_t GetConvertedCSSPropertyID(AtRuleDescriptorID);
+  static bool IsPropertyMatch(const CSSPropertyValueMetadata&,
+                              const CSSValue&,
+                              uint16_t id,
+                              CSSPropertyID);
+  static bool IsPropertyMatch(const CSSPropertyValueMetadata&,
+                              const CSSValue&,
+                              uint16_t id,
+                              const AtomicString& custom_property_name);
+  static bool IsPropertyMatch(const CSSPropertyValueMetadata&,
+                              const CSSValue&,
+                              uint16_t id,
+                              AtRuleDescriptorID);
+
   unsigned css_parser_mode_ : 3;
   mutable unsigned is_mutable_ : 1;
   unsigned array_size_ : 28;
@@ -166,195 +180,6 @@
   DISALLOW_COPY_AND_ASSIGN(CSSPropertyValueSet);
 };
 
-// Used for lazily parsing properties.
-class CSSLazyPropertyParser
-    : public GarbageCollectedFinalized<CSSLazyPropertyParser> {
- public:
-  CSSLazyPropertyParser() = default;
-  virtual ~CSSLazyPropertyParser() = default;
-  virtual CSSPropertyValueSet* ParseProperties() = 0;
-  virtual void Trace(blink::Visitor*);
-  DISALLOW_COPY_AND_ASSIGN(CSSLazyPropertyParser);
-};
-
-class CORE_EXPORT ImmutableCSSPropertyValueSet : public CSSPropertyValueSet {
- public:
-  ~ImmutableCSSPropertyValueSet();
-  static ImmutableCSSPropertyValueSet*
-  Create(const CSSPropertyValue* properties, unsigned count, CSSParserMode);
-
-  unsigned PropertyCount() const { return array_size_; }
-
-  const Member<const CSSValue>* ValueArray() const;
-  const CSSPropertyValueMetadata* MetadataArray() const;
-
-  template <typename T>  // CSSPropertyID or AtomicString
-  int FindPropertyIndex(T property) const;
-
-  void TraceAfterDispatch(blink::Visitor*);
-
-  void* operator new(std::size_t, void* location) { return location; }
-
-  void* storage_;
-
- private:
-  ImmutableCSSPropertyValueSet(const CSSPropertyValue*,
-                               unsigned count,
-                               CSSParserMode);
-};
-
-inline const Member<const CSSValue>* ImmutableCSSPropertyValueSet::ValueArray()
-    const {
-  return reinterpret_cast<const Member<const CSSValue>*>(
-      const_cast<const void**>(&(this->storage_)));
-}
-
-inline const CSSPropertyValueMetadata*
-ImmutableCSSPropertyValueSet::MetadataArray() const {
-  return reinterpret_cast<const CSSPropertyValueMetadata*>(
-      &reinterpret_cast<const char*>(
-          &(this->storage_))[array_size_ * sizeof(Member<CSSValue>)]);
-}
-
-DEFINE_TYPE_CASTS(ImmutableCSSPropertyValueSet,
-                  CSSPropertyValueSet,
-                  set,
-                  !set->IsMutable(),
-                  !set.IsMutable());
-
-class CORE_EXPORT MutableCSSPropertyValueSet : public CSSPropertyValueSet {
- public:
-  ~MutableCSSPropertyValueSet() = default;
-  static MutableCSSPropertyValueSet* Create(CSSParserMode);
-  static MutableCSSPropertyValueSet* Create(const CSSPropertyValue* properties,
-                                            unsigned count);
-
-  unsigned PropertyCount() const { return property_vector_.size(); }
-
-  // Returns whether this style set was changed.
-  bool AddParsedProperties(const HeapVector<CSSPropertyValue, 256>&);
-  bool AddRespectingCascade(const CSSPropertyValue&);
-
-  struct SetResult {
-    bool did_parse;
-    bool did_change;
-  };
-  // These expand shorthand properties into multiple properties.
-  SetResult SetProperty(CSSPropertyID unresolved_property,
-                        const String& value,
-                        bool important,
-                        SecureContextMode,
-                        StyleSheetContents* context_style_sheet = nullptr);
-  SetResult SetProperty(const AtomicString& custom_property_name,
-                        const PropertyRegistry*,
-                        const String& value,
-                        bool important,
-                        SecureContextMode,
-                        StyleSheetContents* context_style_sheet,
-                        bool is_animation_tainted);
-  void SetProperty(CSSPropertyID, const CSSValue&, bool important = false);
-
-  // These do not. FIXME: This is too messy, we can do better.
-  bool SetProperty(CSSPropertyID,
-                   CSSValueID identifier,
-                   bool important = false);
-  bool SetProperty(const CSSPropertyValue&, CSSPropertyValue* slot = nullptr);
-
-  template <typename T>  // CSSPropertyID or AtomicString
-  bool RemoveProperty(T property, String* return_text = nullptr);
-  bool RemovePropertiesInSet(const CSSProperty** set, unsigned length);
-  void RemoveEquivalentProperties(const CSSPropertyValueSet*);
-  void RemoveEquivalentProperties(const CSSStyleDeclaration*);
-
-  void MergeAndOverrideOnConflict(const CSSPropertyValueSet*);
-
-  void Clear();
-  void ParseDeclarationList(const String& style_declaration,
-                            SecureContextMode,
-                            StyleSheetContents* context_style_sheet);
-
-  CSSStyleDeclaration* EnsureCSSStyleDeclaration();
-
-  template <typename T>  // CSSPropertyID or AtomicString
-  int FindPropertyIndex(T property) const;
-
-  void TraceAfterDispatch(blink::Visitor*);
-
- private:
-  explicit MutableCSSPropertyValueSet(CSSParserMode);
-  explicit MutableCSSPropertyValueSet(const CSSPropertyValueSet&);
-  MutableCSSPropertyValueSet(const CSSPropertyValue* properties,
-                             unsigned count);
-
-  bool RemovePropertyAtIndex(int, String* return_text);
-
-  bool RemoveShorthandProperty(CSSPropertyID);
-  bool RemoveShorthandProperty(const AtomicString& custom_property_name) {
-    return false;
-  }
-  CSSPropertyValue* FindCSSPropertyWithID(
-      CSSPropertyID,
-      const AtomicString& custom_property_name = g_null_atom);
-  Member<PropertySetCSSStyleDeclaration> cssom_wrapper_;
-
-  friend class CSSPropertyValueSet;
-
-  HeapVector<CSSPropertyValue, 4> property_vector_;
-};
-
-DEFINE_TYPE_CASTS(MutableCSSPropertyValueSet,
-                  CSSPropertyValueSet,
-                  set,
-                  set->IsMutable(),
-                  set.IsMutable());
-
-inline MutableCSSPropertyValueSet* ToMutableCSSPropertyValueSet(
-    const Persistent<CSSPropertyValueSet>& set) {
-  return ToMutableCSSPropertyValueSet(set.Get());
-}
-
-inline MutableCSSPropertyValueSet* ToMutableCSSPropertyValueSet(
-    const Member<CSSPropertyValueSet>& set) {
-  return ToMutableCSSPropertyValueSet(set.Get());
-}
-
-inline const CSSPropertyValueMetadata&
-CSSPropertyValueSet::PropertyReference::PropertyMetadata() const {
-  if (property_set_->IsMutable()) {
-    return ToMutableCSSPropertyValueSet(*property_set_)
-        .property_vector_.at(index_)
-        .Metadata();
-  }
-  return ToImmutableCSSPropertyValueSet(*property_set_).MetadataArray()[index_];
-}
-
-inline const CSSValue& CSSPropertyValueSet::PropertyReference::PropertyValue()
-    const {
-  if (property_set_->IsMutable()) {
-    return *ToMutableCSSPropertyValueSet(*property_set_)
-                .property_vector_.at(index_)
-                .Value();
-  }
-  return *ToImmutableCSSPropertyValueSet(*property_set_).ValueArray()[index_];
-}
-
-inline unsigned CSSPropertyValueSet::PropertyCount() const {
-  if (is_mutable_)
-    return ToMutableCSSPropertyValueSet(this)->property_vector_.size();
-  return array_size_;
-}
-
-inline bool CSSPropertyValueSet::IsEmpty() const {
-  return !PropertyCount();
-}
-
-template <typename T>
-inline int CSSPropertyValueSet::FindPropertyIndex(T property) const {
-  if (is_mutable_)
-    return ToMutableCSSPropertyValueSet(this)->FindPropertyIndex(property);
-  return ToImmutableCSSPropertyValueSet(this)->FindPropertyIndex(property);
-}
-
 }  // namespace blink
 
 #endif  // CSSPropertyValueSet_h
diff --git a/third_party/WebKit/Source/core/css/CSSSelectorWatch.cpp b/third_party/WebKit/Source/core/css/CSSSelectorWatch.cpp
index 54190eee..7ad8193 100644
--- a/third_party/WebKit/Source/core/css/CSSSelectorWatch.cpp
+++ b/third_party/WebKit/Source/core/css/CSSSelectorWatch.cpp
@@ -30,7 +30,7 @@
 
 #include "core/css/CSSSelectorWatch.h"
 
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/ImmutableCSSPropertyValueSet.h"
 #include "core/css/StyleEngine.h"
 #include "core/css/parser/CSSParser.h"
 #include "core/dom/Document.h"
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 59d065d..63d1f63 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -663,18 +663,18 @@
     const StyleContentAlignmentData& data) {
   CSSValueList* result = CSSValueList::CreateSpaceSeparated();
   // Handle content-distribution values
-  if (data.Distribution() != kContentDistributionDefault)
+  if (data.Distribution() != ContentDistributionType::kDefault)
     result->Append(*CSSIdentifierValue::Create(data.Distribution()));
 
   // Handle content-position values (either as fallback or actual value)
   switch (data.GetPosition()) {
-    case kContentPositionNormal:
+    case ContentPosition::kNormal:
       // Handle 'normal' value, not valid as content-distribution fallback.
-      if (data.Distribution() == kContentDistributionDefault) {
+      if (data.Distribution() == ContentDistributionType::kDefault) {
         result->Append(*CSSIdentifierValue::Create(CSSValueNormal));
       }
       break;
-    case kContentPositionLastBaseline:
+    case ContentPosition::kLastBaseline:
       result->Append(
           *CSSValuePair::Create(CSSIdentifierValue::Create(CSSValueLast),
                                 CSSIdentifierValue::Create(CSSValueBaseline),
@@ -685,8 +685,8 @@
   }
 
   // Handle overflow-alignment (only allowed for content-position values)
-  if ((data.GetPosition() >= kContentPositionCenter ||
-       data.Distribution() != kContentDistributionDefault) &&
+  if ((data.GetPosition() >= ContentPosition::kCenter ||
+       data.Distribution() != ContentDistributionType::kDefault) &&
       data.Overflow() != kOverflowAlignmentDefault)
     result->Append(*CSSIdentifierValue::Create(data.Overflow()));
   DCHECK_GT(result->length(), 0u);
diff --git a/third_party/WebKit/Source/core/css/FontFaceCacheTest.cpp b/third_party/WebKit/Source/core/css/FontFaceCacheTest.cpp
index f73dd1b..22d2761 100644
--- a/third_party/WebKit/Source/core/css/FontFaceCacheTest.cpp
+++ b/third_party/WebKit/Source/core/css/FontFaceCacheTest.cpp
@@ -6,11 +6,11 @@
 #include "core/css/CSSFontFamilyValue.h"
 #include "core/css/CSSFontStyleRangeValue.h"
 #include "core/css/CSSIdentifierValue.h"
-#include "core/css/CSSPropertyValueSet.h"
 #include "core/css/CSSSegmentedFontFace.h"
 #include "core/css/CSSValueList.h"
 #include "core/css/FontFace.h"
 #include "core/css/FontFaceCache.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleRule.h"
 #include "core/testing/PageTestBase.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/third_party/WebKit/Source/core/css/ImmutableCSSPropertyValueSet.cpp b/third_party/WebKit/Source/core/css/ImmutableCSSPropertyValueSet.cpp
new file mode 100644
index 0000000..853d790
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/ImmutableCSSPropertyValueSet.cpp
@@ -0,0 +1,81 @@
+// 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/ImmutableCSSPropertyValueSet.h"
+
+#include "core/css/MutableCSSPropertyValueSet.h"
+#include "core/css/parser/AtRuleDescriptors.h"
+
+namespace blink {
+
+size_t ImmutableCSSPropertyValueSet::SizeWithPropertyCount(unsigned count) {
+  return sizeof(ImmutableCSSPropertyValueSet) - sizeof(void*) +
+         sizeof(Member<CSSValue>) * count +
+         sizeof(CSSPropertyValueMetadata) * count;
+}
+
+ImmutableCSSPropertyValueSet* ImmutableCSSPropertyValueSet::Create(
+    const CSSPropertyValue* properties,
+    unsigned count,
+    CSSParserMode css_parser_mode) {
+  DCHECK_LE(count, static_cast<unsigned>(kMaxArraySize));
+  void* slot =
+      ThreadHeap::Allocate<CSSPropertyValueSet>(SizeWithPropertyCount(count));
+  return new (slot)
+      ImmutableCSSPropertyValueSet(properties, count, css_parser_mode);
+}
+
+ImmutableCSSPropertyValueSet* CSSPropertyValueSet::ImmutableCopyIfNeeded()
+    const {
+  if (!IsMutable()) {
+    return ToImmutableCSSPropertyValueSet(
+        const_cast<CSSPropertyValueSet*>(this));
+  }
+  const MutableCSSPropertyValueSet* mutable_this =
+      ToMutableCSSPropertyValueSet(this);
+  return ImmutableCSSPropertyValueSet::Create(
+      mutable_this->property_vector_.data(),
+      mutable_this->property_vector_.size(), CssParserMode());
+}
+
+ImmutableCSSPropertyValueSet::ImmutableCSSPropertyValueSet(
+    const CSSPropertyValue* properties,
+    unsigned length,
+    CSSParserMode css_parser_mode)
+    : CSSPropertyValueSet(css_parser_mode, length) {
+  CSSPropertyValueMetadata* metadata_array =
+      const_cast<CSSPropertyValueMetadata*>(this->MetadataArray());
+  Member<const CSSValue>* value_array =
+      const_cast<Member<const CSSValue>*>(this->ValueArray());
+  for (unsigned i = 0; i < array_size_; ++i) {
+    metadata_array[i] = properties[i].Metadata();
+    value_array[i] = properties[i].Value();
+  }
+}
+
+template <typename T>
+int ImmutableCSSPropertyValueSet::FindPropertyIndex(T property) const {
+  uint16_t id = GetConvertedCSSPropertyID(property);
+  for (int n = array_size_ - 1; n >= 0; --n) {
+    if (IsPropertyMatch(MetadataArray()[n], *ValueArray()[n], id, property))
+      return n;
+  }
+
+  return -1;
+}
+template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
+    CSSPropertyID) const;
+template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
+    AtomicString) const;
+template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
+    AtRuleDescriptorID) const;
+
+void ImmutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
+  const Member<const CSSValue>* values = ValueArray();
+  for (unsigned i = 0; i < array_size_; i++)
+    visitor->Trace(values[i]);
+  CSSPropertyValueSet::TraceAfterDispatch(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/ImmutableCSSPropertyValueSet.h b/third_party/WebKit/Source/core/css/ImmutableCSSPropertyValueSet.h
new file mode 100644
index 0000000..8c441890
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/ImmutableCSSPropertyValueSet.h
@@ -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.
+
+#ifndef ImmutableCSSPropertyValueSet_h
+#define ImmutableCSSPropertyValueSet_h
+
+#include "core/css/CSSPropertyValueSet.h"
+
+namespace blink {
+
+class CORE_EXPORT ImmutableCSSPropertyValueSet : public CSSPropertyValueSet {
+ public:
+  static size_t SizeWithPropertyCount(unsigned count);
+  static ImmutableCSSPropertyValueSet*
+  Create(const CSSPropertyValue* properties, unsigned count, CSSParserMode);
+
+  unsigned PropertyCount() const { return array_size_; }
+
+  const Member<const CSSValue>* ValueArray() const;
+  const CSSPropertyValueMetadata* MetadataArray() const;
+
+  template <typename T>  // CSSPropertyID or AtomicString
+  int FindPropertyIndex(T property) const;
+
+  void TraceAfterDispatch(blink::Visitor*);
+
+  void* operator new(std::size_t, void* location) { return location; }
+
+  void* storage_;
+
+ private:
+  ImmutableCSSPropertyValueSet(const CSSPropertyValue*,
+                               unsigned count,
+                               CSSParserMode);
+};
+
+inline const Member<const CSSValue>* ImmutableCSSPropertyValueSet::ValueArray()
+    const {
+  return reinterpret_cast<const Member<const CSSValue>*>(
+      const_cast<const void**>(&(this->storage_)));
+}
+
+inline const CSSPropertyValueMetadata*
+ImmutableCSSPropertyValueSet::MetadataArray() const {
+  return reinterpret_cast<const CSSPropertyValueMetadata*>(
+      &reinterpret_cast<const char*>(
+          &(this->storage_))[array_size_ * sizeof(Member<CSSValue>)]);
+}
+
+DEFINE_TYPE_CASTS(ImmutableCSSPropertyValueSet,
+                  CSSPropertyValueSet,
+                  set,
+                  !set->IsMutable(),
+                  !set.IsMutable());
+
+}  // namespace blink
+
+#endif  // ImmutableCSSPropertyValueSet_h
diff --git a/third_party/WebKit/Source/core/css/MutableCSSPropertyValueSet.cpp b/third_party/WebKit/Source/core/css/MutableCSSPropertyValueSet.cpp
new file mode 100644
index 0000000..183ae27
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/MutableCSSPropertyValueSet.cpp
@@ -0,0 +1,373 @@
+// 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/MutableCSSPropertyValueSet.h"
+
+#include "core/StylePropertyShorthand.h"
+#include "core/css/CSSCustomPropertyDeclaration.h"
+#include "core/css/CSSIdentifierValue.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/css/parser/CSSParser.h"
+#include "core/css/parser/CSSParserContext.h"
+
+namespace blink {
+
+namespace {
+
+inline bool ContainsId(const CSSProperty** set,
+                       unsigned length,
+                       CSSPropertyID id) {
+  for (unsigned i = 0; i < length; ++i) {
+    if (set[i]->IDEquals(id))
+      return true;
+  }
+  return false;
+}
+
+}  // namespace
+
+MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
+    CSSParserMode css_parser_mode)
+    : CSSPropertyValueSet(css_parser_mode) {}
+
+MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
+    const CSSPropertyValue* properties,
+    unsigned length)
+    : CSSPropertyValueSet(kHTMLStandardMode) {
+  property_vector_.ReserveInitialCapacity(length);
+  for (unsigned i = 0; i < length; ++i)
+    property_vector_.UncheckedAppend(properties[i]);
+}
+
+MutableCSSPropertyValueSet::MutableCSSPropertyValueSet(
+    const CSSPropertyValueSet& other)
+    : CSSPropertyValueSet(other.CssParserMode()) {
+  if (other.IsMutable()) {
+    property_vector_ = ToMutableCSSPropertyValueSet(other).property_vector_;
+  } else {
+    property_vector_.ReserveInitialCapacity(other.PropertyCount());
+    for (unsigned i = 0; i < other.PropertyCount(); ++i) {
+      property_vector_.UncheckedAppend(
+          other.PropertyAt(i).ToCSSPropertyValue());
+    }
+  }
+}
+
+bool MutableCSSPropertyValueSet::RemoveShorthandProperty(
+    CSSPropertyID property_id) {
+  StylePropertyShorthand shorthand = shorthandForProperty(property_id);
+  if (!shorthand.length())
+    return false;
+
+  return RemovePropertiesInSet(shorthand.properties(), shorthand.length());
+}
+
+bool MutableCSSPropertyValueSet::RemovePropertyAtIndex(int property_index,
+                                                       String* return_text) {
+  if (property_index == -1) {
+    if (return_text)
+      *return_text = "";
+    return false;
+  }
+
+  if (return_text)
+    *return_text = PropertyAt(property_index).Value().CssText();
+
+  // A more efficient removal strategy would involve marking entries as empty
+  // and sweeping them when the vector grows too big.
+  property_vector_.EraseAt(property_index);
+
+  return true;
+}
+
+template <typename T>
+bool MutableCSSPropertyValueSet::RemoveProperty(T property,
+                                                String* return_text) {
+  if (RemoveShorthandProperty(property)) {
+    // FIXME: Return an equivalent shorthand when possible.
+    if (return_text)
+      *return_text = "";
+    return true;
+  }
+
+  int found_property_index = FindPropertyIndex(property);
+  return RemovePropertyAtIndex(found_property_index, return_text);
+}
+template CORE_EXPORT bool MutableCSSPropertyValueSet::RemoveProperty(
+    CSSPropertyID,
+    String*);
+template CORE_EXPORT bool MutableCSSPropertyValueSet::RemoveProperty(
+    AtomicString,
+    String*);
+
+MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
+    CSSPropertyID unresolved_property,
+    const String& value,
+    bool important,
+    SecureContextMode secure_context_mode,
+    StyleSheetContents* context_style_sheet) {
+  DCHECK_GE(unresolved_property, firstCSSProperty);
+
+  // Setting the value to an empty string just removes the property in both IE
+  // and Gecko. Setting it to null seems to produce less consistent results, but
+  // we treat it just the same.
+  if (value.IsEmpty()) {
+    bool did_parse = true;
+    bool did_change = RemoveProperty(resolveCSSPropertyID(unresolved_property));
+    return SetResult{did_parse, did_change};
+  }
+
+  // When replacing an existing property value, this moves the property to the
+  // end of the list. Firefox preserves the position, and MSIE moves the
+  // property to the beginning.
+  return CSSParser::ParseValue(this, unresolved_property, value, important,
+                               secure_context_mode, context_style_sheet);
+}
+
+MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
+    const AtomicString& custom_property_name,
+    const PropertyRegistry* registry,
+    const String& value,
+    bool important,
+    SecureContextMode secure_context_mode,
+    StyleSheetContents* context_style_sheet,
+    bool is_animation_tainted) {
+  if (value.IsEmpty()) {
+    bool did_parse = true;
+    bool did_change = RemoveProperty(custom_property_name);
+    return MutableCSSPropertyValueSet::SetResult{did_parse, did_change};
+  }
+  return CSSParser::ParseValueForCustomProperty(
+      this, custom_property_name, registry, value, important,
+      secure_context_mode, context_style_sheet, is_animation_tainted);
+}
+
+void MutableCSSPropertyValueSet::SetProperty(CSSPropertyID property_id,
+                                             const CSSValue& value,
+                                             bool important) {
+  StylePropertyShorthand shorthand = shorthandForProperty(property_id);
+  if (!shorthand.length()) {
+    SetProperty(
+        CSSPropertyValue(CSSProperty::Get(property_id), value, important));
+    return;
+  }
+
+  RemovePropertiesInSet(shorthand.properties(), shorthand.length());
+
+  for (unsigned i = 0; i < shorthand.length(); ++i) {
+    property_vector_.push_back(
+        CSSPropertyValue(*shorthand.properties()[i], value, important));
+  }
+}
+
+bool MutableCSSPropertyValueSet::SetProperty(const CSSPropertyValue& property,
+                                             CSSPropertyValue* slot) {
+  const AtomicString& name =
+      (property.Id() == CSSPropertyVariable)
+          ? ToCSSCustomPropertyDeclaration(property.Value())->GetName()
+          : g_null_atom;
+  CSSPropertyValue* to_replace =
+      slot ? slot : FindCSSPropertyWithID(property.Id(), name);
+  if (to_replace && *to_replace == property)
+    return false;
+  if (to_replace) {
+    *to_replace = property;
+    return true;
+  }
+  property_vector_.push_back(property);
+  return true;
+}
+
+bool MutableCSSPropertyValueSet::SetProperty(CSSPropertyID property_id,
+                                             CSSValueID identifier,
+                                             bool important) {
+  SetProperty(CSSPropertyValue(CSSProperty::Get(property_id),
+                               *CSSIdentifierValue::Create(identifier),
+                               important));
+  return true;
+}
+
+void MutableCSSPropertyValueSet::ParseDeclarationList(
+    const String& style_declaration,
+    SecureContextMode secure_context_mode,
+    StyleSheetContents* context_style_sheet) {
+  property_vector_.clear();
+
+  CSSParserContext* context;
+  if (context_style_sheet) {
+    context = CSSParserContext::CreateWithStyleSheetContents(
+        context_style_sheet->ParserContext(), context_style_sheet);
+    context->SetMode(CssParserMode());
+  } else {
+    context = CSSParserContext::Create(CssParserMode(), secure_context_mode);
+  }
+
+  CSSParser::ParseDeclarationList(context, this, style_declaration);
+}
+
+bool MutableCSSPropertyValueSet::AddParsedProperties(
+    const HeapVector<CSSPropertyValue, 256>& properties) {
+  bool changed = false;
+  property_vector_.ReserveCapacity(property_vector_.size() + properties.size());
+  for (unsigned i = 0; i < properties.size(); ++i)
+    changed |= SetProperty(properties[i]);
+  return changed;
+}
+
+bool MutableCSSPropertyValueSet::AddRespectingCascade(
+    const CSSPropertyValue& property) {
+  // Only add properties that have no !important counterpart present
+  if (!PropertyIsImportant(property.Id()) || property.IsImportant())
+    return SetProperty(property);
+  return false;
+}
+
+void MutableCSSPropertyValueSet::MergeAndOverrideOnConflict(
+    const CSSPropertyValueSet* other) {
+  unsigned size = other->PropertyCount();
+  for (unsigned n = 0; n < size; ++n) {
+    PropertyReference to_merge = other->PropertyAt(n);
+    // TODO(leviw): This probably doesn't work correctly with Custom Properties
+    CSSPropertyValue* old = FindCSSPropertyWithID(to_merge.Id());
+    if (old)
+      SetProperty(to_merge.ToCSSPropertyValue(), old);
+    else
+      property_vector_.push_back(to_merge.ToCSSPropertyValue());
+  }
+}
+
+void MutableCSSPropertyValueSet::Clear() {
+  property_vector_.clear();
+}
+
+bool MutableCSSPropertyValueSet::RemovePropertiesInSet(const CSSProperty** set,
+                                                       unsigned length) {
+  if (property_vector_.IsEmpty())
+    return false;
+
+  CSSPropertyValue* properties = property_vector_.data();
+  unsigned old_size = property_vector_.size();
+  unsigned new_index = 0;
+  for (unsigned old_index = 0; old_index < old_size; ++old_index) {
+    const CSSPropertyValue& property = properties[old_index];
+    if (ContainsId(set, length, property.Id()))
+      continue;
+    // Modify property_vector_ in-place since this method is
+    // performance-sensitive.
+    properties[new_index++] = properties[old_index];
+  }
+  if (new_index != old_size) {
+    property_vector_.Shrink(new_index);
+    return true;
+  }
+  return false;
+}
+
+CSSPropertyValue* MutableCSSPropertyValueSet::FindCSSPropertyWithID(
+    CSSPropertyID property_id,
+    const AtomicString& custom_property_name) {
+  int found_property_index = -1;
+  if (property_id == CSSPropertyVariable && !custom_property_name.IsNull()) {
+    // TODO(shanestephens): fix call sites so we always have a
+    // customPropertyName here.
+    found_property_index = FindPropertyIndex(custom_property_name);
+  } else {
+    DCHECK(custom_property_name.IsNull());
+    found_property_index = FindPropertyIndex(property_id);
+  }
+  if (found_property_index == -1)
+    return nullptr;
+  return &property_vector_.at(found_property_index);
+}
+
+bool CSSPropertyValueSet::PropertyMatches(
+    CSSPropertyID property_id,
+    const CSSValue& property_value) const {
+  int found_property_index = FindPropertyIndex(property_id);
+  if (found_property_index == -1)
+    return false;
+  return PropertyAt(found_property_index).Value() == property_value;
+}
+
+void MutableCSSPropertyValueSet::RemoveEquivalentProperties(
+    const CSSPropertyValueSet* style) {
+  Vector<CSSPropertyID> properties_to_remove;
+  unsigned size = property_vector_.size();
+  for (unsigned i = 0; i < size; ++i) {
+    PropertyReference property = PropertyAt(i);
+    if (style->PropertyMatches(property.Id(), property.Value()))
+      properties_to_remove.push_back(property.Id());
+  }
+  // FIXME: This should use mass removal.
+  for (unsigned i = 0; i < properties_to_remove.size(); ++i)
+    RemoveProperty(properties_to_remove[i]);
+}
+
+void MutableCSSPropertyValueSet::RemoveEquivalentProperties(
+    const CSSStyleDeclaration* style) {
+  Vector<CSSPropertyID> properties_to_remove;
+  unsigned size = property_vector_.size();
+  for (unsigned i = 0; i < size; ++i) {
+    PropertyReference property = PropertyAt(i);
+    if (style->CssPropertyMatches(property.Id(), &property.Value()))
+      properties_to_remove.push_back(property.Id());
+  }
+  // FIXME: This should use mass removal.
+  for (unsigned i = 0; i < properties_to_remove.size(); ++i)
+    RemoveProperty(properties_to_remove[i]);
+}
+
+CSSStyleDeclaration* MutableCSSPropertyValueSet::EnsureCSSStyleDeclaration() {
+  // FIXME: get rid of this weirdness of a CSSStyleDeclaration inside of a
+  // style property set.
+  if (cssom_wrapper_) {
+    DCHECK(
+        !static_cast<CSSStyleDeclaration*>(cssom_wrapper_.Get())->parentRule());
+    DCHECK(!cssom_wrapper_->ParentElement());
+    return cssom_wrapper_.Get();
+  }
+  cssom_wrapper_ = new PropertySetCSSStyleDeclaration(*this);
+  return cssom_wrapper_.Get();
+}
+
+template <typename T>
+int MutableCSSPropertyValueSet::FindPropertyIndex(T property) const {
+  const CSSPropertyValue* begin = property_vector_.data();
+  const CSSPropertyValue* end = begin + property_vector_.size();
+
+  uint16_t id = CSSPropertyValueSet::GetConvertedCSSPropertyID(property);
+
+  const CSSPropertyValue* it = std::find_if(
+      begin, end, [property, id](const CSSPropertyValue& css_property) -> bool {
+        return IsPropertyMatch(css_property.Metadata(), *css_property.Value(),
+                               id, property);
+      });
+
+  return (it == end) ? -1 : it - begin;
+}
+template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
+    CSSPropertyID) const;
+template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
+    AtomicString) const;
+template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
+    AtRuleDescriptorID) const;
+
+void MutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
+  visitor->Trace(cssom_wrapper_);
+  visitor->Trace(property_vector_);
+  CSSPropertyValueSet::TraceAfterDispatch(visitor);
+}
+
+MutableCSSPropertyValueSet* MutableCSSPropertyValueSet::Create(
+    CSSParserMode css_parser_mode) {
+  return new MutableCSSPropertyValueSet(css_parser_mode);
+}
+
+MutableCSSPropertyValueSet* MutableCSSPropertyValueSet::Create(
+    const CSSPropertyValue* properties,
+    unsigned count) {
+  return new MutableCSSPropertyValueSet(properties, count);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/MutableCSSPropertyValueSet.h b/third_party/WebKit/Source/core/css/MutableCSSPropertyValueSet.h
new file mode 100644
index 0000000..1d08d83b
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/MutableCSSPropertyValueSet.h
@@ -0,0 +1,100 @@
+// 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 MutableCSSPropertyValueSet_h
+#define MutableCSSPropertyValueSet_h
+
+#include "core/css/CSSPropertyValueSet.h"
+
+namespace blink {
+
+class CORE_EXPORT MutableCSSPropertyValueSet : public CSSPropertyValueSet {
+ public:
+  ~MutableCSSPropertyValueSet() = default;
+  static MutableCSSPropertyValueSet* Create(CSSParserMode);
+  static MutableCSSPropertyValueSet* Create(const CSSPropertyValue* properties,
+                                            unsigned count);
+
+  unsigned PropertyCount() const { return property_vector_.size(); }
+
+  // Returns whether this style set was changed.
+  bool AddParsedProperties(const HeapVector<CSSPropertyValue, 256>&);
+  bool AddRespectingCascade(const CSSPropertyValue&);
+
+  struct SetResult {
+    bool did_parse;
+    bool did_change;
+  };
+  // These expand shorthand properties into multiple properties.
+  SetResult SetProperty(CSSPropertyID unresolved_property,
+                        const String& value,
+                        bool important,
+                        SecureContextMode,
+                        StyleSheetContents* context_style_sheet = nullptr);
+  SetResult SetProperty(const AtomicString& custom_property_name,
+                        const PropertyRegistry*,
+                        const String& value,
+                        bool important,
+                        SecureContextMode,
+                        StyleSheetContents* context_style_sheet,
+                        bool is_animation_tainted);
+  void SetProperty(CSSPropertyID, const CSSValue&, bool important = false);
+
+  // These do not. FIXME: This is too messy, we can do better.
+  bool SetProperty(CSSPropertyID,
+                   CSSValueID identifier,
+                   bool important = false);
+  bool SetProperty(const CSSPropertyValue&, CSSPropertyValue* slot = nullptr);
+
+  template <typename T>  // CSSPropertyID or AtomicString
+  bool RemoveProperty(T property, String* return_text = nullptr);
+  bool RemovePropertiesInSet(const CSSProperty** set, unsigned length);
+  void RemoveEquivalentProperties(const CSSPropertyValueSet*);
+  void RemoveEquivalentProperties(const CSSStyleDeclaration*);
+
+  void MergeAndOverrideOnConflict(const CSSPropertyValueSet*);
+
+  void Clear();
+  void ParseDeclarationList(const String& style_declaration,
+                            SecureContextMode,
+                            StyleSheetContents* context_style_sheet);
+
+  CSSStyleDeclaration* EnsureCSSStyleDeclaration();
+
+  template <typename T>  // CSSPropertyID, AtRuleDescriptorID or AtomicString
+  int FindPropertyIndex(T property) const;
+
+  void TraceAfterDispatch(blink::Visitor*);
+
+ private:
+  explicit MutableCSSPropertyValueSet(CSSParserMode);
+  explicit MutableCSSPropertyValueSet(const CSSPropertyValueSet&);
+  MutableCSSPropertyValueSet(const CSSPropertyValue* properties,
+                             unsigned count);
+
+  bool RemovePropertyAtIndex(int, String* return_text);
+
+  bool RemoveShorthandProperty(CSSPropertyID);
+  bool RemoveShorthandProperty(const AtomicString& custom_property_name) {
+    return false;
+  }
+  CSSPropertyValue* FindCSSPropertyWithID(
+      CSSPropertyID,
+      const AtomicString& custom_property_name = g_null_atom);
+  Member<PropertySetCSSStyleDeclaration> cssom_wrapper_;
+
+  friend class CSSPropertyValueSet;
+
+  HeapVector<CSSPropertyValue, 4> property_vector_;
+};
+
+DEFINE_TYPE_CASTS(MutableCSSPropertyValueSet,
+                  CSSPropertyValueSet,
+                  set,
+                  set->IsMutable(),
+                  set.IsMutable());
+
+}  // namespace blink
+
+#endif  // MutableCSSPropertyValueSet_h
diff --git a/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp b/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp
index 0d9a185..7e6fc67 100644
--- a/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp
+++ b/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp
@@ -29,6 +29,7 @@
 #include "core/css/CSSKeyframesRule.h"
 #include "core/css/CSSPropertyValueSet.h"
 #include "core/css/CSSStyleSheet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleChangeReason.h"
 #include "core/css/StyleEngine.h"
 #include "core/dom/Element.h"
@@ -179,8 +180,13 @@
   StyleAttributeMutationScope mutation_scope(this);
   WillMutate();
 
-  PropertySet().ParseDeclarationList(
-      text, execution_context->GetSecureContextMode(), ContextStyleSheet());
+  // A null execution_context may be passed in by the inspector, this shouldn't
+  // occur normally.
+  const SecureContextMode mode = execution_context
+                                     ? execution_context->GetSecureContextMode()
+                                     : SecureContextMode::kInsecureContext;
+
+  PropertySet().ParseDeclarationList(text, mode, ContextStyleSheet());
 
   DidMutate(kPropertyChanged);
 
diff --git a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
index 0814409..b540a2b 100644
--- a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
+++ b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
@@ -210,16 +210,23 @@
 
   FontResource* font = ToFontResource(GetResource());
   if (font->StillNeedsLoad()) {
-    if (!font->Url().ProtocolIsData() && !font->IsLoaded() &&
-        display_ == kFontDisplayAuto &&
-        font->IsLowPriorityLoadingAllowedForRemoteFont()) {
-      // Set the loading priority to VeryLow since this font is not required
-      // for painting the text.
-      font->DidChangePriority(ResourceLoadPriority::kVeryLow, 0);
+    if (is_intervention_triggered_) {
+      font_selector_->GetExecutionContext()->AddConsoleMessage(
+          ConsoleMessage::Create(
+              kOtherMessageSource, kInfoMessageLevel,
+              "Slow network is detected. See "
+              "https://www.chromestatus.com/feature/5636954674692096 for more "
+              "details. Fallback font will be used while loading: " +
+                  font->Url().ElidedString()));
+
+      // Set the loading priority to VeryLow only when all other clients agreed
+      // that this font is not required for painting the text.
+      if (font->IsLowPriorityLoadingAllowedForRemoteFont())
+        font->DidChangePriority(ResourceLoadPriority::kVeryLow, 0);
     }
     if (font_selector_->GetExecutionContext()->Fetcher()->StartLoad(font)) {
       // Start timers only when load is actually started asynchronously.
-      if (!font->IsLoaded()) {
+      if (!IsLoaded()) {
         font->StartLoadLimitTimers(
             font_selector_->GetExecutionContext()
                 ->GetTaskRunner(TaskType::kUnspecedLoading)
@@ -227,13 +234,6 @@
       }
       histograms_.LoadStarted();
     }
-    if (is_intervention_triggered_) {
-      font_selector_->GetExecutionContext()->AddConsoleMessage(
-          ConsoleMessage::Create(kOtherMessageSource, kInfoMessageLevel,
-                                 "Slow network is detected. Fallback font will "
-                                 "be used while loading: " +
-                                     font->Url().ElidedString()));
-    }
   }
 
   face_->DidBeginLoad();
diff --git a/third_party/WebKit/Source/core/css/StyleRule.cpp b/third_party/WebKit/Source/core/css/StyleRule.cpp
index 7feec2a1..44f9876 100644
--- a/third_party/WebKit/Source/core/css/StyleRule.cpp
+++ b/third_party/WebKit/Source/core/css/StyleRule.cpp
@@ -30,9 +30,11 @@
 #include "core/css/CSSStyleRule.h"
 #include "core/css/CSSSupportsRule.h"
 #include "core/css/CSSViewportRule.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleRuleImport.h"
 #include "core/css/StyleRuleKeyframe.h"
 #include "core/css/StyleRuleNamespace.h"
+#include "core/css/parser/CSSLazyPropertyParser.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/css/StyleRule.h b/third_party/WebKit/Source/core/css/StyleRule.h
index 2218bd9..7018056 100644
--- a/third_party/WebKit/Source/core/css/StyleRule.h
+++ b/third_party/WebKit/Source/core/css/StyleRule.h
@@ -31,6 +31,7 @@
 
 namespace blink {
 
+class CSSLazyPropertyParser;
 class CSSRule;
 class CSSStyleSheet;
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp
index db27ae4..afda142 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSNumericValue.cpp
@@ -213,10 +213,8 @@
 }
 
 CSSNumericValue* CSSNumericValue::FromCSSValue(const CSSPrimitiveValue& value) {
-  if (value.IsCalculated()) {
-    // TODO(meade): Implement this case.
-    return nullptr;
-  }
+  if (value.IsCalculated())
+    return CalcToNumericValue(*value.CssCalcValue()->ExpressionNode());
   return CSSUnitValue::FromCSSValue(value);
 }
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp b/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp
index 49eafd1..af4e165 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp
@@ -41,6 +41,10 @@
 CSSPerspective* CSSPerspective::FromCSSValue(const CSSFunctionValue& value) {
   DCHECK_EQ(value.FunctionType(), CSSValuePerspective);
   DCHECK_EQ(value.length(), 1U);
+  if (!value.Item(0).IsPrimitiveValue() ||
+      !ToCSSPrimitiveValue(value.Item(0)).IsLength() ||
+      ToCSSPrimitiveValue(value.Item(0)).IsCalculated())
+    return nullptr;
   CSSNumericValue* length =
       CSSNumericValue::FromCSSValue(ToCSSPrimitiveValue(value.Item(0)));
   // TODO(meade): This shouldn't happen once CSSNumericValue is fully
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
index 918ba92..f14e374 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
@@ -49,12 +49,14 @@
   return new CSSUnitValue(value, unit);
 }
 
-CSSUnitValue* CSSUnitValue::FromCSSValue(
-    const CSSPrimitiveValue& css_primitive_value) {
-  if (!IsValidUnit(css_primitive_value.TypeWithCalcResolved()))
+CSSUnitValue* CSSUnitValue::FromCSSValue(const CSSPrimitiveValue& value) {
+  CSSPrimitiveValue::UnitType unit = value.TypeWithCalcResolved();
+  if (unit == CSSPrimitiveValue::UnitType::kInteger)
+    unit = CSSPrimitiveValue::UnitType::kNumber;
+
+  if (!IsValidUnit(unit))
     return nullptr;
-  return new CSSUnitValue(css_primitive_value.GetDoubleValue(),
-                          css_primitive_value.TypeWithCalcResolved());
+  return new CSSUnitValue(value.GetDoubleValue(), unit);
 }
 
 void CSSUnitValue::setUnit(const String& unit_name,
diff --git a/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp b/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp
index c6437621..4058e4c0 100644
--- a/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp
@@ -10,6 +10,7 @@
 #include "core/css/CSSCustomPropertyDeclaration.h"
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/cssom/CSSUnsupportedStyleValue.h"
 #include "core/css/cssom/StyleValueFactory.h"
 #include "core/css/properties/CSSProperty.h"
diff --git a/third_party/WebKit/Source/core/css/parser/CSSLazyPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSLazyPropertyParser.h
new file mode 100644
index 0000000..00eb0a4b
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/parser/CSSLazyPropertyParser.h
@@ -0,0 +1,28 @@
+// 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 CSSLazyPropertyParser_h
+#define CSSLazyPropertyParser_h
+
+#include "platform/heap/GarbageCollected.h"
+#include "platform/heap/Heap.h"
+
+namespace blink {
+
+class CSSPropertyValueSet;
+
+// Used for lazily parsing properties.
+class CSSLazyPropertyParser
+    : public GarbageCollectedFinalized<CSSLazyPropertyParser> {
+ public:
+  CSSLazyPropertyParser() = default;
+  virtual ~CSSLazyPropertyParser() = default;
+  virtual CSSPropertyValueSet* ParseProperties() = 0;
+  virtual void Trace(blink::Visitor*) {}
+  DISALLOW_COPY_AND_ASSIGN(CSSLazyPropertyParser);
+};
+
+}  // namespace blink
+
+#endif  // CSSLazyPropertyParser_h
diff --git a/third_party/WebKit/Source/core/css/parser/CSSLazyPropertyParserImpl.h b/third_party/WebKit/Source/core/css/parser/CSSLazyPropertyParserImpl.h
index 27588ae..304e3a6a 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSLazyPropertyParserImpl.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSLazyPropertyParserImpl.h
@@ -5,7 +5,7 @@
 #ifndef CSSLazyPropertyParserImpl_h
 #define CSSLazyPropertyParserImpl_h
 
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/parser/CSSLazyPropertyParser.h"
 #include "core/css/parser/CSSParserTokenRange.h"
 #include "core/css/parser/CSSTokenizer.h"
 
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParser.h b/third_party/WebKit/Source/core/css/parser/CSSParser.h
index 4b9945a6..f60725f1 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParser.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSParser.h
@@ -8,7 +8,7 @@
 #include <memory>
 #include "core/CSSPropertyNames.h"
 #include "core/CoreExport.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/parser/CSSParserContext.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
index 7f8d059..29a92d57 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp
@@ -10,6 +10,8 @@
 #include "core/css/CSSCustomPropertyDeclaration.h"
 #include "core/css/CSSKeyframesRule.h"
 #include "core/css/CSSStyleSheet.h"
+#include "core/css/ImmutableCSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/PropertyRegistry.h"
 #include "core/css/StyleRuleImport.h"
 #include "core/css/StyleRuleKeyframe.h"
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h
index 2dea9c7..9a6e3cde 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.h
@@ -11,7 +11,7 @@
 #include "core/CSSPropertyNames.h"
 #include "core/css/CSSPropertySourceData.h"
 #include "core/css/CSSPropertyValue.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/parser/CSSParserTokenRange.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/css/resolver/MatchResultTest.cpp b/third_party/WebKit/Source/core/css/resolver/MatchResultTest.cpp
index b526f14..11f36f7 100644
--- a/third_party/WebKit/Source/core/css/resolver/MatchResultTest.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/MatchResultTest.cpp
@@ -4,7 +4,7 @@
 
 #include "core/css/resolver/MatchResult.h"
 
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
index 3554660..87498d4 100644
--- a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
@@ -32,11 +32,11 @@
 #include "core/CSSValueKeywords.h"
 #include "core/css/CSSDefaultStyleSheets.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
-#include "core/css/CSSPropertyValueSet.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/CSSToLengthConversionData.h"
 #include "core/css/DocumentStyleSheetCollection.h"
 #include "core/css/MediaValuesInitialViewport.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleRule.h"
 #include "core/css/StyleRuleImport.h"
 #include "core/css/StyleSheetContents.h"
diff --git a/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp b/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp
index 8f32b72..4021e5a 100644
--- a/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp
+++ b/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp
@@ -322,7 +322,7 @@
       // Call the streamer_done_ callback. Ensure that is_currently_streaming_
       // is reset only after the callback returns, to prevent accidentally
       // start streaming by work done within the callback. (crbug.com/754360)
-      WTF::Closure done = std::move(streamer_done_);
+      base::OnceClosure done = std::move(streamer_done_);
       if (done)
         std::move(done).Run();
       is_currently_streaming_ = false;
@@ -349,7 +349,7 @@
 
 bool ClassicPendingScript::StartStreamingIfPossible(
     ScriptStreamer::Type streamer_type,
-    WTF::Closure done) {
+    base::OnceClosure done) {
   if (IsCurrentlyStreaming())
     return false;
 
diff --git a/third_party/WebKit/Source/core/dom/ClassicPendingScript.h b/third_party/WebKit/Source/core/dom/ClassicPendingScript.h
index 93d8ebd..44953544 100644
--- a/third_party/WebKit/Source/core/dom/ClassicPendingScript.h
+++ b/third_party/WebKit/Source/core/dom/ClassicPendingScript.h
@@ -70,7 +70,8 @@
   bool IsExternal() const override { return is_external_; }
   bool ErrorOccurred() const override;
   bool WasCanceled() const override;
-  bool StartStreamingIfPossible(ScriptStreamer::Type, WTF::Closure) override;
+  bool StartStreamingIfPossible(ScriptStreamer::Type,
+                                base::OnceClosure) override;
   bool IsCurrentlyStreaming() const override;
   KURL UrlForTracing() const override;
   void DisposeInternal() override;
@@ -126,7 +127,7 @@
   bool intervened_ = false;
 
   Member<ScriptStreamer> streamer_;
-  WTF::Closure streamer_done_;
+  base::OnceClosure streamer_done_;
 
   // This flag tracks whether streamer_ is currently streaming. It is used
   // mainly to prevent re-streaming a script while it is being streamed.
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
index d9b6b07..92c599e 100644
--- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -954,7 +954,6 @@
 
 void ContainerNode::DetachLayoutTree(const AttachContext& context) {
   AttachContext children_context(context);
-  children_context.resolved_style = nullptr;
   children_context.clear_invalidation = true;
 
   for (Node* child = firstChild(); child; child = child->nextSibling())
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 3f0bd37..96618259 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -4803,7 +4803,7 @@
   return dom_window_->GetEventQueue();
 }
 
-void Document::EnqueueAnimationFrameTask(WTF::Closure task) {
+void Document::EnqueueAnimationFrameTask(base::OnceClosure task) {
   EnsureScriptedAnimationController().EnqueueTask(std::move(task));
 }
 
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 89c24a49..6db58933 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1135,7 +1135,7 @@
 
   void EnqueueResizeEvent();
   void EnqueueScrollEventForNode(Node*);
-  void EnqueueAnimationFrameTask(WTF::Closure);
+  void EnqueueAnimationFrameTask(base::OnceClosure);
   void EnqueueAnimationFrameEvent(Event*);
   // Only one event for a target/event type combination will be dispatched per
   // frame.
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index d5acd67..485e8f5 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -37,10 +37,10 @@
 #include "core/animation/css/CSSAnimations.h"
 #include "core/css/CSSIdentifierValue.h"
 #include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSPropertyValueSet.h"
 #include "core/css/CSSSelectorWatch.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/CSSValue.h"
+#include "core/css/ImmutableCSSPropertyValueSet.h"
 #include "core/css/PropertySetCSSStyleDeclaration.h"
 #include "core/css/SelectorQuery.h"
 #include "core/css/StyleChangeReason.h"
@@ -1835,8 +1835,7 @@
   }
 
   if (!IsActiveSlotOrActiveV0InsertionPoint()) {
-    context.resolved_style = GetNonAttachedStyle();
-    LayoutTreeBuilderForElement builder(*this, context.resolved_style);
+    LayoutTreeBuilderForElement builder(*this, GetNonAttachedStyle());
     builder.CreateLayoutObjectIfNeeded();
 
     if (ComputedStyle* style = builder.ResolvedStyle()) {
@@ -1857,7 +1856,6 @@
   SelectorFilterParentScope filter_scope(*this);
 
   AttachContext children_context(context);
-  children_context.resolved_style = nullptr;
 
   LayoutObject* layout_object = GetLayoutObject();
   if (layout_object)
@@ -2224,7 +2222,6 @@
 
   if (NeedsReattachLayoutTree()) {
     AttachContext reattach_context;
-    reattach_context.resolved_style = GetNonAttachedStyle();
     ReattachLayoutTree(reattach_context);
     whitespace_attacher.DidReattachElement(this,
                                            reattach_context.previous_in_flow);
diff --git a/third_party/WebKit/Source/core/dom/ElementData.cpp b/third_party/WebKit/Source/core/dom/ElementData.cpp
index 7e93da8d..ee5e5c6 100644
--- a/third_party/WebKit/Source/core/dom/ElementData.cpp
+++ b/third_party/WebKit/Source/core/dom/ElementData.cpp
@@ -31,6 +31,8 @@
 #include "core/dom/ElementData.h"
 
 #include "core/css/CSSPropertyValueSet.h"
+#include "core/css/ImmutableCSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/QualifiedName.h"
 #include "platform/wtf/Vector.h"
 
diff --git a/third_party/WebKit/Source/core/dom/ElementShadow.cpp b/third_party/WebKit/Source/core/dom/ElementShadow.cpp
index 81fdccba..9c6975f 100644
--- a/third_party/WebKit/Source/core/dom/ElementShadow.cpp
+++ b/third_party/WebKit/Source/core/dom/ElementShadow.cpp
@@ -107,7 +107,6 @@
 
 void ElementShadow::Attach(const Node::AttachContext& context) {
   Node::AttachContext children_context(context);
-  children_context.resolved_style = nullptr;
 
   for (ShadowRoot* root = &YoungestShadowRoot(); root;
        root = root->OlderShadowRoot()) {
@@ -118,7 +117,6 @@
 
 void ElementShadow::Detach(const Node::AttachContext& context) {
   Node::AttachContext children_context(context);
-  children_context.resolved_style = nullptr;
 
   for (ShadowRoot* root = &YoungestShadowRoot(); root;
        root = root->OlderShadowRoot())
diff --git a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h
index 077805eb..4e2958d 100644
--- a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h
+++ b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h
@@ -7,6 +7,7 @@
 
 #include <limits>
 
+#include "base/callback.h"
 #include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/intersection_observer/IntersectionObserver.h"
@@ -29,7 +30,7 @@
 class CORE_EXPORT ElementVisibilityObserver final
     : public GarbageCollectedFinalized<ElementVisibilityObserver> {
  public:
-  using VisibilityCallback = WTF::RepeatingFunction<void(bool)>;
+  using VisibilityCallback = base::RepeatingCallback<void(bool)>;
 
   ElementVisibilityObserver(Element*, VisibilityCallback);
   virtual ~ElementVisibilityObserver();
diff --git a/third_party/WebKit/Source/core/dom/IdleDeadlineTest.cpp b/third_party/WebKit/Source/core/dom/IdleDeadlineTest.cpp
index 2d77ffd..77818c19 100644
--- a/third_party/WebKit/Source/core/dom/IdleDeadlineTest.cpp
+++ b/third_party/WebKit/Source/core/dom/IdleDeadlineTest.cpp
@@ -25,9 +25,9 @@
   void Shutdown() override {}
   bool ShouldYieldForHighPriorityWork() override { return true; }
   bool CanExceedIdleDeadlineIfRequired() override { return false; }
-  void PostIdleTask(const WebTraceLocation&, WebThread::IdleTask*) override {}
+  void PostIdleTask(const WebTraceLocation&, WebThread::IdleTask) override {}
   void PostNonNestableIdleTask(const WebTraceLocation&,
-                               WebThread::IdleTask*) override {}
+                               WebThread::IdleTask) override {}
   std::unique_ptr<WebViewScheduler> CreateWebViewScheduler(
       InterventionReporter*,
       WebViewScheduler::WebViewSchedulerDelegate*) override {
diff --git a/third_party/WebKit/Source/core/dom/ModulePendingScript.h b/third_party/WebKit/Source/core/dom/ModulePendingScript.h
index d11c39e..ed5870d 100644
--- a/third_party/WebKit/Source/core/dom/ModulePendingScript.h
+++ b/third_party/WebKit/Source/core/dom/ModulePendingScript.h
@@ -82,7 +82,8 @@
   bool ErrorOccurred() const override;
   bool WasCanceled() const override { return false; }
 
-  bool StartStreamingIfPossible(ScriptStreamer::Type, WTF::Closure) override {
+  bool StartStreamingIfPossible(ScriptStreamer::Type,
+                                base::OnceClosure) override {
     return false;
   }
   bool IsCurrentlyStreaming() const override { return false; }
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 5ea9e04..8c98836b 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -82,6 +82,7 @@
 #include "core/frame/LocalFrameClient.h"
 #include "core/frame/LocalFrameView.h"
 #include "core/frame/UseCounter.h"
+#include "core/fullscreen/Fullscreen.h"
 #include "core/html/HTMLDialogElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLSlotElement.h"
@@ -914,10 +915,19 @@
 
   DCHECK(!ChildNeedsDistributionRecalc());
 
-  const HTMLDialogElement* dialog = GetDocument().ActiveModalDialog();
-  if (dialog && this != GetDocument() &&
-      !FlatTreeTraversal::ContainsIncludingPseudoElement(*dialog, *this)) {
-    return true;
+  if (this != GetDocument()) {
+    // TODO(foolip): When fullscreen uses top layer, this can be simplified to
+    // just look at the topmost element in top layer. https://crbug.com/240576.
+    // Note: It's currently appropriate that a modal dialog element takes
+    // precedence over a fullscreen element, because it will be rendered on top,
+    // but with fullscreen merged into top layer that will no longer be true.
+    const Element* modal_element = GetDocument().ActiveModalDialog();
+    if (!modal_element)
+      modal_element = Fullscreen::FullscreenElementFrom(GetDocument());
+    if (modal_element && !FlatTreeTraversal::ContainsIncludingPseudoElement(
+                             *modal_element, *this)) {
+      return true;
+    }
   }
 
   if (RuntimeEnabledFeatures::InertAttributeEnabled()) {
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h
index b8ff789..5a4aec61 100644
--- a/third_party/WebKit/Source/core/dom/Node.h
+++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -626,7 +626,6 @@
 
   struct AttachContext {
     STACK_ALLOCATED();
-    ComputedStyle* resolved_style = nullptr;
     // Keep track of previously attached in-flow box during attachment so that
     // we don't need to backtrack past display:none/contents and out of flow
     // objects when we need to do whitespace re-attachment.
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.h b/third_party/WebKit/Source/core/dom/PendingScript.h
index 123e85e..c49cc21 100644
--- a/third_party/WebKit/Source/core/dom/PendingScript.h
+++ b/third_party/WebKit/Source/core/dom/PendingScript.h
@@ -97,7 +97,8 @@
   virtual bool WasCanceled() const = 0;
 
   // Support for script streaming.
-  virtual bool StartStreamingIfPossible(ScriptStreamer::Type, WTF::Closure) = 0;
+  virtual bool StartStreamingIfPossible(ScriptStreamer::Type,
+                                        base::OnceClosure) = 0;
   virtual bool IsCurrentlyStreaming() const = 0;
 
   // Used only for tracing, and can return a null URL.
diff --git a/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp b/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
index 612c96b..690571b 100644
--- a/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
+++ b/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
@@ -33,7 +33,7 @@
 #include <algorithm>
 
 #include "base/macros.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/Element.h"
 #include "core/html/forms/HTMLInputElement.h"
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index 693fe320..52df9b84 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -727,88 +727,6 @@
   return pending_script;
 }
 
-// Steps 3--7 of https://html.spec.whatwg.org/#execute-the-script-block
-// with additional support for HTML imports.
-// Steps 2 and 8 are handled in ExecuteScriptBlock().
-ScriptLoader::ExecuteScriptResult ScriptLoader::DoExecuteScript(
-    const Script* script) {
-  DCHECK(already_started_);
-  CHECK_EQ(script->GetScriptType(), GetScriptType());
-
-  if (element_->ElementHasDuplicateAttributes()) {
-    UseCounter::Count(element_->GetDocument(),
-                      WebFeature::kDuplicatedAttributeForExecutedScript);
-  }
-
-  Document* element_document = &(element_->GetDocument());
-  Document* context_document = element_document->ContextDocument();
-  DCHECK(context_document);
-
-  LocalFrame* frame = context_document->GetFrame();
-  DCHECK(frame);
-
-  if (!is_external_script_) {
-    bool should_bypass_main_world_csp =
-        (frame->GetScriptController().ShouldBypassMainWorldCSP());
-
-    AtomicString nonce = element_->GetNonceForElement();
-    if (!should_bypass_main_world_csp &&
-        !element_->AllowInlineScriptForCSP(
-            nonce, start_line_number_, script->InlineSourceTextForCSP(),
-            ContentSecurityPolicy::InlineType::kBlock)) {
-      return ExecuteScriptResult::kShouldFireErrorEvent;
-    }
-  }
-
-  const bool is_imported_script = context_document != element_document;
-
-  // 3. "If the script is from an external file,
-  //     or the script's type is module",
-  //     then increment the ignore-destructive-writes counter of the
-  //     script element's node document. Let neutralized doc be that Document."
-  IgnoreDestructiveWriteCountIncrementer
-      ignore_destructive_write_count_incrementer(
-          is_external_script_ ||
-                  script->GetScriptType() == ScriptType::kModule ||
-                  is_imported_script
-              ? context_document
-              : nullptr);
-
-  // 4. "Let old script element be the value to which the script element's
-  //     node document's currentScript object was most recently set."
-  // This is implemented as push/popCurrentScript().
-
-  // 5. "Switch on the script's type:"
-  //    - "classic":
-  //    1. "If the script element's root is not a shadow root,
-  //        then set the script element's node document's currentScript
-  //        attribute to the script element. Otherwise, set it to null."
-  //    - "module":
-  //    1. "Set the script element's node document's currentScript attribute
-  //        to null."
-  ScriptElementBase* current_script = nullptr;
-  if (script->GetScriptType() == ScriptType::kClassic)
-    current_script = element_;
-  context_document->PushCurrentScript(current_script);
-
-  //    - "classic":
-  //    2. "Run the classic script given by the script's script."
-  // Note: This is where the script is compiled and actually executed.
-  //    - "module":
-  //    2. "Run the module script given by the script's script."
-  script->RunScript(frame, element_->GetDocument().GetSecurityOrigin());
-
-  // 6. "Set the script element's node document's currentScript attribute
-  //     to old script element."
-  context_document->PopCurrentScript(current_script);
-
-  return ExecuteScriptResult::kShouldFireLoadEvent;
-
-  // 7. "Decrement the ignore-destructive-writes counter of neutralized doc,
-  //     if it was incremented in the earlier step."
-  // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer.
-}
-
 void ScriptLoader::Execute() {
   DCHECK(!will_be_parser_executed_);
   DCHECK(async_exec_type_ != ScriptRunner::kNone);
@@ -824,6 +742,7 @@
                                       const KURL& document_url) {
   DCHECK(pending_script);
   DCHECK_EQ(pending_script->IsExternal(), is_external_script_);
+  DCHECK(already_started_);
 
   Document* element_document = &(element_->GetDocument());
   Document* context_document = element_document->ContextDocument();
@@ -854,6 +773,21 @@
   if (!pending_script->CheckMIMETypeBeforeRunScript(context_document))
     error_occurred = true;
 
+  if (!error_occurred && !is_external_script_) {
+    bool should_bypass_main_world_csp =
+        frame->GetScriptController().ShouldBypassMainWorldCSP();
+
+    AtomicString nonce = element_->GetNonceForElement();
+    if (!should_bypass_main_world_csp &&
+        !element_->AllowInlineScriptForCSP(
+            nonce, start_line_number_, script->InlineSourceTextForCSP(),
+            ContentSecurityPolicy::InlineType::kBlock)) {
+      // Consider as if "the script's script is null" retrospectively,
+      // if the CSP check fails, which is considered as load failure.
+      error_occurred = true;
+    }
+  }
+
   const bool was_canceled = pending_script->WasCanceled();
   const bool is_external = pending_script->IsExternal();
   const double parser_blocking_load_start_time =
@@ -879,8 +813,59 @@
 
   double script_exec_start_time = MonotonicallyIncreasingTime();
 
-  // Steps 3--7 are in DoExecuteScript().
-  ExecuteScriptResult result = DoExecuteScript(script);
+  {
+    CHECK_EQ(script->GetScriptType(), GetScriptType());
+
+    if (element_->ElementHasDuplicateAttributes()) {
+      UseCounter::Count(element_->GetDocument(),
+                        WebFeature::kDuplicatedAttributeForExecutedScript);
+    }
+
+    const bool is_imported_script = context_document != element_document;
+
+    // 3. "If the script is from an external file,
+    //     or the script's type is module",
+    const bool needs_increment =
+        is_external_script_ || script->GetScriptType() == ScriptType::kModule ||
+        is_imported_script;
+    //     then increment the ignore-destructive-writes counter of the
+    //     script element's node document. Let neutralized doc be that
+    //     Document."
+    IgnoreDestructiveWriteCountIncrementer incrementer(
+        needs_increment ? context_document : nullptr);
+
+    // 4. "Let old script element be the value to which the script element's
+    //     node document's currentScript object was most recently set."
+    // This is implemented as push/popCurrentScript().
+
+    // 5. "Switch on the script's type:"
+    //    - "classic":
+    //    1. "If the script element's root is not a shadow root,
+    //        then set the script element's node document's currentScript
+    //        attribute to the script element. Otherwise, set it to null."
+    //    - "module":
+    //    1. "Set the script element's node document's currentScript attribute
+    //        to null."
+    ScriptElementBase* current_script = nullptr;
+    if (script->GetScriptType() == ScriptType::kClassic)
+      current_script = element_;
+    context_document->PushCurrentScript(current_script);
+
+    //    - "classic":
+    //    2. "Run the classic script given by the script's script."
+    // Note: This is where the script is compiled and actually executed.
+    //    - "module":
+    //    2. "Run the module script given by the script's script."
+    script->RunScript(frame, element_->GetDocument().GetSecurityOrigin());
+
+    // 6. "Set the script element's node document's currentScript attribute
+    //     to old script element."
+    context_document->PopCurrentScript(current_script);
+
+    // 7. "Decrement the ignore-destructive-writes counter of neutralized doc,
+    //     if it was incremented in the earlier step."
+    // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer.
+  }
 
   // NOTE: we do not check m_willBeParserExecuted here, since
   // m_willBeParserExecuted is false for inline scripts, and we want to
@@ -893,23 +878,10 @@
             WasCreatedDuringDocumentWrite());
   }
 
-  switch (result) {
-    case ExecuteScriptResult::kShouldFireLoadEvent:
-      // 8. "If the script is from an external file, then fire an event named
-      //     load at the script element."
-      if (is_external)
-        DispatchLoadEvent();
-      break;
-
-    case ExecuteScriptResult::kShouldFireErrorEvent:
-      // Consider as if "the script's script is null" retrospectively,
-      // due to CSP check failures etc., which are considered as load failure.
-      DispatchErrorEvent();
-      break;
-
-    case ExecuteScriptResult::kShouldFireNone:
-      break;
-  }
+  // 8. "If the script is from an external file, then fire an event named
+  //     load at the script element."
+  if (is_external)
+    DispatchLoadEvent();
 }
 
 void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) {
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.h b/third_party/WebKit/Source/core/dom/ScriptLoader.h
index 664edcb..364c83b 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.h
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.h
@@ -155,12 +155,6 @@
                              Modulator*,
                              const ScriptFetchOptions&);
 
-  enum class ExecuteScriptResult {
-    kShouldFireErrorEvent,
-    kShouldFireLoadEvent,
-    kShouldFireNone
-  };
-  ExecuteScriptResult DoExecuteScript(const Script*);
   void DispatchLoadEvent();
   void DispatchErrorEvent();
 
diff --git a/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp b/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp
index d8e5cdcb..e2fff36 100644
--- a/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp
@@ -44,11 +44,11 @@
   // future release of googletest, but for now we use the recommended
   // workaround of 'bumping' the method-to-be-mocked to another method.
   bool StartStreamingIfPossible(ScriptStreamer::Type type,
-                                WTF::Closure closure) override {
+                                base::OnceClosure closure) override {
     return DoStartStreamingIfPossible(type, &closure);
   }
   MOCK_METHOD2(DoStartStreamingIfPossible,
-               bool(ScriptStreamer::Type, WTF::Closure*));
+               bool(ScriptStreamer::Type, base::OnceClosure*));
 
  protected:
   MOCK_METHOD0(DisposeInternal, void());
@@ -72,7 +72,7 @@
   // Set up the mock for streaming. The closure passed in will receive the
   // 'finish streaming' callback, so that the test case can control when
   // the mock streaming has mock finished.
-  MockScriptLoader* SetupForStreaming(WTF::Closure& finished_callback);
+  MockScriptLoader* SetupForStreaming(base::OnceClosure& finished_callback);
   MockScriptLoader* SetupForNonStreaming();
 
   virtual void Trace(blink::Visitor*);
@@ -89,7 +89,7 @@
 }
 
 MockScriptLoader* MockScriptLoader::SetupForStreaming(
-    WTF::Closure& finished_callback) {
+    base::OnceClosure& finished_callback) {
   mock_pending_script_ = MockPendingScript::Create();
   SetupForNonStreaming();
 
@@ -98,11 +98,12 @@
   // streamig is done.
   EXPECT_CALL(*mock_pending_script_, DoStartStreamingIfPossible(_, _))
       .WillOnce(Return(false))
-      .WillOnce(Invoke([&finished_callback](ScriptStreamer::Type,
-                                            WTF::Closure* callback) -> bool {
-        finished_callback = std::move(*callback);
-        return true;
-      }))
+      .WillOnce(
+          Invoke([&finished_callback](ScriptStreamer::Type,
+                                      base::OnceClosure* callback) -> bool {
+            finished_callback = std::move(*callback);
+            return true;
+          }))
       .WillRepeatedly(Return(false));
   EXPECT_CALL(*mock_pending_script_, IsCurrentlyStreaming())
       .WillRepeatedly(
@@ -523,7 +524,7 @@
 }
 
 TEST_F(ScriptRunnerTest, DontExecuteWhileStreaming) {
-  WTF::Closure callback;
+  base::OnceClosure callback;
   Persistent<MockScriptLoader> script_loader1 =
       MockScriptLoader::Create()->SetupForStreaming(callback);
   EXPECT_CALL(*script_loader1, IsReady()).WillRepeatedly(Return(true));
diff --git a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
index eeda533b..d74b378 100644
--- a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
@@ -87,7 +87,7 @@
 }
 
 void ScriptedAnimationController::RunTasks() {
-  Vector<WTF::Closure> tasks;
+  Vector<base::OnceClosure> tasks;
   tasks.swap(task_queue_);
   for (auto& task : tasks)
     std::move(task).Run();
@@ -172,7 +172,7 @@
   ScheduleAnimationIfNeeded();
 }
 
-void ScriptedAnimationController::EnqueueTask(WTF::Closure task) {
+void ScriptedAnimationController::EnqueueTask(base::OnceClosure task) {
   task_queue_.push_back(std::move(task));
   ScheduleAnimationIfNeeded();
 }
diff --git a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
index 460e1df..bea49754 100644
--- a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
+++ b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
@@ -65,7 +65,7 @@
   void EnqueuePerFrameEvent(Event*);
 
   // Animation frame tasks are used for Fullscreen.
-  void EnqueueTask(WTF::Closure);
+  void EnqueueTask(base::OnceClosure);
 
   // Used for the MediaQueryList change event.
   void EnqueueMediaQueryChangeListeners(
@@ -96,7 +96,7 @@
   Member<Document> document_;
   FrameRequestCallbackCollection callback_collection_;
   int suspend_count_;
-  Vector<WTF::Closure> task_queue_;
+  Vector<base::OnceClosure> task_queue_;
   HeapVector<Member<Event>> event_queue_;
   HeapListHashSet<std::pair<Member<const EventTarget>, const StringImpl*>>
       per_frame_events_;
diff --git a/third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp b/third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp
index 387c6d2..97dad8d 100644
--- a/third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp
@@ -44,7 +44,7 @@
 
 class TaskOrderObserver {
  public:
-  WTF::RepeatingClosure CreateTask(int id) {
+  base::RepeatingClosure CreateTask(int id) {
     return WTF::BindRepeating(&TaskOrderObserver::RunTask,
                               WTF::Unretained(this), id);
   }
@@ -119,7 +119,7 @@
 
 class RunTaskEventListener final : public EventListener {
  public:
-  RunTaskEventListener(WTF::RepeatingClosure task)
+  RunTaskEventListener(base::RepeatingClosure task)
       : EventListener(kCPPEventListenerType), task_(std::move(task)) {}
   void handleEvent(ExecutionContext*, Event*) override { task_.Run(); }
   bool operator==(const EventListener& other) const override {
@@ -127,7 +127,7 @@
   }
 
  private:
-  WTF::RepeatingClosure task_;
+  base::RepeatingClosure task_;
 };
 
 }  // anonymous namespace
@@ -156,11 +156,11 @@
 class RunTaskCallback final
     : public FrameRequestCallbackCollection::FrameCallback {
  public:
-  RunTaskCallback(WTF::RepeatingClosure task) : task_(std::move(task)) {}
+  RunTaskCallback(base::RepeatingClosure task) : task_(std::move(task)) {}
   void Invoke(double) override { task_.Run(); }
 
  private:
-  WTF::RepeatingClosure task_;
+  base::RepeatingClosure task_;
 };
 
 }  // anonymous namespace
diff --git a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp
index e61e8964..c8e521c4 100644
--- a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp
@@ -231,14 +231,6 @@
           GetExecutionContext(), id, allotted_time_millis,
           callback_type == IdleDeadline::CallbackType::kCalledByTimeout));
   idle_task->invoke(IdleDeadline::Create(deadline_seconds, callback_type));
-
-  double overrun_millis =
-      std::max((MonotonicallyIncreasingTime() - deadline_seconds) * 1000, 0.0);
-
-  DEFINE_STATIC_LOCAL(
-      CustomCountHistogram, idle_callback_overrun_histogram,
-      ("WebCore.ScriptedIdleTaskController.IdleCallbackOverrun", 0, 10000, 50));
-  idle_callback_overrun_histogram.Count(overrun_millis);
 }
 
 void ScriptedIdleTaskController::ContextDestroyed(ExecutionContext*) {
diff --git a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskControllerTest.cpp b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskControllerTest.cpp
index 055f80b..ff331074 100644
--- a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskControllerTest.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskControllerTest.cpp
@@ -32,11 +32,11 @@
   bool ShouldYieldForHighPriorityWork() override { return should_yield_; }
   bool CanExceedIdleDeadlineIfRequired() override { return false; }
   void PostIdleTask(const WebTraceLocation&,
-                    WebThread::IdleTask* idle_task) override {
-    idle_task_.reset(idle_task);
+                    WebThread::IdleTask idle_task) override {
+    idle_task_ = std::move(idle_task);
   }
   void PostNonNestableIdleTask(const WebTraceLocation&,
-                               WebThread::IdleTask*) override {}
+                               WebThread::IdleTask) override {}
   std::unique_ptr<WebViewScheduler> CreateWebViewScheduler(
       InterventionReporter*,
       WebViewScheduler::WebViewSchedulerDelegate*) override {
@@ -50,15 +50,12 @@
   void RemovePendingNavigation(
       scheduler::RendererScheduler::NavigatingFrameType) override {}
 
-  void RunIdleTask() {
-    auto idle_task = std::move(idle_task_);
-    idle_task->Run(0);
-  }
-  bool HasIdleTask() const { return idle_task_.get(); }
+  void RunIdleTask() { std::move(idle_task_).Run(0); }
+  bool HasIdleTask() const { return !!idle_task_; }
 
  private:
   bool should_yield_;
-  std::unique_ptr<WebThread::IdleTask> idle_task_;
+  WebThread::IdleTask idle_task_;
 
   DISALLOW_COPY_AND_ASSIGN(MockScriptedIdleTaskControllerScheduler);
 };
diff --git a/third_party/WebKit/Source/core/dom/ShadowRoot.cpp b/third_party/WebKit/Source/core/dom/ShadowRoot.cpp
index 52fe48d1..5dd96be 100644
--- a/third_party/WebKit/Source/core/dom/ShadowRoot.cpp
+++ b/third_party/WebKit/Source/core/dom/ShadowRoot.cpp
@@ -61,10 +61,11 @@
       TreeScope(*this, document),
       style_sheet_list_(nullptr),
       child_shadow_root_count_(0),
-      type_(static_cast<unsigned>(type)),
+      type_(static_cast<unsigned short>(type)),
       registered_with_parent_shadow_root_(false),
       descendant_insertion_points_is_valid_(false),
-      delegates_focus_(false) {}
+      delegates_focus_(false),
+      unused_(0) {}
 
 ShadowRoot::~ShadowRoot() {}
 
diff --git a/third_party/WebKit/Source/core/dom/ShadowRoot.h b/third_party/WebKit/Source/core/dom/ShadowRoot.h
index a74c9da..03c62f3 100644
--- a/third_party/WebKit/Source/core/dom/ShadowRoot.h
+++ b/third_party/WebKit/Source/core/dom/ShadowRoot.h
@@ -190,11 +190,12 @@
   Member<ShadowRootRareDataV0> shadow_root_rare_data_v0_;
   TraceWrapperMember<StyleSheetList> style_sheet_list_;
   Member<SlotAssignment> slot_assignment_;
-  unsigned child_shadow_root_count_ : 13;
-  unsigned type_ : 2;
-  unsigned registered_with_parent_shadow_root_ : 1;
-  unsigned descendant_insertion_points_is_valid_ : 1;
-  unsigned delegates_focus_ : 1;
+  unsigned short child_shadow_root_count_;
+  unsigned short type_ : 2;
+  unsigned short registered_with_parent_shadow_root_ : 1;
+  unsigned short descendant_insertion_points_is_valid_ : 1;
+  unsigned short delegates_focus_ : 1;
+  unsigned short unused_ : 11;
 };
 
 inline Element* ShadowRoot::ActiveElement() const {
diff --git a/third_party/WebKit/Source/core/dom/V0InsertionPoint.cpp b/third_party/WebKit/Source/core/dom/V0InsertionPoint.cpp
index b196cb8..24f23ff 100644
--- a/third_party/WebKit/Source/core/dom/V0InsertionPoint.cpp
+++ b/third_party/WebKit/Source/core/dom/V0InsertionPoint.cpp
@@ -109,7 +109,6 @@
   // cause them to be inserted in the wrong place later. This also lets
   // distributed nodes benefit from the n^2 protection.
   AttachContext children_context(context);
-  children_context.resolved_style = nullptr;
 
   for (size_t i = 0; i < distributed_nodes_.size(); ++i) {
     Node* child = distributed_nodes_.at(i);
diff --git a/third_party/WebKit/Source/core/editing/EditingStyleTest.cpp b/third_party/WebKit/Source/core/editing/EditingStyleTest.cpp
index cfded12..da71294 100644
--- a/third_party/WebKit/Source/core/editing/EditingStyleTest.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingStyleTest.cpp
@@ -4,7 +4,7 @@
 
 #include "core/editing/EditingStyle.h"
 
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Document.h"
 #include "core/editing/testing/EditingTestBase.h"
 #include "core/html/HTMLBodyElement.h"
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp
index 402938a..8ba3e47 100644
--- a/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -32,7 +32,7 @@
 #include "core/clipboard/DataTransfer.h"
 #include "core/clipboard/Pasteboard.h"
 #include "core/css/CSSComputedStyleDeclaration.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/AXObjectCache.h"
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/ElementTraversal.h"
diff --git a/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp b/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp
index aad1288..a7a714e 100644
--- a/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp
+++ b/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp
@@ -12,6 +12,7 @@
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutText.h"
 #include "platform/wtf/Assertions.h"
+#include "platform/wtf/Functional.h"
 
 namespace blink {
 
@@ -63,7 +64,7 @@
 }
 
 using IsTypeOf =
-    WTF::RepeatingFunction<bool(const LayoutObject& layout_object)>;
+    base::RepeatingCallback<bool(const LayoutObject& layout_object)>;
 using IsTypeOfSimple = bool(const LayoutObject& layout_object);
 #define USING_LAYOUTOBJECT_FUNC(member_func)                   \
   static bool member_func(const LayoutObject& layout_object) { \
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index 0524aa19..32a8e69 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -695,14 +695,31 @@
   if (!layout_object)
     return LocalCaretRect();
 
-  const InlineBoxPosition& box_position = ComputeInlineBoxPosition(position);
+  const PositionWithAffinityTemplate<Strategy>& adjusted =
+      ComputeInlineAdjustedPosition(position);
 
-  if (box_position.inline_box) {
-    return ComputeLocalCaretRect(
-        LineLayoutAPIShim::LayoutObjectFrom(
-            box_position.inline_box->GetLineLayoutItem()),
-        box_position);
+  if (adjusted.IsNotNull()) {
+    // TODO(xiaochengh): Plug in NG implementation here.
+
+    // TODO(editing-dev): This DCHECK is for ensuring the correctness of
+    // breaking |ComputeInlineBoxPosition| into |ComputeInlineAdjustedPosition|
+    // and |ComputeInlineBoxPositionForInlineAdjustedPosition|. If there is any
+    // DCHECK hit, we should pass primary direction to the latter function.
+    // TODO(crbug.com/793098): Fix it so that we don't need to bother about
+    // primary direction.
+    DCHECK_EQ(PrimaryDirectionOf(*position.AnchorNode()),
+              PrimaryDirectionOf(*adjusted.AnchorNode()));
+    const InlineBoxPosition& box_position =
+        ComputeInlineBoxPositionForInlineAdjustedPosition(adjusted);
+
+    if (box_position.inline_box) {
+      return ComputeLocalCaretRect(
+          LineLayoutAPIShim::LayoutObjectFrom(
+              box_position.inline_box->GetLineLayoutItem()),
+          box_position);
+    }
   }
+
   // DeleteSelectionCommandTest.deleteListFromTable goes here.
   return LocalCaretRect(
       layout_object,
@@ -721,7 +738,23 @@
   if (!node->GetLayoutObject())
     return LocalCaretRect();
 
-  const InlineBoxPosition& box_position = ComputeInlineBoxPosition(position);
+  const PositionWithAffinityTemplate<Strategy>& adjusted =
+      ComputeInlineAdjustedPosition(position);
+  if (adjusted.IsNull())
+    return LocalCaretRect();
+
+  // TODO(xiaochengh): Plug in NG implementation here.
+
+  // TODO(editing-dev): This DCHECK is for ensuring the correctness of
+  // breaking |ComputeInlineBoxPosition| into |ComputeInlineAdjustedPosition|
+  // and |ComputeInlineBoxPositionForInlineAdjustedPosition|. If there is any
+  // DCHECK hit, we should pass primary direction to the latter function.
+  // TODO(crbug.com/793098): Fix it so that we don't need to bother about
+  // primary direction.
+  DCHECK_EQ(PrimaryDirectionOf(*position.AnchorNode()),
+            PrimaryDirectionOf(*adjusted.AnchorNode()));
+  const InlineBoxPosition& box_position =
+      ComputeInlineBoxPositionForInlineAdjustedPosition(adjusted);
 
   if (!box_position.inline_box)
     return LocalCaretRect();
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
index ddfb1c9..618cc9e 100644
--- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -30,6 +30,7 @@
 #include "core/css/CSSComputedStyleDeclaration.h"
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Document.h"
 #include "core/dom/NodeList.h"
 #include "core/dom/NodeTraversal.h"
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommandTest.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommandTest.cpp
index 8b02f30..aed45d26 100644
--- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommandTest.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommandTest.cpp
@@ -4,7 +4,7 @@
 
 #include "core/editing/commands/ApplyStyleCommand.h"
 
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Document.h"
 #include "core/editing/EditingStyle.h"
 #include "core/editing/FrameSelection.h"
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
index 8292ea8..a8d92be0 100644
--- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -33,8 +33,8 @@
 #include "core/clipboard/Pasteboard.h"
 #include "core/css/CSSComputedStyleDeclaration.h"
 #include "core/css/CSSIdentifierValue.h"
-#include "core/css/CSSPropertyValueSet.h"
 #include "core/css/CSSValueList.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/TagCollection.h"
 #include "core/dom/events/Event.h"
diff --git a/third_party/WebKit/Source/core/editing/commands/RemoveFormatCommand.cpp b/third_party/WebKit/Source/core/editing/commands/RemoveFormatCommand.cpp
index 62e7182..c2c8ccc 100644
--- a/third_party/WebKit/Source/core/editing/commands/RemoveFormatCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/RemoveFormatCommand.cpp
@@ -27,7 +27,7 @@
 #include "core/editing/commands/RemoveFormatCommand.h"
 
 #include "core/CSSValueKeywords.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/editing/EditingStyle.h"
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
index 4c246ce..7ce1be0 100644
--- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -29,8 +29,8 @@
 #include "base/macros.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/CSSPropertyNames.h"
-#include "core/css/CSSPropertyValueSet.h"
 #include "core/css/CSSStyleDeclaration.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Document.h"
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/Element.h"
diff --git a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp
index 71b5f95..b3f9e0f 100644
--- a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp
+++ b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp
@@ -29,7 +29,7 @@
 
 #include "core/editing/serializers/StyledMarkupAccumulator.h"
 
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Text.h"
 #include "core/editing/EditingUtilities.h"
 #include "core/editing/EphemeralRange.h"
diff --git a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp
index bf9ef57..b698f53 100644
--- a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp
+++ b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp
@@ -30,7 +30,7 @@
 #include "core/editing/serializers/StyledMarkupSerializer.h"
 
 #include "base/macros.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/ElementShadow.h"
diff --git a/third_party/WebKit/Source/core/exported/PrerenderingTest.cpp b/third_party/WebKit/Source/core/exported/PrerenderingTest.cpp
index 2973402..dc8f71c 100644
--- a/third_party/WebKit/Source/core/exported/PrerenderingTest.cpp
+++ b/third_party/WebKit/Source/core/exported/PrerenderingTest.cpp
@@ -237,7 +237,8 @@
   WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
   EXPECT_FALSE(web_prerender.IsNull());
   EXPECT_EQ(ToWebURL("http://prerender.com/"), web_prerender.Url());
-  EXPECT_EQ(kPrerenderRelTypePrerender, web_prerender.RelTypes());
+  EXPECT_EQ(static_cast<unsigned>(kPrerenderRelTypePrerender),
+            web_prerender.RelTypes());
 
   EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
   EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
diff --git a/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp b/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp
index 56561ad4..6457b13 100644
--- a/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp
+++ b/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp
@@ -26,6 +26,8 @@
 
 namespace {
 
+const int text_dumper_max_depth = 512;
+
 bool IsRenderedAndVisible(const Node& node) {
   if (node.GetLayoutObject() &&
       node.GetLayoutObject()->Style()->Visibility() == EVisibility::kVisible)
@@ -67,18 +69,20 @@
   void DumpTextFrom(const Node& node) {
     DCHECK(!has_emitted_);
     DCHECK(!required_line_breaks_);
-    HandleNode(node);
+    HandleNode(node, 0);
   }
 
  private:
-  void HandleNode(const Node& node) {
+  void HandleNode(const Node& node, int depth) {
     const size_t required_line_breaks_around = RequiredLineBreaksAround(node);
     AddRequiredLineBreaks(required_line_breaks_around);
 
-    for (const Node& child : NodeTraversal::ChildrenOf(node)) {
-      HandleNode(child);
-      if (builder_.length() >= max_length_)
-        return;
+    if (depth < text_dumper_max_depth) {
+      for (const Node& child : NodeTraversal::ChildrenOf(node)) {
+        HandleNode(child, depth + 1);
+        if (builder_.length() >= max_length_)
+          return;
+      }
     }
 
     if (!IsRenderedAndVisible(node))
diff --git a/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.cpp b/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.cpp
index 9da4e2b..9b94417 100644
--- a/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebSharedWorkerImpl.cpp
@@ -319,14 +319,14 @@
       shadow_page_->GetDocument()->GetFrame()->GetSettings());
   auto global_scope_creation_params =
       std::make_unique<GlobalScopeCreationParams>(
-          url_, document->UserAgent(), main_script_loader_->SourceText(),
-          nullptr /* cached_meta_data */,
+          url_, document->UserAgent(),
           content_security_policy ? content_security_policy->Headers().get()
                                   : nullptr,
           referrer_policy, starter_origin, worker_clients,
           main_script_loader_->ResponseAddressSpace(),
           main_script_loader_->OriginTrialTokens(), std::move(worker_settings),
           kV8CacheOptionsDefault, std::move(pending_interface_provider_));
+  String source_code = main_script_loader_->SourceText();
 
   // SharedWorker can sometimes run tasks that are initiated by/associated with
   // a document's frame but these documents can be from a different process. So
@@ -351,7 +351,7 @@
       std::move(global_scope_creation_params), thread_startup_data,
       std::make_unique<GlobalScopeInspectorCreationParams>(
           worker_inspector_proxy_->ShouldPauseOnWorkerStart(document)),
-      task_runners);
+      task_runners, source_code);
   worker_inspector_proxy_->WorkerThreadCreated(document, GetWorkerThread(),
                                                url_);
   client_->WorkerScriptLoaded();
diff --git a/third_party/WebKit/Source/core/exported/WebViewImpl.cpp b/third_party/WebKit/Source/core/exported/WebViewImpl.cpp
index f48894b1..aa82171 100644
--- a/third_party/WebKit/Source/core/exported/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebViewImpl.cpp
@@ -3258,9 +3258,8 @@
 }
 
 void WebViewImpl::RequestDecode(const PaintImage& image,
-                                WTF::Function<void(bool)> callback) {
-  layer_tree_view_->RequestDecode(image,
-                                  ConvertToBaseCallback(std::move(callback)));
+                                base::OnceCallback<void(bool)> callback) {
+  layer_tree_view_->RequestDecode(image, std::move(callback));
 }
 
 Color WebViewImpl::BaseBackgroundColor() const {
diff --git a/third_party/WebKit/Source/core/exported/WebViewImpl.h b/third_party/WebKit/Source/core/exported/WebViewImpl.h
index 188561f..338135e 100644
--- a/third_party/WebKit/Source/core/exported/WebViewImpl.h
+++ b/third_party/WebKit/Source/core/exported/WebViewImpl.h
@@ -472,7 +472,7 @@
     last_hidden_page_popup_ = page_popup;
   }
 
-  void RequestDecode(const PaintImage&, WTF::Function<void(bool)> callback);
+  void RequestDecode(const PaintImage&, base::OnceCallback<void(bool)>);
 
  private:
   void SetPageScaleFactorAndLocation(float, const FloatPoint&);
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
index b6e8605..9b67869 100644
--- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
@@ -145,6 +145,7 @@
                                const IntPoint& point,
                                int modifiers) {
   WebMouseEvent result(type, modifiers, WebInputEvent::kTimeStampForTesting);
+  result.pointer_type = WebPointerProperties::PointerType::kMouse;
   result.SetPositionInWidget(point.X(), point.Y());
   result.SetPositionInScreen(point.X(), point.Y());
   result.button = button;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index 13b4439..a0903d0f 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -255,9 +255,10 @@
   if (client_redirect_policy == ClientRedirectPolicy::kNotClientRedirect) {
     if (!loader_.GetDocumentLoader()->GetHistoryItem())
       return;
+    DCHECK(GetDocument());
     FrameLoadRequest request = FrameLoadRequest(
-        nullptr, loader_.ResourceRequestForReload(load_type, NullURL(),
-                                                  client_redirect_policy));
+        GetDocument(), loader_.ResourceRequestForReload(
+                           load_type, NullURL(), client_redirect_policy));
     request.SetClientRedirect(client_redirect_policy);
     loader_.Load(request, load_type);
   } else {
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp
index 8def2c1..1bcd9728 100644
--- a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp
+++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.cpp
@@ -265,8 +265,9 @@
   GetPage()->GetPointerLockController().DidLosePointerLock();
 }
 
-void WebFrameWidgetBase::RequestDecode(const PaintImage& image,
-                                       WTF::Function<void(bool)> callback) {
+void WebFrameWidgetBase::RequestDecode(
+    const PaintImage& image,
+    base::OnceCallback<void(bool)> callback) {
   View()->RequestDecode(image, std::move(callback));
 }
 
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h
index 220edee..7611e25 100644
--- a/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h
+++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetBase.h
@@ -111,7 +111,7 @@
   bool IsFlinging() const override;
 
   // Image decode functionality.
-  void RequestDecode(const PaintImage&, WTF::Function<void(bool)> callback);
+  void RequestDecode(const PaintImage&, base::OnceCallback<void(bool)>);
 
   // This method returns the focused frame belonging to this WebWidget, that
   // is, a focused frame with the same local root as the one corresponding
diff --git a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
index ef217259..848c373 100644
--- a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
@@ -860,6 +860,8 @@
   WebURLRequest request = RequestForReload(load_type, override_url);
   if (request.IsNull())
     return;
+  request.SetRequestorOrigin(
+      WebSecurityOrigin(GetFrame()->GetDocument()->GetSecurityOrigin()));
   Load(request, load_type, WebHistoryItem(), kWebHistoryDifferentDocumentLoad,
        false, base::UnguessableToken::Create());
 }
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
index 8ec606c..d7a6e69 100644
--- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -49,6 +49,7 @@
 #include "core/loader/PingLoader.h"
 #include "core/probe/CoreProbes.h"
 #include "core/workers/WorkerGlobalScope.h"
+#include "core/workers/WorkletGlobalScope.h"
 #include "platform/json/JSONValues.h"
 #include "platform/loader/fetch/IntegrityMetadata.h"
 #include "platform/loader/fetch/ResourceRequest.h"
@@ -1380,6 +1381,10 @@
   if (!queue)
     return;
 
+  // Worklets don't support Events in general.
+  if (execution_context_->IsWorkletGlobalScope())
+    return;
+
   SecurityPolicyViolationEvent* event = SecurityPolicyViolationEvent::Create(
       EventTypeNames::securitypolicyviolation, violation_data);
   DCHECK(event->bubbles());
diff --git a/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp b/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp
index 41340537..a2767e3 100644
--- a/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp
+++ b/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp
@@ -903,6 +903,11 @@
 
   // TODO(foolip): This should not call |UpdateStyleAndLayoutTree()|.
   GetDocument()->UpdateStyleAndLayoutTree();
+
+  // Any element not contained by the fullscreen element is inert (see
+  // |Node::IsInert()|), so changing the fullscreen element will typically
+  // change the inertness of most elements. Clear the entire cache.
+  GetDocument()->ClearAXObjectCache();
 }
 
 void Fullscreen::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.cpp b/third_party/WebKit/Source/core/html/HTMLElement.cpp
index b8bcc95b..19c484d 100644
--- a/third_party/WebKit/Source/core/html/HTMLElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLElement.cpp
@@ -31,7 +31,7 @@
 #include "core/CSSValueKeywords.h"
 #include "core/css/CSSColorValue.h"
 #include "core/css/CSSMarkup.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleChangeReason.h"
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/ElementShadow.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLHRElement.cpp b/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
index 0a2bdc508..1fb5dbc 100644
--- a/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
@@ -25,7 +25,7 @@
 #include "core/CSSPropertyNames.h"
 #include "core/CSSValueKeywords.h"
 #include "core/css/CSSColorValue.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/html/forms/HTMLOptGroupElement.h"
 #include "core/html/forms/HTMLSelectElement.h"
 #include "core/html_names.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLPreElement.cpp b/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
index a144c7f7..4a6ee29f 100644
--- a/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
@@ -24,7 +24,7 @@
 
 #include "core/CSSPropertyNames.h"
 #include "core/CSSValueKeywords.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/html_names.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
index d9654f8..87bea1a 100644
--- a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
@@ -204,7 +204,6 @@
 void HTMLSlotElement::AttachLayoutTree(AttachContext& context) {
   if (SupportsAssignment()) {
     AttachContext children_context(context);
-    children_context.resolved_style = nullptr;
 
     for (auto& node : ChildrenInFlatTreeIfAssignmentIsSupported()) {
       if (node->NeedsAttach())
diff --git a/third_party/WebKit/Source/core/html/HTMLTableElement.cpp b/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
index 1c0264bf2..8e79ac96 100644
--- a/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
@@ -31,7 +31,7 @@
 #include "core/css/CSSIdentifierValue.h"
 #include "core/css/CSSImageValue.h"
 #include "core/css/CSSInheritedValue.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleChangeReason.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/ElementTraversal.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp b/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
index 42fc088..cadfa81 100644
--- a/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
@@ -27,7 +27,7 @@
 #include "core/CSSPropertyNames.h"
 #include "core/CSSValueKeywords.h"
 #include "core/css/CSSImageValue.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/dom/Document.h"
 #include "core/dom/FlatTreeTraversal.h"
 #include "core/frame/UseCounter.h"
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
index a6e3ae0..9da17848 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
@@ -542,7 +542,7 @@
 
 void CanvasAsyncBlobCreator::PostDelayedTaskToCurrentThread(
     const WebTraceLocation& location,
-    WTF::Closure task,
+    base::OnceClosure task,
     double delay_ms) {
   context_->GetTaskRunner(TaskType::kCanvasBlobSerialization)
       ->PostDelayedTask(location, std::move(task),
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h
index c1f524d..64156cd 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h
@@ -82,7 +82,7 @@
   virtual void ScheduleInitiateEncoding(double quality);
   virtual void IdleEncodeRows(double deadline_seconds);
   virtual void PostDelayedTaskToCurrentThread(const WebTraceLocation&,
-                                              WTF::Closure,
+                                              base::OnceClosure,
                                               double delay_ms);
   virtual void SignalAlternativeCodePathFinishedForTesting() {}
   virtual void CreateBlobAndReturnResult();
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
index 33d3250..6fc63ac4 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
@@ -45,7 +45,7 @@
   void CreateNullAndReturnResult() override {}
   void SignalAlternativeCodePathFinishedForTesting() override;
   void PostDelayedTaskToCurrentThread(const WebTraceLocation&,
-                                      WTF::Closure,
+                                      base::OnceClosure,
                                       double delay_ms) override;
 };
 
@@ -55,7 +55,7 @@
 
 void MockCanvasAsyncBlobCreator::PostDelayedTaskToCurrentThread(
     const WebTraceLocation& location,
-    WTF::Closure task,
+    base::OnceClosure task,
     double delay_ms) {
   DCHECK(IsMainThread());
   Platform::Current()->MainThread()->GetWebTaskRunner()->PostTask(
diff --git a/third_party/WebKit/Source/core/html/custom/CustomElementReactionTestHelpers.h b/third_party/WebKit/Source/core/html/custom/CustomElementReactionTestHelpers.h
index 4de0d8d..fd009f3 100644
--- a/third_party/WebKit/Source/core/html/custom/CustomElementReactionTestHelpers.h
+++ b/third_party/WebKit/Source/core/html/custom/CustomElementReactionTestHelpers.h
@@ -34,7 +34,7 @@
 
 class Call : public Command {
  public:
-  using Callback = WTF::Function<void(Element*)>;
+  using Callback = base::OnceCallback<void(Element*)>;
   Call(Callback callback) : callback_(std::move(callback)) {}
   ~Call() override = default;
   void Run(Element* element) override { std::move(callback_).Run(element); }
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLOptionElement.cpp b/third_party/WebKit/Source/core/html/forms/HTMLOptionElement.cpp
index 050385a..e8793a3 100644
--- a/third_party/WebKit/Source/core/html/forms/HTMLOptionElement.cpp
+++ b/third_party/WebKit/Source/core/html/forms/HTMLOptionElement.cpp
@@ -88,7 +88,7 @@
 
 void HTMLOptionElement::AttachLayoutTree(AttachContext& context) {
   AttachContext option_context(context);
-  if (!context.resolved_style && ParentComputedStyle()) {
+  if (!GetNonAttachedStyle() && ParentComputedStyle()) {
     if (HTMLSelectElement* select = OwnerSelectElement())
       select->UpdateListOnLayoutObject();
     SetNonAttachedStyle(OriginalStyleForLayoutObject());
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
index 29843b231..bec7fe62 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
@@ -445,7 +445,7 @@
   // returning control to the parser.
   if (!ParserBlockingScript()->IsReady()) {
     parser_blocking_script_->StartStreamingIfPossible(
-        ScriptStreamer::kParsingBlocking, WTF::Closure());
+        ScriptStreamer::kParsingBlocking, base::OnceClosure());
     parser_blocking_script_->WatchForLoad(this);
   }
 }
@@ -459,7 +459,7 @@
 
   if (!pending_script->IsReady()) {
     pending_script->StartStreamingIfPossible(ScriptStreamer::kDeferred,
-                                             WTF::Closure());
+                                             base::OnceClosure());
   }
 
   DCHECK(pending_script->IsExternalOrModule());
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 0aa62e1..36b2805 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -120,6 +120,22 @@
          IsHTMLInputElement(ToShadowRoot(target_node)->host());
 }
 
+Vector<WebPointerEvent> GetCoalescedWebPointerEventsWithNoTransformation(
+    const Vector<WebTouchEvent>& coalesced_events,
+    int id) {
+  Vector<WebPointerEvent> related_pointer_events;
+  for (const auto& touch_event : coalesced_events) {
+    for (unsigned i = 0; i < touch_event.touches_length; ++i) {
+      if (touch_event.touches[i].id == id &&
+          touch_event.touches[i].state != WebTouchPoint::kStateStationary) {
+        related_pointer_events.push_back(
+            WebPointerEvent(touch_event, touch_event.touches[i]));
+      }
+    }
+  }
+  return related_pointer_events;
+}
+
 }  // namespace
 
 using namespace HTMLNames;
@@ -550,8 +566,10 @@
 }
 
 WebInputEventResult EventHandler::HandlePointerEvent(
-    const WebPointerEvent& web_pointer_event) {
-  return pointer_event_manager_->HandlePointerEvent(web_pointer_event);
+    const WebPointerEvent& web_pointer_event,
+    const Vector<WebPointerEvent>& coalesced_events) {
+  return pointer_event_manager_->HandlePointerEvent(web_pointer_event,
+                                                    coalesced_events);
 }
 
 WebInputEventResult EventHandler::HandleMousePressEvent(
@@ -2058,7 +2076,33 @@
     const WebTouchEvent& event,
     const Vector<WebTouchEvent>& coalesced_events) {
   TRACE_EVENT0("blink", "EventHandler::handleTouchEvent");
-  return pointer_event_manager_->HandleTouchEvents(event, coalesced_events);
+  if (event.GetType() == WebInputEvent::kTouchScrollStarted) {
+    // As long as the type is not mouse it is fine. Any type but mouse causes
+    // all the active scroll capable pointers to get canceled.
+    return pointer_event_manager_->HandlePointerEvent(
+        WebPointerEvent(WebPointerProperties::PointerType::kUnknown,
+                        event.TimeStampSeconds()),
+        Vector<WebPointerEvent>());
+  }
+
+  for (unsigned touch_point_index = 0; touch_point_index < event.touches_length;
+       ++touch_point_index) {
+    const WebTouchPoint& touch_point = event.touches[touch_point_index];
+    if (touch_point.state != blink::WebTouchPoint::kStateStationary) {
+      const WebPointerEvent& web_pointer_event =
+          WebPointerEvent(event, event.touches[touch_point_index]);
+      const Vector<WebPointerEvent>& web_coalesced_pointer_events =
+          GetCoalescedWebPointerEventsWithNoTransformation(
+              coalesced_events, event.touches[touch_point_index].id);
+      pointer_event_manager_->HandlePointerEvent(web_pointer_event,
+                                                 web_coalesced_pointer_events);
+    }
+  }
+
+  // Calling this function |FlushEvents| will be moved to MainThreadEventQueue
+  // class. It will be called before rAF and also whenever we run in low latency
+  // mode as mentioned in crbug.com/728250.
+  return pointer_event_manager_->FlushEvents();
 }
 
 WebInputEventResult EventHandler::PassMousePressEventToSubframe(
diff --git a/third_party/WebKit/Source/core/input/EventHandler.h b/third_party/WebKit/Source/core/input/EventHandler.h
index 0693694..ad9f3b46 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.h
+++ b/third_party/WebKit/Source/core/input/EventHandler.h
@@ -26,6 +26,7 @@
 #ifndef EventHandler_h
 #define EventHandler_h
 
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/CoreExport.h"
 #include "core/dom/UserGestureIndicator.h"
@@ -78,8 +79,6 @@
 
 class CORE_EXPORT EventHandler final
     : public GarbageCollectedFinalized<EventHandler> {
-  WTF_MAKE_NONCOPYABLE(EventHandler);
-
  public:
   explicit EventHandler(LocalFrame&);
   void Trace(blink::Visitor*);
@@ -148,7 +147,9 @@
       const Vector<WebMouseEvent>& coalesced_events);
   void HandleMouseLeaveEvent(const WebMouseEvent&);
 
-  WebInputEventResult HandlePointerEvent(const WebPointerEvent&);
+  WebInputEventResult HandlePointerEvent(
+      const WebPointerEvent&,
+      const Vector<WebPointerEvent>& coalesced_events);
 
   WebInputEventResult HandleMousePressEvent(const WebMouseEvent&);
   WebInputEventResult HandleMouseReleaseEvent(const WebMouseEvent&);
@@ -436,6 +437,8 @@
                            EditableAnchorTextCanStartSelection);
   FRIEND_TEST_ALL_PREFIXES(EventHandlerTest,
                            ReadOnlyInputDoesNotInheritUserSelect);
+
+  DISALLOW_COPY_AND_ASSIGN(EventHandler);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/input/GestureManager.h b/third_party/WebKit/Source/core/input/GestureManager.h
index a58c2063..b4f5b84 100644
--- a/third_party/WebKit/Source/core/input/GestureManager.h
+++ b/third_party/WebKit/Source/core/input/GestureManager.h
@@ -5,6 +5,7 @@
 #ifndef GestureManager_h
 #define GestureManager_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/frame/LocalFrame.h"
 #include "core/layout/HitTestRequest.h"
@@ -24,8 +25,6 @@
 // gesture to the responsible class.
 class CORE_EXPORT GestureManager
     : public GarbageCollectedFinalized<GestureManager> {
-  WTF_MAKE_NONCOPYABLE(GestureManager);
-
  public:
   GestureManager(LocalFrame&,
                  ScrollManager&,
@@ -80,6 +79,7 @@
   const Member<SelectionController> selection_controller_;
 
   WTF::Optional<WTF::TimeTicks> last_show_press_timestamp_;
+  DISALLOW_COPY_AND_ASSIGN(GestureManager);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.cpp b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
index a9f15b4..68d8f1b 100644
--- a/third_party/WebKit/Source/core/input/MouseEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
@@ -913,7 +913,9 @@
     // corresponding pointer.
     if (initiator == DragInitiator::kMouse) {
       frame_->GetEventHandler().HandlePointerEvent(
-          WebPointerEvent(WebInputEvent::Type::kPointerCancel, event.Event()));
+          WebPointerEvent(WebPointerProperties::PointerType::kMouse,
+                          event.Event().TimeStampSeconds()),
+          Vector<WebPointerEvent>());
     }
     // TODO(crbug.com/708278): If the drag starts with touch the touch cancel
     // should trigger the release of pointer capture.
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.h b/third_party/WebKit/Source/core/input/MouseEventManager.h
index 11347077..02a005d 100644
--- a/third_party/WebKit/Source/core/input/MouseEventManager.h
+++ b/third_party/WebKit/Source/core/input/MouseEventManager.h
@@ -5,6 +5,7 @@
 #ifndef MouseEventManager_h
 #define MouseEventManager_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/dom/SynchronousMutationObserver.h"
 #include "core/input/BoundaryEventDispatcher.h"
@@ -35,7 +36,6 @@
 class CORE_EXPORT MouseEventManager final
     : public GarbageCollectedFinalized<MouseEventManager>,
       public SynchronousMutationObserver {
-  WTF_MAKE_NONCOPYABLE(MouseEventManager);
   USING_GARBAGE_COLLECTED_MIXIN(MouseEventManager);
 
  public:
@@ -154,8 +154,6 @@
 
  private:
   class MouseEventBoundaryEventDispatcher : public BoundaryEventDispatcher {
-    WTF_MAKE_NONCOPYABLE(MouseEventBoundaryEventDispatcher);
-
    public:
     MouseEventBoundaryEventDispatcher(MouseEventManager*,
                                       const WebMouseEvent*,
@@ -185,6 +183,7 @@
     const WebMouseEvent* web_mouse_event_;
     Member<EventTarget> exited_target_;
     String canvas_region_id_;
+    DISALLOW_COPY_AND_ASSIGN(MouseEventBoundaryEventDispatcher);
   };
 
   // If the given element is a shadow host and its root has delegatesFocus=false
@@ -246,6 +245,8 @@
   LayoutPoint drag_start_pos_;
 
   TaskRunnerTimer<MouseEventManager> fake_mouse_move_event_timer_;
+
+  DISALLOW_COPY_AND_ASSIGN(MouseEventManager);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
index e662df5..9a1c026 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -33,22 +33,6 @@
   return registry.HasEventHandlers(EventHandlerRegistry::kPointerEvent);
 }
 
-Vector<WebPointerEvent> GetCoalescedWebPointerEventsWithNoTransformation(
-    const Vector<WebTouchEvent>& coalesced_events,
-    int id) {
-  Vector<WebPointerEvent> related_pointer_events;
-  for (const auto& touch_event : coalesced_events) {
-    for (unsigned i = 0; i < touch_event.touches_length; ++i) {
-      if (touch_event.touches[i].id == id &&
-          touch_event.touches[i].state != WebTouchPoint::kStateStationary) {
-        related_pointer_events.push_back(
-            WebPointerEvent(touch_event, touch_event.touches[i]));
-      }
-    }
-  }
-  return related_pointer_events;
-}
-
 }  // namespace
 
 PointerEventManager::PointerEventManager(LocalFrame& frame,
@@ -69,6 +53,7 @@
   node_under_pointer_.clear();
   pointer_capture_target_.clear();
   pending_pointer_capture_target_.clear();
+  user_gesture_holder_.reset();
   dispatching_pointer_id_ = 0;
 }
 
@@ -248,9 +233,10 @@
   }
 }
 
-void PointerEventManager::DispatchPointerCancelEvents(
+void PointerEventManager::HandlePointerInterruption(
     const WebPointerEvent& web_pointer_event) {
-  DCHECK(web_pointer_event.GetType() == WebInputEvent::Type::kPointerCancel);
+  DCHECK(web_pointer_event.GetType() ==
+         WebInputEvent::Type::kPointerCausedUaAction);
 
   HeapVector<Member<PointerEvent>> canceled_pointer_events;
   if (web_pointer_event.pointer_type ==
@@ -309,103 +295,24 @@
   }
 }
 
-void PointerEventManager::UnblockTouchPointers() {
-  scroll_capable_pointers_canceled_ = false;
-}
-
-WebInputEventResult PointerEventManager::HandleTouchEvents(
-    const WebTouchEvent& event,
-    const Vector<WebTouchEvent>& coalesced_events) {
-  if (event.GetType() == WebInputEvent::kTouchScrollStarted) {
-    WebPointerEvent web_pointer_event_cancel;
-    web_pointer_event_cancel.SetType(WebInputEvent::Type::kPointerCancel);
-    web_pointer_event_cancel.SetTimeStampSeconds(event.TimeStampSeconds());
-    web_pointer_event_cancel.pointer_type =
-        WebPointerProperties::PointerType::kTouch;
-    return HandlePointerEvent(web_pointer_event_cancel);
-  }
-
-  bool new_touch_sequence = true;
-  for (unsigned i = 0; i < event.touches_length; ++i) {
-    if (event.touches[i].state != WebTouchPoint::kStatePressed) {
-      new_touch_sequence = false;
-      break;
-    }
-  }
-  if (new_touch_sequence)
-    UnblockTouchPointers();
-
-  // Do the first point target calculation to create the user gesture.
-  EventHandlingUtil::PointerEventTarget first_pointer_event_target;
-  if (event.touches_length) {
-    first_pointer_event_target =
-        ComputePointerEventTarget(event.TouchPointInRootFrame(0));
-  }
-
-  // Any finger lifting is a user gesture only when it wasn't associated with a
-  // scroll.
-  // https://docs.google.com/document/d/1oF1T3O7_E4t1PYHV6gyCwHxOi3ystm0eSL5xZu7nvOg/edit#
-  // Re-use the same UserGesture for touchend and pointerup (but not for the
-  // mouse events generated by GestureTap).
-  // For the rare case of multi-finger scenarios spanning documents, it
-  // seems extremely unlikely to matter which document the gesture is
-  // associated with so just pick the first finger.
-  std::unique_ptr<UserGestureIndicator> holder;
-  if (event.GetType() == WebInputEvent::kTouchEnd &&
-      !scroll_capable_pointers_canceled_ && event.touches_length &&
-      first_pointer_event_target.target_frame) {
-    holder =
-        Frame::NotifyUserActivation(first_pointer_event_target.target_frame);
-  }
-
-  for (unsigned touch_point_idx = 0; touch_point_idx < event.touches_length;
-       ++touch_point_idx) {
-    // Do any necessary hit-tests and compute the event targets for all pointers
-    // in the event.
-    const auto& touch_point = event.TouchPointInRootFrame(touch_point_idx);
-    EventHandlingUtil::PointerEventTarget pointer_event_target =
-        touch_point_idx ? ComputePointerEventTarget(touch_point)
-                        : first_pointer_event_target;
-
-    if (touch_point.state != blink::WebTouchPoint::kStateStationary) {
-      const WebPointerEvent& web_pointer_event =
-          WebPointerEvent(event, event.touches[touch_point_idx]);
-      const Vector<WebPointerEvent>& web_coalesced_pointer_events =
-          GetCoalescedWebPointerEventsWithNoTransformation(
-              coalesced_events, event.touches[touch_point_idx].id);
-      DispatchTouchPointerEvent(web_pointer_event, web_coalesced_pointer_events,
-                                pointer_event_target);
-
-      touch_event_manager_->HandleTouchPoint(web_pointer_event,
-                                             web_coalesced_pointer_events,
-                                             pointer_event_target);
-    }
-  }
-
-  // Calling this function |FlushEvents| will be moved to MainThreadEventQueue
-  // class. It will be called before rAF and also whenever we run in low latency
-  // mode as mentioned in crbug.com/728250.
-  return touch_event_manager_->FlushEvents();
-}
-
 EventHandlingUtil::PointerEventTarget
 PointerEventManager::ComputePointerEventTarget(
-    const WebTouchPoint& touch_point) {
+    const WebPointerEvent& web_pointer_event) {
   EventHandlingUtil::PointerEventTarget pointer_event_target;
 
-  int pointer_id = pointer_event_factory_.GetPointerEventId(touch_point);
+  int pointer_id = pointer_event_factory_.GetPointerEventId(web_pointer_event);
   // Do the hit test either when the touch first starts or when the touch
   // is not captured. |m_pendingPointerCaptureTarget| indicates the target
   // that will be capturing this event. |m_pointerCaptureTarget| may not
   // have this target yet since the processing of that will be done right
   // before firing the event.
-  if (touch_point.state == WebTouchPoint::kStatePressed ||
+  if (web_pointer_event.GetType() == WebInputEvent::kPointerDown ||
       !pending_pointer_capture_target_.Contains(pointer_id)) {
     HitTestRequest::HitTestRequestType hit_type = HitTestRequest::kTouchEvent |
                                                   HitTestRequest::kReadOnly |
                                                   HitTestRequest::kActive;
     LayoutPoint page_point = frame_->View()->RootFrameToContents(
-        LayoutPoint(touch_point.PositionInWidget()));
+        LayoutPoint(web_pointer_event.PositionInWidget()));
     HitTestResult hit_test_tesult =
         frame_->GetEventHandler().HitTestResultAtPoint(page_point, hit_type);
     Node* node = hit_test_tesult.InnerNode();
@@ -440,13 +347,14 @@
   return pointer_event_target;
 }
 
-void PointerEventManager::DispatchTouchPointerEvent(
+WebInputEventResult PointerEventManager::DispatchTouchPointerEvent(
     const WebPointerEvent& web_pointer_event,
     const Vector<WebPointerEvent>& coalesced_events,
     const EventHandlingUtil::PointerEventTarget& pointer_event_target) {
-  // Iterate through the touch points, sending PointerEvents to the targets as
-  // required.
-  // Do not send pointer events for stationary touches or null targetFrame
+  DCHECK_NE(web_pointer_event.GetType(),
+            WebInputEvent::Type::kPointerCausedUaAction);
+
+  WebInputEventResult result = WebInputEventResult::kHandledSystem;
   if (pointer_event_target.target_node && pointer_event_target.target_frame &&
       !scroll_capable_pointers_canceled_) {
     PointerEvent* pointer_event = pointer_event_factory_.Create(
@@ -455,7 +363,7 @@
             ? pointer_event_target.target_node->GetDocument().domWindow()
             : nullptr);
 
-    WebInputEventResult result =
+    result =
         SendTouchPointerEvent(pointer_event_target.target_node, pointer_event);
 
     // If a pointerdown has been canceled, queue the unique id to allow
@@ -471,6 +379,7 @@
           web_pointer_event.unique_touch_event_id);
     }
   }
+  return result;
 }
 
 WebInputEventResult PointerEventManager::SendTouchPointerEvent(
@@ -503,17 +412,53 @@
   return result;
 }
 
-WebInputEventResult PointerEventManager::HandlePointerEvent(
-    const WebPointerEvent& web_pointer_event) {
-  // TODO(crbug.com/625841): This function only handles pointercancel for now.
-  // But we should extend it to handle any pointerevents.
-  DCHECK(web_pointer_event.GetType() == WebInputEvent::Type::kPointerCancel);
+WebInputEventResult PointerEventManager::FlushEvents() {
+  WebInputEventResult result = touch_event_manager_->FlushEvents();
+  user_gesture_holder_.reset();
+  return result;
+}
 
-  if (web_pointer_event.GetType() == WebInputEvent::Type::kPointerCancel) {
-    DispatchPointerCancelEvents(web_pointer_event);
+WebInputEventResult PointerEventManager::HandlePointerEvent(
+    const WebPointerEvent& event,
+    const Vector<WebPointerEvent>& coalesced_events) {
+  if (event.GetType() == WebInputEvent::Type::kPointerCausedUaAction) {
+    HandlePointerInterruption(event);
+    return WebInputEventResult::kHandledSystem;
   }
 
-  return WebInputEventResult::kHandledSystem;
+  if (event.scroll_capable) {
+    if (!touch_event_manager_->IsAnyTouchActive()) {
+      scroll_capable_pointers_canceled_ = false;
+    }
+  }
+
+  // The rest of this function does not handle non-scrolling
+  // (i.e. mouse like) events yet.
+
+  EventHandlingUtil::PointerEventTarget pointer_event_target =
+      ComputePointerEventTarget(event.WebPointerEventInRootFrame());
+
+  // Any finger lifting is a user gesture only when it wasn't associated with a
+  // scroll.
+  // https://docs.google.com/document/d/1oF1T3O7_E4t1PYHV6gyCwHxOi3ystm0eSL5xZu7nvOg/edit#
+  // Re-use the same UserGesture for touchend and pointerup (but not for the
+  // mouse events generated by GestureTap).
+  // For the rare case of multi-finger scenarios spanning documents, it
+  // seems extremely unlikely to matter which document the gesture is
+  // associated with so just pick the pointer event that comes.
+  if (event.GetType() == WebInputEvent::kPointerUp &&
+      !scroll_capable_pointers_canceled_ && pointer_event_target.target_frame) {
+    user_gesture_holder_ =
+        Frame::NotifyUserActivation(pointer_event_target.target_frame);
+  }
+
+  WebInputEventResult result =
+      DispatchTouchPointerEvent(event, coalesced_events, pointer_event_target);
+
+  touch_event_manager_->HandleTouchPoint(event, coalesced_events,
+                                         pointer_event_target);
+
+  return result;
 }
 
 WebInputEventResult PointerEventManager::SendMousePointerEvent(
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.h b/third_party/WebKit/Source/core/input/PointerEventManager.h
index 393431c..5cd4178 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.h
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.h
@@ -5,6 +5,7 @@
 #ifndef PointerEventManager_h
 #define PointerEventManager_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/events/PointerEvent.h"
 #include "core/events/PointerEventFactory.h"
@@ -24,8 +25,6 @@
 // properties of active pointer events.
 class CORE_EXPORT PointerEventManager
     : public GarbageCollectedFinalized<PointerEventManager> {
-  WTF_MAKE_NONCOPYABLE(PointerEventManager);
-
  public:
   PointerEventManager(LocalFrame&, MouseEventManager&);
   void Trace(blink::Visitor*);
@@ -34,7 +33,9 @@
   // cause firing DOM pointerevents, mouseevent, and touch events accordingly.
   // TODO(crbug.com/625841): We need to get all event handling path to go
   // through this function.
-  WebInputEventResult HandlePointerEvent(const WebPointerEvent&);
+  WebInputEventResult HandlePointerEvent(
+      const WebPointerEvent&,
+      const Vector<WebPointerEvent>& coalesced_events);
 
   // Sends the mouse pointer events and the boundary events
   // that it may cause. It also sends the compat mouse events
@@ -47,10 +48,6 @@
       const WebMouseEvent&,
       const Vector<WebMouseEvent>& coalesced_events);
 
-  WebInputEventResult HandleTouchEvents(
-      const WebTouchEvent&,
-      const Vector<WebTouchEvent>& coalesced_events);
-
   // Sends boundary events pointerout/leave/over/enter and
   // mouseout/leave/over/enter to the corresponding targets.
   // inside the document. This functions handles the cases that pointer is
@@ -92,6 +89,13 @@
 
   void ProcessPendingPointerCaptureForPointerLock(const WebMouseEvent&);
 
+  // Sends any outstanding events. For example it notifies TouchEventManager
+  // to group any changes to touch since last FlushEvents and send the touch
+  // event out to js. Since after this function any outstanding event is sent,
+  // it also clears any state that might have kept since the last call to this
+  // function.
+  WebInputEventResult FlushEvents();
+
  private:
   typedef HeapHashMap<int,
                       Member<EventTarget>,
@@ -111,8 +115,6 @@
   };
 
   class PointerEventBoundaryEventDispatcher : public BoundaryEventDispatcher {
-    WTF_MAKE_NONCOPYABLE(PointerEventBoundaryEventDispatcher);
-
    public:
     PointerEventBoundaryEventDispatcher(PointerEventManager*, PointerEvent*);
 
@@ -135,24 +137,23 @@
                   bool check_for_listener);
     Member<PointerEventManager> pointer_event_manager_;
     Member<PointerEvent> pointer_event_;
+    DISALLOW_COPY_AND_ASSIGN(PointerEventBoundaryEventDispatcher);
   };
 
-  // Sends pointercancels for existing PointerEvents. For example when browser
-  // starts dragging with mouse or when we start scrolling with scroll capable
-  // pointers pointercancel events should be dispatched.
-  void DispatchPointerCancelEvents(const WebPointerEvent&);
-
-  // Enables firing of touch-type PointerEvents after they were inhibited by
-  // blockTouchPointers().
-  void UnblockTouchPointers();
+  // Sends pointercancels for existing PointerEvents that are interrupted.
+  // For example when browser starts dragging with mouse or when we start
+  // scrolling with scroll capable pointers pointercancel events should be
+  // dispatched for those. Also sets initial states accordingly so the
+  // following events in that stream don't generate pointerevents (e.g.
+  // in the scrolling case which scroll starts and pointerevents stop and
+  // touchevents continue to fire).
+  void HandlePointerInterruption(const WebPointerEvent&);
 
   // Returns PointerEventTarget for a WebTouchPoint, hit-testing as necessary.
   EventHandlingUtil::PointerEventTarget ComputePointerEventTarget(
-      const WebTouchPoint&);
+      const WebPointerEvent&);
 
-  // Sends touch pointer events and sets consumed bits in TouchInfo array
-  // based on the return value of pointer event handlers.
-  void DispatchTouchPointerEvent(
+  WebInputEventResult DispatchTouchPointerEvent(
       const WebPointerEvent&,
       const Vector<WebPointerEvent>& coalesced_events,
       const EventHandlingUtil::PointerEventTarget&);
@@ -232,9 +233,19 @@
   Member<TouchEventManager> touch_event_manager_;
   Member<MouseEventManager> mouse_event_manager_;
 
+  // TODO(crbug.com/789643): If we go with one token for pointerevent and one
+  // for touch events then we can remove this class field.
+  // It keeps the shared user gesture token between DOM touch events and
+  // pointerevents. It gets created at first when this class gets notified of
+  // the appropriate pointerevent and it must be cleared after the corresponding
+  // touch event is sent (i.e. after FlushEvents).
+  std::unique_ptr<UserGestureIndicator> user_gesture_holder_;
+
   // The pointerId of the PointerEvent currently being dispatched within this
   // frame or 0 if none.
   int dispatching_pointer_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(PointerEventManager);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/input/TouchEventManager.cpp b/third_party/WebKit/Source/core/input/TouchEventManager.cpp
index 9e324ef1..e01f025 100644
--- a/third_party/WebKit/Source/core/input/TouchEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/TouchEventManager.cpp
@@ -89,9 +89,8 @@
   WebTouchPoint web_touch_point(web_pointer_event);
   web_touch_point.state =
       TouchPointStateFromPointerEventType(web_pointer_event.GetType(), stale);
-  // TODO(crbug.com/731725): This mapping needs a division by 2.
-  web_touch_point.radius_x = web_pointer_event.width;
-  web_touch_point.radius_y = web_pointer_event.height;
+  web_touch_point.radius_x = web_pointer_event.width / 2.f;
+  web_touch_point.radius_y = web_pointer_event.height / 2.f;
   web_touch_point.rotation_angle = web_pointer_event.rotation_angle;
   return web_touch_point;
 }
@@ -197,7 +196,7 @@
           ->RootFrameToDocument(transformed_event.PositionInWidget())
           .ScaledBy(scale_factor);
   FloatSize adjusted_radius =
-      FloatSize(transformed_event.width, transformed_event.height)
+      FloatSize(transformed_event.width / 2.f, transformed_event.height / 2.f)
           .ScaledBy(scale_factor);
 
   return Touch::Create(target_frame, touch_node, point_attr->event_.id,
@@ -565,6 +564,7 @@
     const EventHandlingUtil::PointerEventTarget& pointer_event_target) {
   DCHECK_GE(event.GetType(), WebInputEvent::kPointerTypeFirst);
   DCHECK_LE(event.GetType(), WebInputEvent::kPointerTypeLast);
+  DCHECK_NE(event.GetType(), WebInputEvent::kPointerCausedUaAction);
 
   if (touch_attribute_map_.IsEmpty()) {
     // Ideally we'd DCHECK(!m_touchSequenceDocument) here since we should
diff --git a/third_party/WebKit/Source/core/input/TouchEventManager.h b/third_party/WebKit/Source/core/input/TouchEventManager.h
index c473625..6a08fdb3 100644
--- a/third_party/WebKit/Source/core/input/TouchEventManager.h
+++ b/third_party/WebKit/Source/core/input/TouchEventManager.h
@@ -5,6 +5,7 @@
 #ifndef TouchEventManager_h
 #define TouchEventManager_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/events/PointerEventFactory.h"
 #include "core/input/EventHandlingUtil.h"
@@ -26,8 +27,6 @@
 // maintaining related states.
 class CORE_EXPORT TouchEventManager
     : public GarbageCollectedFinalized<TouchEventManager> {
-  WTF_MAKE_NONCOPYABLE(TouchEventManager);
-
  public:
 
   explicit TouchEventManager(LocalFrame&);
@@ -111,6 +110,8 @@
   // The current touch action, computed on each touch start and is
   // a union of all touches. Reset when all touches are released.
   TouchAction current_touch_action_;
+
+  DISALLOW_COPY_AND_ASSIGN(TouchEventManager);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/DOMEditor.cpp b/third_party/WebKit/Source/core/inspector/DOMEditor.cpp
index 775fcba..87c7148 100644
--- a/third_party/WebKit/Source/core/inspector/DOMEditor.cpp
+++ b/third_party/WebKit/Source/core/inspector/DOMEditor.cpp
@@ -30,6 +30,7 @@
 
 #include "core/inspector/DOMEditor.h"
 
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/dom/DOMException.h"
@@ -47,8 +48,6 @@
 using protocol::Response;
 
 class DOMEditor::RemoveChildAction final : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(RemoveChildAction);
-
  public:
   RemoveChildAction(ContainerNode* parent_node, Node* node)
       : InspectorHistory::Action("RemoveChild"),
@@ -82,11 +81,10 @@
   Member<ContainerNode> parent_node_;
   Member<Node> node_;
   Member<Node> anchor_node_;
+  DISALLOW_COPY_AND_ASSIGN(RemoveChildAction);
 };
 
 class DOMEditor::InsertBeforeAction final : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(InsertBeforeAction);
-
  public:
   InsertBeforeAction(ContainerNode* parent_node, Node* node, Node* anchor_node)
       : InspectorHistory::Action("InsertBefore"),
@@ -136,11 +134,10 @@
   Member<Node> node_;
   Member<Node> anchor_node_;
   Member<RemoveChildAction> remove_child_action_;
+  DISALLOW_COPY_AND_ASSIGN(InsertBeforeAction);
 };
 
 class DOMEditor::RemoveAttributeAction final : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(RemoveAttributeAction);
-
  public:
   RemoveAttributeAction(Element* element, const AtomicString& name)
       : InspectorHistory::Action("RemoveAttribute"),
@@ -171,11 +168,10 @@
   Member<Element> element_;
   AtomicString name_;
   AtomicString value_;
+  DISALLOW_COPY_AND_ASSIGN(RemoveAttributeAction);
 };
 
 class DOMEditor::SetAttributeAction final : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(SetAttributeAction);
-
  public:
   SetAttributeAction(Element* element,
                      const AtomicString& name,
@@ -218,11 +214,10 @@
   AtomicString value_;
   bool had_attribute_;
   AtomicString old_value_;
+  DISALLOW_COPY_AND_ASSIGN(SetAttributeAction);
 };
 
 class DOMEditor::SetOuterHTMLAction final : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(SetOuterHTMLAction);
-
  public:
   SetOuterHTMLAction(Node* node, const String& html)
       : InspectorHistory::Action("SetOuterHTML"),
@@ -273,12 +268,11 @@
   Member<Node> new_node_;
   Member<InspectorHistory> history_;
   Member<DOMEditor> dom_editor_;
+  DISALLOW_COPY_AND_ASSIGN(SetOuterHTMLAction);
 };
 
 class DOMEditor::ReplaceWholeTextAction final
     : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(ReplaceWholeTextAction);
-
  public:
   ReplaceWholeTextAction(Text* text_node, const String& text)
       : InspectorHistory::Action("ReplaceWholeText"),
@@ -309,12 +303,11 @@
   Member<Text> text_node_;
   String text_;
   String old_text_;
+  DISALLOW_COPY_AND_ASSIGN(ReplaceWholeTextAction);
 };
 
 class DOMEditor::ReplaceChildNodeAction final
     : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(ReplaceChildNodeAction);
-
  public:
   ReplaceChildNodeAction(ContainerNode* parent_node,
                          Node* new_node,
@@ -349,11 +342,10 @@
   Member<ContainerNode> parent_node_;
   Member<Node> new_node_;
   Member<Node> old_node_;
+  DISALLOW_COPY_AND_ASSIGN(ReplaceChildNodeAction);
 };
 
 class DOMEditor::SetNodeValueAction final : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(SetNodeValueAction);
-
  public:
   SetNodeValueAction(Node* node, const String& value)
       : InspectorHistory::Action("SetNodeValue"), node_(node), value_(value) {}
@@ -382,6 +374,7 @@
   Member<Node> node_;
   String value_;
   String old_value_;
+  DISALLOW_COPY_AND_ASSIGN(SetNodeValueAction);
 };
 
 DOMEditor::DOMEditor(InspectorHistory* history) : history_(history) {}
diff --git a/third_party/WebKit/Source/core/inspector/InspectedFrames.h b/third_party/WebKit/Source/core/inspector/InspectedFrames.h
index c3c2a406..211588df 100644
--- a/third_party/WebKit/Source/core/inspector/InspectedFrames.h
+++ b/third_party/WebKit/Source/core/inspector/InspectedFrames.h
@@ -5,10 +5,10 @@
 #ifndef InspectedFrames_h
 #define InspectedFrames_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Forward.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/text/WTFString.h"
 
 namespace blink {
@@ -17,8 +17,6 @@
 
 class CORE_EXPORT InspectedFrames final
     : public GarbageCollectedFinalized<InspectedFrames> {
-  WTF_MAKE_NONCOPYABLE(InspectedFrames);
-
  public:
   class CORE_EXPORT Iterator {
     STACK_ALLOCATED();
@@ -52,6 +50,7 @@
  private:
   Member<LocalFrame> root_;
   String instrumentation_token_;
+  DISALLOW_COPY_AND_ASSIGN(InspectedFrames);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h
index 2a5a7ffe..c824a2c 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h
@@ -5,6 +5,7 @@
 #ifndef InspectorAnimationAgent_h
 #define InspectorAnimationAgent_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/animation/Animation.h"
 #include "core/css/CSSKeyframesRule.h"
@@ -21,8 +22,6 @@
 
 class CORE_EXPORT InspectorAnimationAgent final
     : public InspectorBaseAgent<protocol::Animation::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorAnimationAgent);
-
  public:
   InspectorAnimationAgent(InspectedFrames*,
                           InspectorCSSAgent*,
@@ -91,6 +90,7 @@
   HashMap<String, String> id_to_animation_type_;
   bool is_cloning_;
   HashSet<String> cleared_animations_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorAnimationAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h
index d4495a8a..feeb094b 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h
@@ -26,11 +26,11 @@
 #ifndef InspectorApplicationCacheAgent_h
 #define InspectorApplicationCacheAgent_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/protocol/ApplicationCache.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
-#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
@@ -39,8 +39,6 @@
 
 class CORE_EXPORT InspectorApplicationCacheAgent final
     : public InspectorBaseAgent<protocol::ApplicationCache::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorApplicationCacheAgent);
-
  public:
   static InspectorApplicationCacheAgent* Create(
       InspectedFrames* inspected_frames) {
@@ -87,6 +85,7 @@
                                                    DocumentLoader*&);
 
   Member<InspectedFrames> inspected_frames_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorApplicationCacheAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
index c298e7e6..e054963 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -25,6 +25,7 @@
 
 #include "core/inspector/InspectorCSSAgent.h"
 
+#include "base/macros.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/CSSPropertyNames.h"
 #include "core/StylePropertyShorthand.h"
@@ -354,20 +355,19 @@
 }
 
 class InspectorCSSAgent::StyleSheetAction : public InspectorHistory::Action {
-  WTF_MAKE_NONCOPYABLE(StyleSheetAction);
-
  public:
   StyleSheetAction(const String& name) : InspectorHistory::Action(name) {}
 
   virtual std::unique_ptr<protocol::CSS::CSSStyle> TakeSerializedStyle() {
     return nullptr;
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StyleSheetAction);
 };
 
 class InspectorCSSAgent::SetStyleSheetTextAction final
     : public InspectorCSSAgent::StyleSheetAction {
-  WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction);
-
  public:
   SetStyleSheetTextAction(InspectorStyleSheetBase* style_sheet,
                           const String& text)
@@ -411,12 +411,11 @@
   Member<InspectorStyleSheetBase> style_sheet_;
   String text_;
   String old_text_;
+  DISALLOW_COPY_AND_ASSIGN(SetStyleSheetTextAction);
 };
 
 class InspectorCSSAgent::ModifyRuleAction final
     : public InspectorCSSAgent::StyleSheetAction {
-  WTF_MAKE_NONCOPYABLE(ModifyRuleAction);
-
  public:
   enum Type {
     kSetRuleSelector,
@@ -531,12 +530,11 @@
   SourceRange old_range_;
   SourceRange new_range_;
   Member<CSSRule> css_rule_;
+  DISALLOW_COPY_AND_ASSIGN(ModifyRuleAction);
 };
 
 class InspectorCSSAgent::SetElementStyleAction final
     : public InspectorCSSAgent::StyleSheetAction {
-  WTF_MAKE_NONCOPYABLE(SetElementStyleAction);
-
  public:
   SetElementStyleAction(InspectorStyleSheetForInlineStyle* style_sheet,
                         const String& text)
@@ -583,12 +581,11 @@
   Member<InspectorStyleSheetForInlineStyle> style_sheet_;
   String text_;
   String old_text_;
+  DISALLOW_COPY_AND_ASSIGN(SetElementStyleAction);
 };
 
 class InspectorCSSAgent::AddRuleAction final
     : public InspectorCSSAgent::StyleSheetAction {
-  WTF_MAKE_NONCOPYABLE(AddRuleAction);
-
  public:
   AddRuleAction(InspectorStyleSheet* style_sheet,
                 const String& rule_text,
@@ -633,6 +630,7 @@
   String old_text_;
   SourceRange location_;
   SourceRange added_range_;
+  DISALLOW_COPY_AND_ASSIGN(AddRuleAction);
 };
 
 // static
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
index 709aef49..0019aa6 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
@@ -26,6 +26,7 @@
 #ifndef InspectorCSSAgent_h
 #define InspectorCSSAgent_h
 
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/CoreExport.h"
 #include "core/css/CSSSelector.h"
@@ -62,7 +63,6 @@
     : public InspectorBaseAgent<protocol::CSS::Metainfo>,
       public InspectorDOMAgent::DOMListener,
       public InspectorStyleSheetBase::Listener {
-  WTF_MAKE_NONCOPYABLE(InspectorCSSAgent);
   USING_GARBAGE_COLLECTED_MIXIN(InspectorCSSAgent);
 
  public:
@@ -333,6 +333,7 @@
 
   friend class InspectorResourceContentLoaderCallback;
   friend class StyleSheetBinder;
+  DISALLOW_COPY_AND_ASSIGN(InspectorCSSAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index 9a8ddeb4..a43b63c 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -1740,7 +1740,7 @@
     Node* node,
     int depth,
     bool pierce,
-    const WTF::RepeatingFunction<bool(Node*)>& filter,
+    base::RepeatingCallback<bool(Node*)> filter,
     HeapVector<Member<Node>>* result) {
   if (filter && filter.Run(node))
     result->push_back(node);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
index e46d457..4918958 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
@@ -31,6 +31,8 @@
 #define InspectorDOMAgent_h
 
 #include <memory>
+#include "base/callback.h"
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/CoreExport.h"
 #include "core/dom/events/EventListenerMap.h"
@@ -66,8 +68,6 @@
 
 class CORE_EXPORT InspectorDOMAgent final
     : public InspectorBaseAgent<protocol::DOM::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorDOMAgent);
-
  public:
   struct CORE_EXPORT DOMListener : public GarbageCollectedMixin {
     virtual ~DOMListener() {}
@@ -254,7 +254,7 @@
   static void CollectNodes(Node* root,
                            int depth,
                            bool pierce,
-                           const WTF::RepeatingFunction<bool(Node*)>&,
+                           base::RepeatingCallback<bool(Node*)>,
                            HeapVector<Member<Node>>* result);
 
   protocol::Response AssertNode(int node_id, Node*&);
@@ -335,6 +335,7 @@
   Member<InspectorHistory> history_;
   Member<DOMEditor> dom_editor_;
   bool suppress_attribute_modified_event_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorDOMAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
index 6a99f61..9474adf 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
@@ -31,6 +31,7 @@
 #ifndef InspectorDOMDebuggerAgent_h
 #define InspectorDOMDebuggerAgent_h
 
+#include "base/macros.h"
 #include "bindings/core/v8/V8EventListenerInfo.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
@@ -57,8 +58,6 @@
 
 class CORE_EXPORT InspectorDOMDebuggerAgent final
     : public InspectorBaseAgent<protocol::DOMDebugger::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorDOMDebuggerAgent);
-
  public:
   static void EventListenersInfoForTarget(v8::Isolate*,
                                           v8::Local<v8::Value>,
@@ -159,6 +158,7 @@
   Member<InspectorDOMAgent> dom_agent_;
   v8_inspector::V8InspectorSession* v8_session_;
   HeapHashMap<Member<Node>, uint32_t> dom_breakpoints_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorDOMDebuggerAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp b/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp
index 43f57e3..4d35af6 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorHighlight.cpp
@@ -4,6 +4,7 @@
 
 #include "core/inspector/InspectorHighlight.h"
 
+#include "base/macros.h"
 #include "core/dom/PseudoElement.h"
 #include "core/frame/LocalFrameView.h"
 #include "core/frame/VisualViewport.h"
@@ -25,7 +26,6 @@
 
 class PathBuilder {
   STACK_ALLOCATED();
-  WTF_MAKE_NONCOPYABLE(PathBuilder);
 
  public:
   PathBuilder() : path_(protocol::ListValue::create()) {}
@@ -54,6 +54,7 @@
                                   size_t length);
 
   std::unique_ptr<protocol::ListValue> path_;
+  DISALLOW_COPY_AND_ASSIGN(PathBuilder);
 };
 
 void PathBuilder::AppendPathCommandAndPoints(const char* command,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorIOAgent.h b/third_party/WebKit/Source/core/inspector/InspectorIOAgent.h
index dfd9a22..2de0569 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorIOAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorIOAgent.h
@@ -5,10 +5,10 @@
 #ifndef InspectorIOAgent_h
 #define InspectorIOAgent_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/protocol/IO.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/text/WTFString.h"
 
 namespace v8 {
@@ -23,8 +23,6 @@
 
 class CORE_EXPORT InspectorIOAgent final
     : public InspectorBaseAgent<protocol::IO::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorIOAgent);
-
  public:
   InspectorIOAgent(v8::Isolate*, v8_inspector::V8InspectorSession*);
 
@@ -39,6 +37,7 @@
 
   v8::Isolate* isolate_;
   v8_inspector::V8InspectorSession* v8_session_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorIOAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
index 11460aac..fdc40e64 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
@@ -30,13 +30,13 @@
 #ifndef InspectorLayerTreeAgent_h
 #define InspectorLayerTreeAgent_h
 
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/protocol/LayerTree.h"
 #include "core/page/PageOverlay.h"
 #include "platform/Timer.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/text/WTFString.h"
 
 namespace blink {
@@ -51,8 +51,6 @@
 
 class CORE_EXPORT InspectorLayerTreeAgent final
     : public InspectorBaseAgent<protocol::LayerTree::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorLayerTreeAgent);
-
  public:
   class Client {
    public:
@@ -134,6 +132,7 @@
   typedef HashMap<String, scoped_refptr<PictureSnapshot>> SnapshotById;
   SnapshotById snapshot_by_id_;
   bool suppress_layer_paint_events_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorLayerTreeAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLogAgent.h b/third_party/WebKit/Source/core/inspector/InspectorLogAgent.h
index 81f11d8..c19f8d0 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLogAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorLogAgent.h
@@ -5,6 +5,7 @@
 #ifndef InspectorLogAgent_h
 #define InspectorLogAgent_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/frame/PerformanceMonitor.h"
 #include "core/inspector/InspectorBaseAgent.h"
@@ -23,7 +24,6 @@
     : public InspectorBaseAgent<protocol::Log::Metainfo>,
       public PerformanceMonitor::Client {
   USING_GARBAGE_COLLECTED_MIXIN(InspectorLogAgent);
-  WTF_MAKE_NONCOPYABLE(InspectorLogAgent);
 
  public:
   InspectorLogAgent(ConsoleMessageStorage*,
@@ -58,6 +58,7 @@
   Member<ConsoleMessageStorage> storage_;
   Member<PerformanceMonitor> performance_monitor_;
   v8_inspector::V8InspectorSession* v8_session_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorLogAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h
index 95df731..2c953846 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h
@@ -31,6 +31,7 @@
 #ifndef InspectorMemoryAgent_h
 #define InspectorMemoryAgent_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/protocol/Memory.h"
@@ -44,8 +45,6 @@
 class CORE_EXPORT InspectorMemoryAgent final
     : public InspectorBaseAgent<protocol::Memory::Metainfo>,
       public BlinkLeakDetectorClient {
-  WTF_MAKE_NONCOPYABLE(InspectorMemoryAgent);
-
  public:
   static InspectorMemoryAgent* Create(InspectedFrames* frames) {
     return new InspectorMemoryAgent(frames);
@@ -68,6 +67,7 @@
   std::unique_ptr<BlinkLeakDetector> detector_;
   std::unique_ptr<PrepareForLeakDetectionCallback> callback_;
   Member<InspectedFrames> frames_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorMemoryAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
index 7c8635b..d144c47 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
@@ -33,6 +33,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/SourceLocation.h"
@@ -148,8 +149,6 @@
 }
 
 class InspectorFileReaderLoaderClient final : public FileReaderLoaderClient {
-  WTF_MAKE_NONCOPYABLE(InspectorFileReaderLoaderClient);
-
  public:
   InspectorFileReaderLoaderClient(
       scoped_refptr<BlobDataHandle> blob,
@@ -208,6 +207,7 @@
   std::unique_ptr<GetResponseBodyCallback> callback_;
   std::unique_ptr<FileReaderLoader> loader_;
   scoped_refptr<SharedBuffer> raw_data_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorFileReaderLoaderClient);
 };
 
 KURL UrlWithoutFragment(const KURL& url) {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h b/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h
index 6e7bd02..44e284c 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.h
@@ -31,6 +31,7 @@
 
 #include <v8-inspector.h>
 #include <memory>
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
@@ -63,7 +64,6 @@
 class CORE_EXPORT InspectorOverlayAgent final
     : public InspectorBaseAgent<protocol::Overlay::Metainfo>,
       public InspectorOverlayHost::Listener {
-  WTF_MAKE_NONCOPYABLE(InspectorOverlayAgent);
   USING_GARBAGE_COLLECTED_MIXIN(InspectorOverlayAgent);
 
  public:
@@ -223,6 +223,7 @@
   bool screenshot_mode_ = false;
   IntPoint screenshot_anchor_;
   IntPoint screenshot_position_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorOverlayAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
index 46f7be7..ed586b5 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
@@ -31,6 +31,7 @@
 #ifndef InspectorPageAgent_h
 #define InspectorPageAgent_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/protocol/Page.h"
@@ -60,8 +61,6 @@
 
 class CORE_EXPORT InspectorPageAgent final
     : public InspectorBaseAgent<protocol::Page::Metainfo> {
-  WTF_MAKE_NONCOPYABLE(InspectorPageAgent);
-
  public:
   class Client {
    public:
@@ -238,6 +237,7 @@
   bool reloading_;
   Member<InspectorResourceContentLoader> inspector_resource_content_loader_;
   int resource_content_loader_client_id_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorPageAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContainer.h b/third_party/WebKit/Source/core/inspector/InspectorResourceContainer.h
index 4a63179..9b32d57 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorResourceContainer.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContainer.h
@@ -5,11 +5,11 @@
 #ifndef InspectorResourceContainer_h
 #define InspectorResourceContainer_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Forward.h"
 #include "platform/wtf/HashMap.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/text/StringHash.h"
 #include "platform/wtf/text/WTFString.h"
 
@@ -20,8 +20,6 @@
 
 class CORE_EXPORT InspectorResourceContainer
     : public GarbageCollectedFinalized<InspectorResourceContainer> {
-  WTF_MAKE_NONCOPYABLE(InspectorResourceContainer);
-
  public:
   explicit InspectorResourceContainer(InspectedFrames*);
   ~InspectorResourceContainer();
@@ -39,6 +37,7 @@
   Member<InspectedFrames> inspected_frames_;
   HashMap<String, String> style_sheet_contents_;
   HashMap<int, String> style_element_contents_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorResourceContainer);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
index 795f87f..7b12494b 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
@@ -143,7 +143,7 @@
 
 void InspectorResourceContentLoader::EnsureResourcesContentLoaded(
     int client_id,
-    WTF::Closure callback) {
+    base::OnceClosure callback) {
   if (!started_)
     Start();
   callbacks_.insert(client_id, Callbacks())
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
index a256723..c4e3fe2 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
@@ -5,12 +5,12 @@
 #ifndef InspectorResourceContentLoader_h
 #define InspectorResourceContentLoader_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "platform/loader/fetch/Resource.h"
 #include "platform/wtf/Functional.h"
 #include "platform/wtf/HashMap.h"
 #include "platform/wtf/HashSet.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/Vector.h"
 
 namespace blink {
@@ -21,8 +21,6 @@
 
 class CORE_EXPORT InspectorResourceContentLoader final
     : public GarbageCollectedFinalized<InspectorResourceContentLoader> {
-  WTF_MAKE_NONCOPYABLE(InspectorResourceContentLoader);
-
  public:
   static InspectorResourceContentLoader* Create(LocalFrame* inspected_frame) {
     return new InspectorResourceContentLoader(inspected_frame);
@@ -32,7 +30,7 @@
   void Trace(blink::Visitor*);
 
   int CreateClientId();
-  void EnsureResourcesContentLoaded(int client_id, WTF::Closure callback);
+  void EnsureResourcesContentLoaded(int client_id, base::OnceClosure callback);
   void Cancel(int client_id);
   void DidCommitLoadForLocalFrame(LocalFrame*);
 
@@ -48,7 +46,7 @@
   void Stop();
   bool HasFinished();
 
-  using Callbacks = Vector<WTF::Closure>;
+  using Callbacks = Vector<base::OnceClosure>;
   HashMap<int, Callbacks> callbacks_;
   bool all_requests_started_;
   bool started_;
@@ -58,6 +56,7 @@
   int last_client_id_;
 
   friend class ResourceClient;
+  DISALLOW_COPY_AND_ASSIGN(InspectorResourceContentLoader);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h b/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h
index 03bc06c..195dbfa4 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorTaskRunner.h
@@ -5,19 +5,18 @@
 #ifndef InspectorTaskRunner_h
 #define InspectorTaskRunner_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Deque.h"
 #include "platform/wtf/Forward.h"
 #include "platform/wtf/Functional.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/ThreadingPrimitives.h"
 #include "v8/include/v8.h"
 
 namespace blink {
 
 class CORE_EXPORT InspectorTaskRunner final {
-  WTF_MAKE_NONCOPYABLE(InspectorTaskRunner);
   USING_FAST_MALLOC(InspectorTaskRunner);
 
  public:
@@ -55,6 +54,7 @@
   ThreadCondition condition_;
   Deque<Task> queue_;
   bool killed_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorTaskRunner);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
index 782c5557..31291a744 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/css/CSSSelector.h"
 #include "core/inspector/InspectorBaseAgent.h"
@@ -70,8 +71,6 @@
 }
 
 class CORE_EXPORT InspectorTraceEvents : public InspectorAgent {
-  WTF_MAKE_NONCOPYABLE(InspectorTraceEvents);
-
  public:
   InspectorTraceEvents() {}
 
@@ -118,6 +117,7 @@
 
  private:
   Member<CoreProbeSink> instrumenting_agents_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorTraceEvents);
 };
 
 namespace InspectorLayoutEvent {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
index be04545..d8b9c0a 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
@@ -31,6 +31,7 @@
 #ifndef InspectorWorkerAgent_h
 #define InspectorWorkerAgent_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/protocol/Target.h"
@@ -45,8 +46,6 @@
 class CORE_EXPORT InspectorWorkerAgent final
     : public InspectorBaseAgent<protocol::Target::Metainfo>,
       public WorkerInspectorProxy::PageInspector {
-  WTF_MAKE_NONCOPYABLE(InspectorWorkerAgent);
-
  public:
   explicit InspectorWorkerAgent(InspectedFrames*);
   ~InspectorWorkerAgent() override;
@@ -90,6 +89,7 @@
   HashMap<String, int> session_id_to_connection_;
   String tracing_session_id_;
   static int s_last_connection_;
+  DISALLOW_COPY_AND_ASSIGN(InspectorWorkerAgent);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h
index 7cbc46f..b70415cc 100644
--- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h
+++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.h
@@ -32,6 +32,7 @@
 #define MainThreadDebugger_h
 
 #include <memory>
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/InspectorTaskRunner.h"
 #include "core/inspector/ThreadDebugger.h"
@@ -48,8 +49,6 @@
 class SourceLocation;
 
 class CORE_EXPORT MainThreadDebugger final : public ThreadDebugger {
-  WTF_MAKE_NONCOPYABLE(MainThreadDebugger);
-
  public:
   class ClientMessageLoop {
     USING_FAST_MALLOC(ClientMessageLoop);
@@ -122,6 +121,7 @@
   std::unique_ptr<InspectorTaskRunner> task_runner_;
   bool paused_;
   static MainThreadDebugger* instance_;
+  DISALLOW_COPY_AND_ASSIGN(MainThreadDebugger);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
index 2881b8a..4d98dac 100644
--- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
+++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
@@ -6,6 +6,7 @@
 #define ThreadDebugger_h
 
 #include <memory>
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/dom/UserGestureIndicator.h"
 #include "core/inspector/ConsoleTypes.h"
@@ -25,8 +26,6 @@
 // TODO(dgozman): rename this to ThreadInspector (and subclasses).
 class CORE_EXPORT ThreadDebugger : public v8_inspector::V8InspectorClient,
                                    public V8PerIsolateData::Data {
-  WTF_MAKE_NONCOPYABLE(ThreadDebugger);
-
  public:
   explicit ThreadDebugger(v8::Isolate*);
   ~ThreadDebugger() override;
@@ -115,6 +114,7 @@
   Vector<v8_inspector::V8InspectorClient::TimerCallback> timer_callbacks_;
   Vector<void*> timer_data_;
   std::unique_ptr<UserGestureIndicator> user_gesture_indicator_;
+  DISALLOW_COPY_AND_ASSIGN(ThreadDebugger);
 };
 
 template <>
diff --git a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h
index 5ea5beb..5e8d035 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h
+++ b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h
@@ -31,13 +31,13 @@
 #ifndef WorkerInspectorController_h
 #define WorkerInspectorController_h
 
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/inspector/InspectorSession.h"
 #include "core/inspector/InspectorTaskRunner.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Forward.h"
 #include "platform/wtf/HashMap.h"
-#include "platform/wtf/Noncopyable.h"
 #include "public/platform/WebThread.h"
 
 namespace blink {
@@ -50,8 +50,6 @@
     : public GarbageCollectedFinalized<WorkerInspectorController>,
       public InspectorSession::Client,
       private WebThread::TaskObserver {
-  WTF_MAKE_NONCOPYABLE(WorkerInspectorController);
-
  public:
   static WorkerInspectorController* Create(WorkerThread*);
   ~WorkerInspectorController() override;
@@ -83,6 +81,7 @@
   WorkerThread* thread_;
   Member<CoreProbeSink> probe_sink_;
   HeapHashMap<int, Member<InspectorSession>> sessions_;
+  DISALLOW_COPY_AND_ASSIGN(WorkerInspectorController);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h
index bab6a69..ff01a7d 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h
+++ b/third_party/WebKit/Source/core/inspector/WorkerThreadDebugger.h
@@ -31,6 +31,7 @@
 #ifndef WorkerThreadDebugger_h
 #define WorkerThreadDebugger_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/ThreadDebugger.h"
 
@@ -41,8 +42,6 @@
 class WorkerThread;
 
 class CORE_EXPORT WorkerThreadDebugger final : public ThreadDebugger {
-  WTF_MAKE_NONCOPYABLE(WorkerThreadDebugger);
-
  public:
   explicit WorkerThreadDebugger(v8::Isolate*);
   ~WorkerThreadDebugger() override;
@@ -87,6 +86,7 @@
 
   int paused_context_group_id_;
   WTF::HashMap<int, WorkerThread*> worker_threads_;
+  DISALLOW_COPY_AND_ASSIGN(WorkerThreadDebugger);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json
index 73eda3f0..46b61a8 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -5492,6 +5492,29 @@
                     ]
                 },
                 {
+                    "name": "deleteObjectStoreEntries",
+                    "description": "Delete a range of entries from an object store",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "type": "string"
+                        },
+                        {
+                            "name": "databaseName",
+                            "type": "string"
+                        },
+                        {
+                            "name": "objectStoreName",
+                            "type": "string"
+                        },
+                        {
+                            "name": "keyRange",
+                            "description": "Range of entry keys to delete",
+                            "$ref": "KeyRange"
+                        }
+                    ]
+                },
+                {
                     "name": "disable",
                     "description": "Disables events from backend."
                 },
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.pdl b/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
index abe4414..3bcafa9 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
@@ -1979,7 +1979,7 @@
   # Returns a document snapshot, including the full DOM tree of the root node (including iframes,
   # template contents, and imported documents) in a flattened array, as well as layout and
   # white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is
-  # flattened. 
+  # flattened.
   command getSnapshot
     parameters
       # Whitelist of computed styles to return.
@@ -2508,6 +2508,15 @@
       # Database name.
       string databaseName
 
+  # Delete a range of entries from an object store
+  command deleteObjectStoreEntries
+    parameters
+      string securityOrigin
+      string databaseName
+      string objectStoreName
+      # Range of entry keys to delete
+      KeyRange keyRange
+
   # Disables events from backend.
   command disable
 
@@ -4982,7 +4991,7 @@
       ServiceWorkerVersionStatus status
       # The Last-Modified header value of the main script.
       optional number scriptLastModified
-      # The time at which the response headers of the main script were received from the server. 
+      # The time at which the response headers of the main script were received from the server.
       # For cached script it is the last time the cache entry was validated.
       optional number scriptResponseTime
       optional array of Target.TargetID controlledClients
diff --git a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
index aeecf82..810fd76f 100644
--- a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
+++ b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
@@ -48,7 +48,7 @@
             },
             {
                 "domain": "IndexedDB",
-                "async": ["requestDatabaseNames", "requestDatabase", "requestData", "clearObjectStore", "deleteDatabase"]
+                "async": ["requestDatabaseNames", "requestDatabase", "requestData", "deleteObjectStoreEntries", "clearObjectStore", "deleteDatabase"]
             },
             {
                 "domain": "LayerTree"
diff --git a/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.cpp b/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.cpp
index 68fdbd8..5dcb527 100644
--- a/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.cpp
+++ b/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.cpp
@@ -281,7 +281,7 @@
 }
 
 void IntersectionObserver::ComputeIntersectionObservations() {
-  if (!RootIsValid())
+  if (!RootIsValid() || !delegate_->GetExecutionContext())
     return;
   Document* delegate_document = ToDocument(delegate_->GetExecutionContext());
   if (!delegate_document || delegate_document->IsStopped())
diff --git a/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.h b/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.h
index 975aa19..6fd1b5d 100644
--- a/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.h
+++ b/third_party/WebKit/Source/core/intersection_observer/IntersectionObserver.h
@@ -5,6 +5,7 @@
 #ifndef IntersectionObserver_h
 #define IntersectionObserver_h
 
+#include "base/callback.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/intersection_observer/IntersectionObservation.h"
 #include "core/intersection_observer/IntersectionObserverEntry.h"
@@ -29,7 +30,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  using EventCallback = WTF::RepeatingFunction<void(
+  using EventCallback = base::RepeatingCallback<void(
       const HeapVector<Member<IntersectionObserverEntry>>&)>;
 
   static IntersectionObserver* Create(const IntersectionObserverInit&,
diff --git a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp
index d292dce9..de1f0f3b 100644
--- a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp
+++ b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp
@@ -434,7 +434,7 @@
   // flex-start (ignoring the specified fallback alignment, if any).
   // https://drafts.csswg.org/css-align/#distribution-flex
   static const StyleContentAlignmentData kNormalBehavior = {
-      kContentPositionNormal, kContentDistributionStretch};
+      ContentPosition::kNormal, ContentDistributionType::kStretch};
   return kNormalBehavior;
 }
 
@@ -485,9 +485,9 @@
   OverflowAlignment overflow = style.JustifyContentOverflowAlignment();
   // For flex, justify-content: stretch behaves as flex-start:
   // https://drafts.csswg.org/css-align/#distribution-flex
-  if (distribution == kContentDistributionStretch) {
-    position = kContentPositionFlexStart;
-    distribution = kContentDistributionDefault;
+  if (distribution == ContentDistributionType::kStretch) {
+    position = ContentPosition::kFlexStart;
+    distribution = ContentDistributionType::kDefault;
   }
   return StyleContentAlignmentData(position, distribution, overflow);
 }
@@ -529,17 +529,17 @@
     LayoutUnit available_free_space,
     const StyleContentAlignmentData& data,
     unsigned number_of_items) {
-  if (data.GetPosition() == kContentPositionFlexEnd)
+  if (data.GetPosition() == ContentPosition::kFlexEnd)
     return available_free_space;
-  if (data.GetPosition() == kContentPositionCenter)
+  if (data.GetPosition() == ContentPosition::kCenter)
     return available_free_space / 2;
-  if (data.Distribution() == kContentDistributionSpaceAround) {
+  if (data.Distribution() == ContentDistributionType::kSpaceAround) {
     if (available_free_space > 0 && number_of_items)
       return available_free_space / (2 * number_of_items);
 
     return available_free_space / 2;
   }
-  if (data.Distribution() == kContentDistributionSpaceEvenly) {
+  if (data.Distribution() == ContentDistributionType::kSpaceEvenly) {
     if (available_free_space > 0 && number_of_items)
       return available_free_space / (number_of_items + 1);
     // Fallback to 'center'
@@ -553,12 +553,12 @@
     const StyleContentAlignmentData& data,
     unsigned number_of_items) {
   if (available_free_space > 0 && number_of_items > 1) {
-    if (data.Distribution() == kContentDistributionSpaceBetween)
+    if (data.Distribution() == ContentDistributionType::kSpaceBetween)
       return available_free_space / (number_of_items - 1);
-    if (data.Distribution() == kContentDistributionSpaceAround ||
-        data.Distribution() == kContentDistributionStretch)
+    if (data.Distribution() == ContentDistributionType::kSpaceAround ||
+        data.Distribution() == ContentDistributionType::kStretch)
       return available_free_space / number_of_items;
-    if (data.Distribution() == kContentDistributionSpaceEvenly)
+    if (data.Distribution() == ContentDistributionType::kSpaceEvenly)
       return available_free_space / (number_of_items + 1);
   }
   return LayoutUnit();
diff --git a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
index 3eaedec..a18bc34f 100644
--- a/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
+++ b/third_party/WebKit/Source/core/layout/GridTrackSizingAlgorithm.cpp
@@ -1369,7 +1369,7 @@
   LayoutUnit free_space = strategy_->FreeSpaceForStretchAutoTracksStep();
   if (auto_sized_tracks_for_stretch_index_.IsEmpty() || (free_space <= 0) ||
       (layout_grid_->ContentAlignment(direction_).Distribution() !=
-       kContentDistributionStretch))
+       ContentDistributionType::kStretch))
     return;
 
   unsigned number_of_auto_sized_tracks =
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index d1d9c918..fe975f72 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -245,6 +245,11 @@
 
   LayoutBoxModelObject::StyleDidChange(diff, old_style);
 
+  // Reflection works through PaintLayer. Some child classes e.g. LayoutSVGBlock
+  // don't create layers and ignore reflections.
+  if (HasReflection() && !HasLayer())
+    SetHasReflection(false);
+
   if (IsFloatingOrOutOfFlowPositioned() && old_style &&
       !old_style->IsFloating() && !old_style->HasOutOfFlowPosition() &&
       Parent() && Parent()->IsLayoutBlockFlow())
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
index dbc6d3c..656983b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -1568,7 +1568,7 @@
     return;
   }
 
-  if (align_content.GetPosition() == kContentPositionFlexStart)
+  if (align_content.GetPosition() == ContentPosition::kFlexStart)
     return;
 
   LayoutUnit available_cross_axis_space = CrossAxisContentExtent();
@@ -1590,7 +1590,7 @@
       AdjustAlignmentForChild(*flex_item.box, line_offset);
     }
 
-    if (align_content.Distribution() == kContentDistributionStretch &&
+    if (align_content.Distribution() == ContentDistributionType::kStretch &&
         available_cross_axis_space > 0)
       line_contexts[line_number].cross_axis_extent +=
           available_cross_axis_space /
diff --git a/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp b/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp
index a60cbb25..329678c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFullScreen.cpp
@@ -103,7 +103,7 @@
   fullscreen_style->GetFont().Update(nullptr);
 
   fullscreen_style->SetDisplay(EDisplay::kFlex);
-  fullscreen_style->SetJustifyContentPosition(kContentPositionCenter);
+  fullscreen_style->SetJustifyContentPosition(ContentPosition::kCenter);
   // TODO (lajava): Since the FullScrenn layout object is anonymous, its Default
   // Alignment (align-items) value can't be used to resolve its children Self
   // Alignment 'auto' values.
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 6458aef..416e26a1 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -1145,7 +1145,7 @@
 
 const StyleContentAlignmentData& LayoutGrid::ContentAlignmentNormalBehavior() {
   static const StyleContentAlignmentData kNormalBehavior = {
-      kContentPositionNormal, kContentDistributionStretch};
+      ContentPosition::kNormal, ContentDistributionType::kStretch};
   return kNormalBehavior;
 }
 
@@ -2050,11 +2050,12 @@
   int last_line = NumTracks(kForColumns, grid_);
   ContentPosition position = StyleRef().ResolvedJustifyContentPosition(
       ContentAlignmentNormalBehavior());
-  if (position == kContentPositionEnd)
+  if (position == ContentPosition::kEnd)
     return column_positions_[last_line] - ClientLogicalWidth();
-  if (position == kContentPositionStart ||
+  if (position == ContentPosition::kStart ||
       StyleRef().ResolvedJustifyContentDistribution(
-          ContentAlignmentNormalBehavior()) == kContentDistributionStretch)
+          ContentAlignmentNormalBehavior()) ==
+          ContentDistributionType::kStretch)
     return column_positions_[0] - BorderAndPaddingLogicalLeft();
   return LayoutUnit();
 }
@@ -2069,11 +2070,12 @@
   int last_line = NumTracks(kForColumns, grid_);
   ContentPosition position = StyleRef().ResolvedJustifyContentPosition(
       ContentAlignmentNormalBehavior());
-  if (position == kContentPositionEnd)
+  if (position == ContentPosition::kEnd)
     return column_positions_[last_line];
-  if (position == kContentPositionStart ||
+  if (position == ContentPosition::kStart ||
       StyleRef().ResolvedJustifyContentDistribution(
-          ContentAlignmentNormalBehavior()) == kContentDistributionStretch) {
+          ContentAlignmentNormalBehavior()) ==
+          ContentDistributionType::kStretch) {
     return column_positions_[0] - BorderAndPaddingLogicalLeft() +
            ClientLogicalWidth();
   }
@@ -2225,20 +2227,20 @@
 ContentPosition static ResolveContentDistributionFallback(
     ContentDistributionType distribution) {
   switch (distribution) {
-    case kContentDistributionSpaceBetween:
-      return kContentPositionStart;
-    case kContentDistributionSpaceAround:
-      return kContentPositionCenter;
-    case kContentDistributionSpaceEvenly:
-      return kContentPositionCenter;
-    case kContentDistributionStretch:
-      return kContentPositionStart;
-    case kContentDistributionDefault:
-      return kContentPositionNormal;
+    case ContentDistributionType::kSpaceBetween:
+      return ContentPosition::kStart;
+    case ContentDistributionType::kSpaceAround:
+      return ContentPosition::kCenter;
+    case ContentDistributionType::kSpaceEvenly:
+      return ContentPosition::kCenter;
+    case ContentDistributionType::kStretch:
+      return ContentPosition::kStart;
+    case ContentDistributionType::kDefault:
+      return ContentPosition::kNormal;
   }
 
   NOTREACHED();
-  return kContentPositionNormal;
+  return ContentPosition::kNormal;
 }
 
 static ContentAlignmentData ContentDistributionOffset(
@@ -2246,8 +2248,8 @@
     ContentPosition& fallback_position,
     ContentDistributionType distribution,
     unsigned number_of_grid_tracks) {
-  if (distribution != kContentDistributionDefault &&
-      fallback_position == kContentPositionNormal)
+  if (distribution != ContentDistributionType::kDefault &&
+      fallback_position == ContentPosition::kNormal)
     fallback_position = ResolveContentDistributionFallback(distribution);
 
   if (available_free_space <= 0)
@@ -2255,20 +2257,20 @@
 
   LayoutUnit distribution_offset;
   switch (distribution) {
-    case kContentDistributionSpaceBetween:
+    case ContentDistributionType::kSpaceBetween:
       if (number_of_grid_tracks < 2)
         return {};
       return {LayoutUnit(), available_free_space / (number_of_grid_tracks - 1)};
-    case kContentDistributionSpaceAround:
+    case ContentDistributionType::kSpaceAround:
       if (number_of_grid_tracks < 1)
         return {};
       distribution_offset = available_free_space / number_of_grid_tracks;
       return {distribution_offset / 2, distribution_offset};
-    case kContentDistributionSpaceEvenly:
+    case ContentDistributionType::kSpaceEvenly:
       distribution_offset = available_free_space / (number_of_grid_tracks + 1);
       return {distribution_offset, distribution_offset};
-    case kContentDistributionStretch:
-    case kContentDistributionDefault:
+    case ContentDistributionType::kStretch:
+    case ContentDistributionType::kDefault:
       return {};
   }
 
@@ -2308,34 +2310,34 @@
 
   bool is_row_axis = direction == kForColumns;
   switch (position) {
-    case kContentPositionLeft:
+    case ContentPosition::kLeft:
       // The align-content's axis is always orthogonal to the inline-axis.
       return {LayoutUnit(), LayoutUnit()};
-    case kContentPositionRight:
+    case ContentPosition::kRight:
       if (is_row_axis)
         return {available_free_space, LayoutUnit()};
       // The align-content's axis is always orthogonal to the inline-axis.
       return {LayoutUnit(), LayoutUnit()};
-    case kContentPositionCenter:
+    case ContentPosition::kCenter:
       return {available_free_space / 2, LayoutUnit()};
     // Only used in flex layout, for other layout, it's equivalent to 'End'.
-    case kContentPositionFlexEnd:
-    case kContentPositionEnd:
+    case ContentPosition::kFlexEnd:
+    case ContentPosition::kEnd:
       if (is_row_axis)
         return {StyleRef().IsLeftToRightDirection() ? available_free_space
                                                     : LayoutUnit(),
                 LayoutUnit()};
       return {available_free_space, LayoutUnit()};
     // Only used in flex layout, for other layout, it's equivalent to 'Start'.
-    case kContentPositionFlexStart:
-    case kContentPositionStart:
+    case ContentPosition::kFlexStart:
+    case ContentPosition::kStart:
       if (is_row_axis)
         return {StyleRef().IsLeftToRightDirection() ? LayoutUnit()
                                                     : available_free_space,
                 LayoutUnit()};
       return {LayoutUnit(), LayoutUnit()};
-    case kContentPositionBaseline:
-    case kContentPositionLastBaseline:
+    case ContentPosition::kBaseline:
+    case ContentPosition::kLastBaseline:
       // FIXME: These two require implementing Baseline Alignment. For now, we
       // always 'start' align the child. crbug.com/234191
       if (is_row_axis)
@@ -2343,7 +2345,7 @@
                                                     : available_free_space,
                 LayoutUnit()};
       return {LayoutUnit(), LayoutUnit()};
-    case kContentPositionNormal:
+    case ContentPosition::kNormal:
       break;
   }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 70c4d0f87..c67178c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -273,6 +273,14 @@
 void LayoutTable::UpdateLogicalWidth() {
   RecalcSectionsIfNeeded();
 
+  if (IsFlexItemIncludingDeprecated() || IsGridItem()) {
+    // TODO(jfernandez): Investigate whether the grid layout algorithm provides
+    // all the logic needed and that we're not skipping anything essential due
+    // to the early return here.
+    LayoutBlock::UpdateLogicalWidth();
+    return;
+  }
+
   if (IsOutOfFlowPositioned()) {
     LogicalExtentComputedValues computed_values;
     ComputePositionedLogicalWidth(computed_values);
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp
index 7ccb496..daa4c28 100644
--- a/third_party/WebKit/Source/core/layout/LayoutText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -570,9 +570,10 @@
   DCHECK(box);
   DCHECK_GE(offset, 0);
 
-  if (offset && static_cast<unsigned>(offset) < box->Len())
+  if (offset && static_cast<unsigned>(offset) < box->Len()) {
     return CreatePositionWithAffinityForBox(box, box->Start() + offset,
                                             should_affinity_be_downstream);
+  }
 
   bool position_is_at_start_of_box = !offset;
   if (position_is_at_start_of_box == box->IsLeftToRightDirection()) {
@@ -581,9 +582,10 @@
     const InlineBox* prev_box = box->PrevLeafChildIgnoringLineBreak();
     if ((prev_box && prev_box->BidiLevel() == box->BidiLevel()) ||
         box->GetLineLayoutItem().ContainingBlock().Style()->Direction() ==
-            box->Direction())  // FIXME: left on 12CBA
+            box->Direction()) {  // FIXME: left on 12CBA
       return CreatePositionWithAffinityForBox(box, box->CaretLeftmostOffset(),
                                               should_affinity_be_downstream);
+    }
 
     if (prev_box && prev_box->BidiLevel() > box->BidiLevel()) {
       // e.g. left of B in aDC12BAb
@@ -619,9 +621,10 @@
   const InlineBox* next_box = box->NextLeafChildIgnoringLineBreak();
   if ((next_box && next_box->BidiLevel() == box->BidiLevel()) ||
       box->GetLineLayoutItem().ContainingBlock().Style()->Direction() ==
-          box->Direction())
+          box->Direction()) {
     return CreatePositionWithAffinityForBox(box, box->CaretRightmostOffset(),
                                             should_affinity_be_downstream);
+  }
 
   // offset is on the right edge
   if (next_box && next_box->BidiLevel() > box->BidiLevel()) {
@@ -683,10 +686,11 @@
           (blocks_are_flipped && point_block_direction == bottom)) {
         ShouldAffinityBeDownstream should_affinity_be_downstream;
         if (LineDirectionPointFitsInBox(point_line_direction.ToInt(), box,
-                                        should_affinity_be_downstream))
+                                        should_affinity_be_downstream)) {
           return CreatePositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(
               box, box->OffsetForPosition(point_line_direction),
               should_affinity_be_downstream);
+        }
       }
     }
     last_box = box;
@@ -753,9 +757,10 @@
 
   // FIXME: should we use the width of the root inline box or the
   // width of the containing block for this?
-  if (extra_width_to_end_of_line)
+  if (extra_width_to_end_of_line) {
     *extra_width_to_end_of_line =
         (box->Root().LogicalWidth() + root_left) - (left + 1);
+  }
 
   LayoutBlock* cb = ContainingBlock();
   const ComputedStyle& cb_style = cb->StyleRef();
@@ -1239,11 +1244,12 @@
             static_cast<unsigned>(text_direction);
         DCHECK_GE(text_direction_index, 0U);
         DCHECK_LE(text_direction_index, 1U);
-        if (!cached_word_trailing_space_width[text_direction_index])
+        if (!cached_word_trailing_space_width[text_direction_index]) {
           cached_word_trailing_space_width[text_direction_index] =
               f.Width(ConstructTextRun(f, &kSpaceCharacter, 1, style_to_use,
                                        text_direction)) +
               word_spacing;
+        }
         word_trailing_space_width =
             cached_word_trailing_space_width[text_direction_index];
       }
@@ -1268,16 +1274,17 @@
                                  *hyphenation, i, word_len, suffix_start);
         if (suffix_start) {
           float suffix_width;
-          if (word_trailing_space_width && is_space)
+          if (word_trailing_space_width && is_space) {
             suffix_width =
                 WidthFromFont(f, i + suffix_start, word_len - suffix_start + 1,
                               lead_width, curr_max_width, text_direction,
                               &fallback_fonts, &glyph_bounds) -
                 word_trailing_space_width;
-          else
+          } else {
             suffix_width = WidthFromFont(
                 f, i + suffix_start, word_len - suffix_start, lead_width,
                 curr_max_width, text_direction, &fallback_fonts, &glyph_bounds);
+          }
           max_fragment_width = std::max(max_fragment_width, suffix_width);
           curr_min_width += max_fragment_width - w;
           max_word_width = std::max(max_word_width, max_fragment_width);
@@ -1297,12 +1304,13 @@
         curr_min_width += w;
       }
       if (between_words) {
-        if (last_word_boundary == i)
+        if (last_word_boundary == i) {
           curr_max_width += w;
-        else
+        } else {
           curr_max_width += WidthFromFont(
               f, last_word_boundary, j - last_word_boundary, lead_width,
               curr_max_width, text_direction, &fallback_fonts, &glyph_bounds);
+        }
         last_word_boundary = j;
       }
 
@@ -1656,9 +1664,10 @@
   // LayoutObjectChildList::insertChildNode() fails to set true to owner.
   // To avoid that, we call setNeedsLayoutAndPrefWidthsRecalc() only if this
   // LayoutText has parent.
-  if (Parent())
+  if (Parent()) {
     SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
         LayoutInvalidationReason::kTextChanged);
+  }
   known_to_have_no_overflow_and_no_fallback_fonts_ = false;
 
   if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
@@ -1763,13 +1772,14 @@
       if (fallback_fonts) {
         DCHECK(glyph_bounds);
         if (PreferredLogicalWidthsDirty() ||
-            !known_to_have_no_overflow_and_no_fallback_fonts_)
+            !known_to_have_no_overflow_and_no_fallback_fonts_) {
           const_cast<LayoutText*>(this)->ComputePreferredLogicalWidths(
               0, *fallback_fonts, *glyph_bounds);
-        else
+        } else {
           *glyph_bounds =
               FloatRect(0, -font_data->GetFontMetrics().FloatAscent(),
                         max_width_, font_data->GetFontMetrics().FloatHeight());
+        }
         w = max_width_;
       } else {
         w = MaxLogicalWidth();
@@ -2220,9 +2230,10 @@
   for (InlineTextBox* box : InlineTextBoxesOf(*this)) {
     paint_invalidator.InvalidateDisplayItemClient(*box, invalidation_reason);
     if (box->Truncation() != kCNoTruncation) {
-      if (EllipsisBox* ellipsis_box = box->Root().GetEllipsisBox())
+      if (EllipsisBox* ellipsis_box = box->Root().GetEllipsisBox()) {
         paint_invalidator.InvalidateDisplayItemClient(*ellipsis_box,
                                                       invalidation_reason);
+      }
     }
   }
 }
diff --git a/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp
index 36219acf..d8cd7f0 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp
@@ -119,9 +119,10 @@
 LayoutUnit InlineTextBox::LineHeight() const {
   if (!IsText() || !GetLineLayoutItem().Parent())
     return LayoutUnit();
-  if (GetLineLayoutItem().IsBR())
+  if (GetLineLayoutItem().IsBR()) {
     return LayoutUnit(
         LineLayoutBR(GetLineLayoutItem()).LineHeight(IsFirstLineStyle()));
+  }
   if (Parent()->GetLineLayoutItem() == GetLineLayoutItem().Parent())
     return Parent()->LineHeight();
   return LineLayoutBoxModel(GetLineLayoutItem().Parent())
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 6e8b0d66..6da3d8c8 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -593,7 +593,8 @@
         std::make_unique<NGExclusionSpace>(*initial_exclusion_space);
 
     NGLineInfo line_info;
-    NGLineBreaker line_breaker(Node(), constraint_space_, &positioned_floats,
+    NGLineBreaker line_breaker(Node(), NGLineBreakerMode::kContent,
+                               constraint_space_, &positioned_floats,
                                &unpositioned_floats_, exclusion_space.get(),
                                handled_item_index, break_token);
 
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
index 4cc6905..fc1b573 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
@@ -658,9 +658,11 @@
 }
 
 static LayoutUnit ComputeContentSize(NGInlineNode node,
-                                     LayoutUnit available_inline_size) {
+                                     NGLineBreakerMode mode) {
   const ComputedStyle& style = node.Style();
   WritingMode writing_mode = style.GetWritingMode();
+  LayoutUnit available_inline_size =
+      mode == NGLineBreakerMode::kMaxContent ? LayoutUnit::Max() : LayoutUnit();
 
   scoped_refptr<NGConstraintSpace> space =
       NGConstraintSpaceBuilder(
@@ -678,7 +680,9 @@
   NGExclusionSpace empty_exclusion_space;
   LayoutUnit result;
   while (!break_token || !break_token->IsFinished()) {
-    NGLineBreaker line_breaker(node, *space, &positioned_floats,
+    unpositioned_floats.clear();
+
+    NGLineBreaker line_breaker(node, mode, *space, &positioned_floats,
                                &unpositioned_floats, &empty_exclusion_space, 0u,
                                break_token.get());
     if (!line_breaker.NextLine(
@@ -692,7 +696,52 @@
     LayoutUnit inline_size = line_info.TextIndent();
     for (const NGInlineItemResult item_result : line_info.Results())
       inline_size += item_result.inline_size;
-    result = std::max(inline_size, result);
+
+    // There should be no positioned floats while determining the min/max sizes.
+    DCHECK_EQ(positioned_floats.size(), 0u);
+
+    // These variables are only used for the max-content calculation.
+    LayoutUnit floats_inline_size;
+    EFloat previous_float_type = EFloat::kNone;
+
+    for (const auto& unpositioned_float : unpositioned_floats) {
+      NGBlockNode float_node = unpositioned_float->node;
+      const ComputedStyle& float_style = float_node.Style();
+
+      Optional<MinMaxSize> child_minmax;
+      if (NeedMinMaxSizeForContentContribution(float_style)) {
+        child_minmax = float_node.ComputeMinMaxSize();
+      }
+
+      MinMaxSize child_sizes =
+          ComputeMinAndMaxContentContribution(float_style, child_minmax);
+      LayoutUnit child_inline_margins =
+          ComputeMinMaxMargins(style, float_node).InlineSum();
+
+      if (mode == NGLineBreakerMode::kMinContent) {
+        result = std::max(result, child_sizes.min_size + child_inline_margins);
+      } else {
+        const EClear float_clear = float_style.Clear();
+
+        // If this float clears the previous float we start a new "line".
+        // This is subtly different to block layout which will only reset either
+        // the left or the right float size trackers.
+        if ((previous_float_type == EFloat::kLeft &&
+             (float_clear == EClear::kBoth || float_clear == EClear::kLeft)) ||
+            (previous_float_type == EFloat::kRight &&
+             (float_clear == EClear::kBoth || float_clear == EClear::kRight))) {
+          result = std::max(result, inline_size + floats_inline_size);
+          floats_inline_size = LayoutUnit();
+        }
+
+        floats_inline_size += child_sizes.max_size + child_inline_margins;
+        previous_float_type = float_style.Floating();
+      }
+    }
+
+    // NOTE: floats_inline_size will be zero for the min-content calculation,
+    // and will just take the inline size of the un-breakable line.
+    result = std::max(result, inline_size + floats_inline_size);
   }
 
   return result;
@@ -710,13 +759,13 @@
   // size. This gives the min-content, the width where lines wrap at every
   // break opportunity.
   MinMaxSize sizes;
-  sizes.min_size = ComputeContentSize(*this, LayoutUnit());
+  sizes.min_size = ComputeContentSize(*this, NGLineBreakerMode::kMinContent);
 
   // Compute the sum of inline sizes of all inline boxes with no line breaks.
   // TODO(kojii): NGConstraintSpaceBuilder does not allow NGSizeIndefinite
   // inline available size. We can allow it, or make this more efficient
   // without using NGLineBreaker.
-  sizes.max_size = ComputeContentSize(*this, LayoutUnit::Max());
+  sizes.max_size = ComputeContentSize(*this, NGLineBreakerMode::kMaxContent);
 
   // Negative text-indent can make min > max. Ensure min is the minimum size.
   sizes.min_size = std::min(sizes.min_size, sizes.max_size);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
index 6ec8178..ffda6d1 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
@@ -354,6 +354,43 @@
   EXPECT_EQ(60, sizes.max_size);
 }
 
+TEST_F(NGInlineNodeTest, MinMaxSizeFloats) {
+  LoadAhem();
+  SetupHtml("t", R"HTML(
+    <style>
+      #left { float: left; width: 50px; }
+    </style>
+    <div id=t style="font: 10px Ahem">
+      XXX <div id="left"></div> XXXX
+    </div>
+  )HTML");
+
+  NGInlineNodeForTest node = CreateInlineNode();
+  MinMaxSize sizes = node.ComputeMinMaxSize();
+
+  EXPECT_EQ(50, sizes.min_size);
+  EXPECT_EQ(130, sizes.max_size);
+}
+
+TEST_F(NGInlineNodeTest, MinMaxSizeFloatsClearance) {
+  LoadAhem();
+  SetupHtml("t", R"HTML(
+    <style>
+      #left { float: left; width: 40px; }
+      #right { float: right; clear: left; width: 50px; }
+    </style>
+    <div id=t style="font: 10px Ahem">
+      XXX <div id="left"></div><div id="right"></div><div id="left"></div> XXX
+    </div>
+  )HTML");
+
+  NGInlineNodeForTest node = CreateInlineNode();
+  MinMaxSize sizes = node.ComputeMinMaxSize();
+
+  EXPECT_EQ(50, sizes.min_size);
+  EXPECT_EQ(160, sizes.max_size);
+}
+
 TEST_F(NGInlineNodeTest, InvalidateAddSpan) {
   SetupHtml("t", "<div id=t>before</div>");
   EXPECT_FALSE(layout_block_flow_->NeedsCollectInlines());
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
index bb609fb..e72ab18a 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
@@ -20,6 +20,7 @@
 
 NGLineBreaker::NGLineBreaker(
     NGInlineNode node,
+    NGLineBreakerMode mode,
     const NGConstraintSpace& space,
     Vector<NGPositionedFloat>* positioned_floats,
     Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats,
@@ -27,6 +28,7 @@
     unsigned handled_float_index,
     const NGInlineBreakToken* break_token)
     : node_(node),
+      mode_(mode),
       constraint_space_(space),
       positioned_floats_(positioned_floats),
       unpositioned_floats_(unpositioned_floats),
@@ -511,11 +513,15 @@
   //  - It can't fit.
   //  - It will be moved down due to block-start edge alignment.
   //  - It will be moved down due to clearance.
+  //  - We are currently computing our min/max-content size. (We use the
+  //    unpositioned_floats to manually adjust the min/max-content size after
+  //    the line breaker has run).
   bool float_after_line =
       !line_.CanFit(inline_margin_size) ||
       exclusion_space_->LastFloatBlockStart() > bfc_block_offset_ ||
       exclusion_space_->ClearanceOffset(float_style.Clear()) >
-          bfc_block_offset_;
+          bfc_block_offset_ ||
+      mode_ != NGLineBreakerMode::kContent;
 
   // Check if we already have a pending float. That's because a float cannot be
   // higher than any block or floated box generated before.
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h
index 7a89b00..cfa3db0e 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h
@@ -22,6 +22,9 @@
 class NGInlineLayoutStateStack;
 struct NGPositionedFloat;
 
+// The line breaker needs to know which mode its in to properly handle floats.
+enum class NGLineBreakerMode { kContent, kMinContent, kMaxContent };
+
 // Represents a line breaker.
 //
 // This class measures each NGInlineItem and determines items to form a line,
@@ -31,6 +34,7 @@
 
  public:
   NGLineBreaker(NGInlineNode,
+                NGLineBreakerMode,
                 const NGConstraintSpace&,
                 Vector<NGPositionedFloat>*,
                 Vector<scoped_refptr<NGUnpositionedFloat>>*,
@@ -140,6 +144,7 @@
 
   LineData line_;
   NGInlineNode node_;
+  NGLineBreakerMode mode_;
   const NGConstraintSpace& constraint_space_;
   Vector<NGPositionedFloat>* positioned_floats_;
   Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats_;
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
index 8048cee..5791d9a 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -48,9 +48,9 @@
     NGExclusionSpace exclusion_space;
     NGLineInfo line_info;
     while (!break_token || !break_token->IsFinished()) {
-      NGLineBreaker line_breaker(node, *space, &positioned_floats,
-                                 &unpositioned_floats, &exclusion_space, 0u,
-                                 break_token.get());
+      NGLineBreaker line_breaker(node, NGLineBreakerMode::kContent, *space,
+                                 &positioned_floats, &unpositioned_floats,
+                                 &exclusion_space, 0u, break_token.get());
       if (!line_breaker.NextLine(
               NGLayoutOpportunity(
                   NGBfcOffset(),
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc
index c470d11b..205bc2b73 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.cc
@@ -40,8 +40,15 @@
   return {*position.AnchorNode(), 1};
 }
 
-// TODO(xiaochengh): Expose it properly as a utility function.
-const LayoutObject* NGInlineFormattingContextOf(const Position& position) {
+// TODO(xiaochengh): Introduce predicates for comparing Position and
+// NGOffsetMappingUnit, to reduce position-offset conversion and ad-hoc
+// predicates below.
+
+}  // namespace
+
+const LayoutBlockFlow* NGInlineFormattingContextOf(const Position& position) {
+  if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+    return nullptr;
   if (!NGOffsetMapping::AcceptsPosition(position))
     return nullptr;
   const auto node_offset_pair = ToNodeOffsetPair(position);
@@ -57,11 +64,10 @@
   return layout_object->EnclosingNGBlockFlow();
 }
 
-// TODO(xiaochengh): Introduce predicates for comparing Position and
-// NGOffsetMappingUnit, to reduce position-offset conversion and ad-hoc
-// predicates below.
-
-}  // namespace
+const LayoutBlockFlow* NGInlineFormattingContextOf(
+    const PositionInFlatTree& position) {
+  return NGInlineFormattingContextOf(ToPositionInDOMTree(position));
+}
 
 NGOffsetMappingUnit::NGOffsetMappingUnit(NGOffsetMappingUnitType type,
                                          const Node& node,
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h
index eb19cb3..6d239f9 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping.h
@@ -16,6 +16,7 @@
 
 namespace blink {
 
+class LayoutBlockFlow;
 class LayoutObject;
 class Node;
 
@@ -185,6 +186,9 @@
   DISALLOW_COPY_AND_ASSIGN(NGOffsetMapping);
 };
 
+CORE_EXPORT const LayoutBlockFlow* NGInlineFormattingContextOf(const Position&);
+const LayoutBlockFlow* NGInlineFormattingContextOf(const PositionInFlatTree&);
+
 }  // namespace blink
 
 #endif  // NGOffsetMapping_h
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc
index 0923b114..e3594d9 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_offset_mapping_test.cc
@@ -121,6 +121,43 @@
   EXPECT_TRUE(IsOffsetMappingStored());
 }
 
+TEST_P(ParameterizedNGOffsetMappingTest, NGInlineFormattingContextOf) {
+  SetBodyInnerHTML(
+      "<div id=container>"
+      "  foo"
+      "  <span id=inline-block style='display:inline-block'>blah</span>"
+      "  <span id=inline-span>bar</span>"
+      "</div>");
+
+  const Element* container = GetElementById("container");
+  const Element* inline_block = GetElementById("inline-block");
+  const Element* inline_span = GetElementById("inline-span");
+  const Node* blah = inline_block->firstChild();
+  const Node* foo = inline_block->previousSibling();
+  const Node* bar = inline_span->firstChild();
+
+  EXPECT_EQ(nullptr,
+            NGInlineFormattingContextOf(Position::BeforeNode(*container)));
+  EXPECT_EQ(nullptr,
+            NGInlineFormattingContextOf(Position::AfterNode(*container)));
+
+  const LayoutObject* container_object = container->GetLayoutObject();
+  EXPECT_EQ(container_object, NGInlineFormattingContextOf(Position(foo, 0)));
+  EXPECT_EQ(container_object, NGInlineFormattingContextOf(Position(bar, 0)));
+  EXPECT_EQ(container_object,
+            NGInlineFormattingContextOf(Position::BeforeNode(*inline_block)));
+  EXPECT_EQ(container_object,
+            NGInlineFormattingContextOf(Position::AfterNode(*inline_block)));
+  EXPECT_EQ(container_object,
+            NGInlineFormattingContextOf(Position::BeforeNode(*inline_span)));
+  EXPECT_EQ(container_object,
+            NGInlineFormattingContextOf(Position::AfterNode(*inline_span)));
+
+  const LayoutObject* inline_block_object = inline_block->GetLayoutObject();
+  EXPECT_EQ(inline_block_object,
+            NGInlineFormattingContextOf(Position(blah, 0)));
+}
+
 TEST_P(ParameterizedNGOffsetMappingTest, OneTextNode) {
   SetupHtml("t", "<div id=t>foo</div>");
   const Node* foo_node = layout_object_->GetNode();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
index 31265bb..b8a57fe 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -138,8 +138,14 @@
         layout_box.SetLocation(child_offset.ToLayoutPoint());
       }
 
-      CopyFragmentDataToLayoutBoxForInlineChildren(
-          ToNGPhysicalContainerFragment(*child), child_offset);
+      // The Location() of inline LayoutObject is relative to the
+      // LayoutBlockFlow. If |child| is a block layout root (e.g., inline block,
+      // float, etc.), it creates another inline formatting context. Do not copy
+      // to its descendants in this case.
+      if (!child->IsBlockLayoutRoot()) {
+        CopyFragmentDataToLayoutBoxForInlineChildren(
+            ToNGPhysicalContainerFragment(*child), child_offset);
+      }
     }
   }
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_container_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_container_fragment_builder.cc
index b5b92b0..e84b800 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_container_fragment_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_container_fragment_builder.cc
@@ -128,6 +128,9 @@
     TextDirection line_direction,
     LayoutObject* inline_container) {
   DCHECK(child);
+  // Fixed positioned children are never placed inside inline container.
+  if (child.Style().GetPosition() == EPosition::kFixed)
+    inline_container = nullptr;
   oof_positioned_candidates_.push_back(NGOutOfFlowPositionedCandidate(
       NGOutOfFlowPositionedDescendant(
           child,
@@ -168,8 +171,9 @@
     builder_relative_position.offset =
         child_offset + candidate.descendant.static_position.offset;
 
-    descendant_candidates->push_back(NGOutOfFlowPositionedDescendant{
-        candidate.descendant.node, builder_relative_position});
+    descendant_candidates->push_back(NGOutOfFlowPositionedDescendant(
+        candidate.descendant.node, builder_relative_position,
+        candidate.descendant.inline_container));
   }
 
   // Clear our current canidate list. This may get modified again if the
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
index 1c8dcd8..658a46ba 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -5,6 +5,8 @@
 #include "core/layout/ng/ng_fragment_builder.h"
 
 #include "core/layout/LayoutObject.h"
+#include "core/layout/ng/inline/ng_inline_fragment_iterator.h"
+#include "core/layout/ng/inline/ng_physical_line_box_fragment.h"
 #include "core/layout/ng/ng_block_break_token.h"
 #include "core/layout/ng/ng_block_node.h"
 #include "core/layout/ng/ng_break_token.h"
@@ -217,4 +219,54 @@
                          end_margin_strut_, LayoutUnit(), status));
 }
 
+// Finds FragmentPairs that define inline containing blocks.
+// inline_container_fragments is a map whose keys specify which
+// inline containing blocks are required.
+// Not finding a required block is an unexpected behavior (DCHECK).
+void NGFragmentBuilder::ComputeInlineContainerFragments(
+    HashMap<const LayoutObject*, FragmentPair>* inline_container_fragments,
+    NGLogicalSize* container_size) {
+  // This function has detailed knowledge of inline fragment tree structure,
+  // and will break if this changes.
+  DCHECK_GE(inline_size_, LayoutUnit());
+  DCHECK_GE(block_size_, LayoutUnit());
+  container_size->inline_size = inline_size_;
+  container_size->block_size = block_size_;
+
+  for (size_t i = 0; i < children_.size(); i++) {
+    if (children_[i]->IsLineBox()) {
+      const NGPhysicalLineBoxFragment* linebox =
+          ToNGPhysicalLineBoxFragment(children_[i].get());
+      for (auto& descendant :
+           NGInlineFragmentTraversal::DescendantsOf(*linebox)) {
+        LayoutObject* key = {};
+        if (descendant.fragment->IsText()) {
+          key = descendant.fragment->GetLayoutObject();
+          DCHECK(key);
+          key = key->Parent();
+          DCHECK(key);
+        } else if (descendant.fragment->IsBox()) {
+          key = descendant.fragment->GetLayoutObject();
+        }
+        if (key && inline_container_fragments->Contains(key)) {
+          NGFragmentBuilder::FragmentPair value =
+              inline_container_fragments->at(key);
+          if (!value.start_fragment) {
+            value.start_fragment = descendant.fragment;
+            value.start_fragment_offset = descendant.offset_to_container_box;
+            value.start_linebox_fragment = linebox;
+            value.start_linebox_offset = offsets_.at(i);
+          }
+          value.end_fragment = descendant.fragment;
+          value.end_fragment_offset = descendant.offset_to_container_box;
+          value.end_linebox_fragment = linebox;
+          value.end_linebox_offset = offsets_.at(i);
+          inline_container_fragments->Set(key, value);
+        }
+      }
+    }
+  }
+  // TODO(atotic) need to implement correct RTL handling.
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
index dba464a..63c17960 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
@@ -18,6 +18,7 @@
 namespace blink {
 
 class NGPhysicalFragment;
+class NGPhysicalLineBoxFragment;
 
 class CORE_EXPORT NGFragmentBuilder final : public NGContainerFragmentBuilder {
   DISALLOW_NEW();
@@ -106,6 +107,30 @@
   // type pair.
   void AddBaseline(NGBaselineRequest, LayoutUnit);
 
+  // Inline containing block geometry is defined by two fragments:
+  // start and end. FragmentPair holds the information needed to compute
+  // inline containing block geometry wrt enclosing container block.
+  //
+  // start_fragment is the start fragment of inline containing block.
+  // start_fragment_offset is offset wrt start_linebox_fragment
+  // start_linebox_offset is offset of linebox from inline-cb
+  // end_fragment/linebox are complementary properties for end fragment.
+  struct FragmentPair {
+    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+    const NGPhysicalLineBoxFragment* start_linebox_fragment;
+    NGLogicalOffset start_linebox_offset;
+    const NGPhysicalFragment* start_fragment;
+    NGPhysicalOffset start_fragment_offset;
+    const NGPhysicalLineBoxFragment* end_linebox_fragment;
+    NGLogicalOffset end_linebox_offset;
+    const NGPhysicalFragment* end_fragment;
+    NGPhysicalOffset end_fragment_offset;
+  };
+
+  void ComputeInlineContainerFragments(
+      HashMap<const LayoutObject*, FragmentPair>* inline_container_fragments,
+      NGLogicalSize* container_size);
+
  private:
   NGLayoutInputNode node_;
   LayoutObject* layout_object_;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 6f833f9..50a4255 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -194,7 +194,6 @@
       const ContentSecurityPolicy* content_security_policy,
       KURL site_for_cookies,
       scoped_refptr<const SecurityOrigin> requestor_origin,
-      scoped_refptr<const SecurityOrigin> requestor_origin_for_frame_loading,
       const ClientHintsPreferences& client_hints_preferences,
       float device_pixel_ratio,
       const String& user_agent,
@@ -209,7 +208,6 @@
         content_security_policy(content_security_policy),
         site_for_cookies(site_for_cookies),
         requestor_origin(requestor_origin),
-        requestor_origin_for_frame_loading(requestor_origin_for_frame_loading),
         client_hints_preferences(client_hints_preferences),
         device_pixel_ratio(device_pixel_ratio),
         user_agent(user_agent),
@@ -225,7 +223,6 @@
   const Member<const ContentSecurityPolicy> content_security_policy;
   const KURL site_for_cookies;
   const scoped_refptr<const SecurityOrigin> requestor_origin;
-  const scoped_refptr<const SecurityOrigin> requestor_origin_for_frame_loading;
   const ClientHintsPreferences client_hints_preferences;
   const float device_pixel_ratio;
   const String user_agent;
@@ -902,18 +899,15 @@
     }
   }
 
-  // Subresource requests inherit their requestor origin from |document_|
-  // directly.  Top-level frame types are taken care of in 'FrameLoadRequest()'.
-  // Auxiliary frame types in 'CreateWindow()' and 'FrameLoader::Load'.
-  if (!request.RequestorOrigin()) {
-    if (request.GetFrameType() == WebURLRequest::kFrameTypeNone) {
+  // * For subresources, the initiator origin is the origin of the
+  //   |document_| that contains them.
+  // * For loading a new document in the frame, the initiator is not set here.
+  //   In most of the cases, it is set in the FrameLoadRequest constructor.
+  //   Otherwise, it must be set immediately after the request has been created.
+  //   See the calls to ResourceRequest::SetRequestorOrigin().
+  if (request.GetFrameType() == WebURLRequest::kFrameTypeNone) {
+    if (!request.RequestorOrigin())
       request.SetRequestorOrigin(GetRequestorOrigin());
-    } else {
-      // Set the requestor origin to the same origin as the frame's document
-      // if it hasn't yet been set. (We may hit here for nested frames and
-      // redirect cases)
-      request.SetRequestorOrigin(GetRequestorOriginForFrameLoading());
-    }
   }
 }
 
@@ -1133,14 +1127,6 @@
   return GetSecurityOrigin();
 }
 
-scoped_refptr<const SecurityOrigin>
-FrameFetchContext::GetRequestorOriginForFrameLoading() {
-  if (IsDetached())
-    return frozen_state_->requestor_origin;
-
-  return GetFrame()->GetDocument()->GetSecurityOrigin();
-}
-
 ClientHintsPreferences FrameFetchContext::GetClientHintsPreferences() const {
   if (IsDetached())
     return frozen_state_->client_hints_preferences;
@@ -1221,18 +1207,17 @@
         GetReferrerPolicy(), GetOutgoingReferrer(), Url(), GetSecurityOrigin(),
         GetParentSecurityOrigin(), GetAddressSpace(),
         GetContentSecurityPolicy(), GetSiteForCookies(), GetRequestorOrigin(),
-        GetRequestorOriginForFrameLoading(), GetClientHintsPreferences(),
-        GetDevicePixelRatio(), GetUserAgent(), IsMainFrame(),
-        IsSVGImageChromeClient());
+        GetClientHintsPreferences(), GetDevicePixelRatio(), GetUserAgent(),
+        IsMainFrame(), IsSVGImageChromeClient());
   } else {
     // Some getters are unavailable in this case.
     frozen_state_ = new FrozenState(
         kReferrerPolicyDefault, String(), NullURL(), GetSecurityOrigin(),
         GetParentSecurityOrigin(), GetAddressSpace(),
         GetContentSecurityPolicy(), GetSiteForCookies(),
-        SecurityOrigin::CreateUnique(), SecurityOrigin::CreateUnique(),
-        GetClientHintsPreferences(), GetDevicePixelRatio(), GetUserAgent(),
-        IsMainFrame(), IsSVGImageChromeClient());
+        SecurityOrigin::CreateUnique(), GetClientHintsPreferences(),
+        GetDevicePixelRatio(), GetUserAgent(), IsMainFrame(),
+        IsSVGImageChromeClient());
   }
 
   // This is needed to break a reference cycle in which off-heap
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.h b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
index b0ba616..4c366a9a34 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.h
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
@@ -224,7 +224,6 @@
   Settings* GetSettings() const;
   String GetUserAgent() const;
   scoped_refptr<const SecurityOrigin> GetRequestorOrigin();
-  scoped_refptr<const SecurityOrigin> GetRequestorOriginForFrameLoading();
   ClientHintsPreferences GetClientHintsPreferences() const;
   float GetDevicePixelRatio() const;
   bool ShouldSendClientHint(mojom::WebClientHintsType,
diff --git a/third_party/WebKit/Source/core/loader/FrameLoadRequest.cpp b/third_party/WebKit/Source/core/loader/FrameLoadRequest.cpp
index dd0e5b8d..c228750 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoadRequest.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoadRequest.cpp
@@ -90,25 +90,9 @@
       WebURLRequest::kFetchRedirectModeManual);
 
   if (origin_document) {
+    DCHECK(!resource_request_.RequestorOrigin());
     resource_request_.SetRequestorOrigin(
         SecurityOrigin::Create(origin_document->Url()));
-    return;
-  }
-
-  // If we don't have an origin document, and we're going to throw away the
-  // response data regardless, set the requestor to a unique origin.
-  if (substitute_data_.IsValid()) {
-    resource_request_.SetRequestorOrigin(SecurityOrigin::CreateUnique());
-    return;
-  }
-
-  // If we're dealing with a top-level request, use the origin of the requested
-  // URL as the initiator.
-  // TODO(mkwst): This should be `nullptr`. https://crbug.com/625969
-  if (resource_request_.GetFrameType() == WebURLRequest::kFrameTypeTopLevel) {
-    resource_request_.SetRequestorOrigin(
-        SecurityOrigin::Create(resource_request.Url()));
-    return;
   }
 }
 
diff --git a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
index 76781d7..0d8685d 100644
--- a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
+++ b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
@@ -250,6 +250,8 @@
     if (resource_request.IsNull())
       return;
     FrameLoadRequest request = FrameLoadRequest(nullptr, resource_request);
+    request.GetResourceRequest().SetRequestorOrigin(
+        SecurityOrigin::Create(resource_request.Url()));
     request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect);
     MaybeLogScheduledNavigationClobber(
         ScheduledNavigationType::kScheduledReload, frame);
@@ -265,8 +267,14 @@
 
  private:
   explicit ScheduledReload(LocalFrame* frame)
-      : ScheduledNavigation(Reason::kReload, 0.0, nullptr, true, true),
-        frame_(frame) {}
+      : ScheduledNavigation(Reason::kReload,
+                            0.0,
+                            nullptr /*origin_document */,
+                            true,
+                            true),
+        frame_(frame) {
+    DCHECK(frame->GetDocument());
+  }
 
   Member<LocalFrame> frame_;
 };
diff --git a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp
index f0a198d..00db69e 100644
--- a/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp
@@ -178,7 +178,6 @@
       std::make_unique<MainThreadWorkletReportingProxy>(&GetDocument());
   auto creation_params = std::make_unique<GlobalScopeCreationParams>(
       GetDocument().Url(), GetDocument().UserAgent(),
-      String() /* source_code */, nullptr /* cached_meta_data */,
       nullptr /* content_security_policy_parsed_headers */,
       GetDocument().GetReferrerPolicy(), GetDocument().GetSecurityOrigin(),
       nullptr /* worker_clients */, GetDocument().AddressSpace(),
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h
index 2fa41413..c65fefc 100644
--- a/third_party/WebKit/Source/core/page/ChromeClient.h
+++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -348,7 +348,7 @@
 
   virtual void RequestDecode(LocalFrame*,
                              const PaintImage& image,
-                             WTF::Function<void(bool)> callback) {
+                             base::OnceCallback<void(bool)> callback) {
     std::move(callback).Run(false);
   }
 
diff --git a/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp b/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp
index 129f3f1..61a5487 100644
--- a/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/core/page/ChromeClientImpl.cpp
@@ -833,7 +833,7 @@
 
 void ChromeClientImpl::RequestDecode(LocalFrame* frame,
                                      const PaintImage& image,
-                                     WTF::Function<void(bool)> callback) {
+                                     base::OnceCallback<void(bool)> callback) {
   WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
   web_frame->LocalRoot()->FrameWidget()->RequestDecode(image,
                                                        std::move(callback));
diff --git a/third_party/WebKit/Source/core/page/ChromeClientImpl.h b/third_party/WebKit/Source/core/page/ChromeClientImpl.h
index cf7157d3..158cde4 100644
--- a/third_party/WebKit/Source/core/page/ChromeClientImpl.h
+++ b/third_party/WebKit/Source/core/page/ChromeClientImpl.h
@@ -232,7 +232,7 @@
 
   void RequestDecode(LocalFrame*,
                      const PaintImage&,
-                     WTF::Function<void(bool)> callback) override;
+                     base::OnceCallback<void(bool)>) override;
 
  private:
   explicit ChromeClientImpl(WebViewImpl*);
diff --git a/third_party/WebKit/Source/core/page/CreateWindow.cpp b/third_party/WebKit/Source/core/page/CreateWindow.cpp
index 6235462..9a46b80 100644
--- a/third_party/WebKit/Source/core/page/CreateWindow.cpp
+++ b/third_party/WebKit/Source/core/page/CreateWindow.cpp
@@ -437,8 +437,6 @@
                                                             : kMaybeSetOpener);
   frame_request.GetResourceRequest().SetFrameType(
       WebURLRequest::kFrameTypeAuxiliary);
-  frame_request.GetResourceRequest().SetRequestorOrigin(
-      SecurityOrigin::Create(active_frame->GetDocument()->Url()));
 
   // Normally, FrameLoader would take care of setting the referrer for a
   // navigation that is triggered from javascript. However, creating a window
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index d4db485..3fc8cf0 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -293,8 +293,12 @@
 
   if (OperationForLoad(drag_data, local_root) != kDragOperationNone) {
     if (page_->GetSettings().GetNavigateOnDragDrop()) {
-      page_->MainFrame()->Navigate(
-          FrameLoadRequest(nullptr, ResourceRequest(drag_data->AsURL())));
+      ResourceRequest resource_request(drag_data->AsURL());
+      // TODO(mkwst): Perhaps this should use a unique origin as the requestor
+      // origin rather than the origin of the dragged data URL?
+      resource_request.SetRequestorOrigin(
+          SecurityOrigin::Create(KURL(drag_data->AsURL())));
+      page_->MainFrame()->Navigate(FrameLoadRequest(nullptr, resource_request));
     }
 
     // TODO(bokan): This case happens when we end a URL drag inside a guest
diff --git a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
index 71e31cfb..8f2a515 100644
--- a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
@@ -324,8 +324,11 @@
           FilterEffect* filter_effect = reference_filter->LastEffect();
           current_interpolation_space =
               filter_effect->OperatingInterpolationSpace();
-          filters.AppendReferenceFilter(PaintFilterBuilder::Build(
-              filter_effect, current_interpolation_space));
+          auto paint_filter = PaintFilterBuilder::Build(
+              filter_effect, current_interpolation_space);
+          if (!paint_filter)
+            continue;
+          filters.AppendReferenceFilter(std::move(paint_filter));
         }
         reference_operation.SetFilter(reference_filter);
         break;
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
index d261a3e..f8d8657 100644
--- a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
@@ -84,7 +84,12 @@
     if (!cross_composited_scrollers && layer->NeedsCompositedScrolling())
       break;
 
-    if (layer->GetLayoutObject().HasOverflowClip() &&
+    // Collect clips for embedded content despite their lack of overflow,
+    // because in practice they do need to clip. However, the clip is only
+    // used when painting child clipping masks to avoid clipping out border
+    // decorations.
+    if ((layer->GetLayoutObject().HasOverflowClip() ||
+         layer->GetLayoutObject().IsLayoutEmbeddedContent()) &&
         layer->GetLayoutObject().Style()->HasBorderRadius() &&
         InContainingBlockChain(&paint_layer, layer)) {
       LayoutPoint delta;
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
index d35f4863..27c5b478c 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -21,12 +21,18 @@
                         PaintControllerPaintTest,
                         ::testing::ValuesIn(kDefaultPaintTestConfigurations));
 
-using PaintControllerPaintTestForSlimmingPaintV2 = PaintControllerPaintTest;
+using PaintControllerPaintTestForSPv2 = PaintControllerPaintTest;
 INSTANTIATE_TEST_CASE_P(
     All,
-    PaintControllerPaintTestForSlimmingPaintV2,
+    PaintControllerPaintTestForSPv2,
     ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
 
+using PaintControllerPaintTestForNonSPv1 = PaintControllerPaintTest;
+INSTANTIATE_TEST_CASE_P(
+    All,
+    PaintControllerPaintTestForNonSPv1,
+    ::testing::ValuesIn(kSlimmingPaintNonV1TestConfigurations));
+
 TEST_P(PaintControllerPaintTest, FullDocumentPaintingWithCaret) {
   SetBodyInnerHTML(
       "<div id='div' contentEditable='true' style='outline:none'>XYZ</div>");
@@ -35,20 +41,9 @@
   Element& div = *ToElement(GetDocument().body()->firstChild());
   InlineTextBox& text_inline_box =
       *ToLayoutText(div.firstChild()->GetLayoutObject())->FirstTextBox();
-
-  DisplayItemClient* background_client = nullptr;
-  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
-      RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    // With SPv1 and RLS, the document background uses the scrolling contents
-    // layer as its DisplayItemClient.
-    background_client = GetLayoutView().Layer()->GraphicsLayerBacking();
-  } else {
-    background_client = &GetLayoutView();
-  }
-
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 2,
-      TestDisplayItem(*background_client, kDocumentBackgroundType),
+      TestDisplayItem(ViewBackgroundClient(), kDocumentBackgroundType),
       TestDisplayItem(text_inline_box, kForegroundType));
 
   div.focus();
@@ -56,7 +51,7 @@
 
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 3,
-      TestDisplayItem(*background_client, kDocumentBackgroundType),
+      TestDisplayItem(ViewBackgroundClient(), kDocumentBackgroundType),
       TestDisplayItem(text_inline_box, kForegroundType),
       TestDisplayItem(CaretDisplayItemClientForTesting(),
                       DisplayItem::kCaret));  // New!
@@ -72,19 +67,9 @@
   LayoutText& text = *ToLayoutText(div_block.FirstChild());
   InlineTextBox& first_text_box = *text.FirstTextBox();
 
-  DisplayItemClient* background_client = nullptr;
-  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
-      RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    // With SPv1 and RLS, the document background uses the scrolling contents
-    // layer as its DisplayItemClient.
-    background_client = GetLayoutView().Layer()->GraphicsLayerBacking();
-  } else {
-    background_client = &GetLayoutView();
-  }
-
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 2,
-      TestDisplayItem(*background_client, kDocumentBackgroundType),
+      TestDisplayItem(ViewBackgroundClient(), kDocumentBackgroundType),
       TestDisplayItem(first_text_box, kForegroundType));
 
   div.setAttribute(HTMLNames::styleAttr, "width: 10px; height: 200px");
@@ -96,12 +81,12 @@
 
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 3,
-      TestDisplayItem(*background_client, kDocumentBackgroundType),
+      TestDisplayItem(ViewBackgroundClient(), kDocumentBackgroundType),
       TestDisplayItem(new_first_text_box, kForegroundType),
       TestDisplayItem(second_text_box, kForegroundType));
 }
 
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2, ChunkIdClientCacheFlag) {
+TEST_P(PaintControllerPaintTestForNonSPv1, ChunkIdClientCacheFlag) {
   SetBodyInnerHTML(R"HTML(
     <div id='div' style='width: 200px; height: 200px; opacity: 0.5'>
       <div style='width: 100px; height: 100px; background-color:
@@ -113,10 +98,12 @@
   LayoutBlock& div = *ToLayoutBlock(GetLayoutObjectByElementId("div"));
   LayoutObject& sub_div = *div.FirstChild();
   LayoutObject& sub_div2 = *sub_div.NextSibling();
-  EXPECT_DISPLAY_LIST(RootPaintController().GetDisplayItemList(), 3,
-                      TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
-                      TestDisplayItem(sub_div, kBackgroundType),
-                      TestDisplayItem(sub_div2, kBackgroundType));
+
+  EXPECT_DISPLAY_LIST(
+      RootPaintController().GetDisplayItemList(), 3,
+      TestDisplayItem(ViewBackgroundClient(), kDocumentBackgroundType),
+      TestDisplayItem(sub_div, kBackgroundType),
+      TestDisplayItem(sub_div2, kBackgroundType));
 
   // Verify that the background does not scroll.
   const PaintChunk& background_chunk = RootPaintController().PaintChunks()[0];
@@ -139,7 +126,7 @@
   EXPECT_TRUE(RootPaintController().ClientCacheIsValid(sub_div));
 }
 
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2, CompositingNoFold) {
+TEST_P(PaintControllerPaintTestForNonSPv1, CompositingNoFold) {
   SetBodyInnerHTML(R"HTML(
     <div id='div' style='width: 200px; height: 200px; opacity: 0.5'>
       <div style='width: 100px; height: 100px; background-color:
@@ -149,17 +136,13 @@
   LayoutBlock& div = *ToLayoutBlock(GetLayoutObjectByElementId("div"));
   LayoutObject& sub_div = *div.FirstChild();
 
-  EXPECT_DISPLAY_LIST(RootPaintController().GetDisplayItemList(), 2,
-                      TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
-                      TestDisplayItem(sub_div, kBackgroundType));
+  EXPECT_DISPLAY_LIST(
+      RootPaintController().GetDisplayItemList(), 2,
+      TestDisplayItem(ViewBackgroundClient(), kDocumentBackgroundType),
+      TestDisplayItem(sub_div, kBackgroundType));
 }
 
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2, FrameScrollingContents) {
-  // TODO(wangxianzhu): Fix cull rect issue when painting layered contents
-  // under overflow clip (in this case the LayoutView).
-  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled())
-    return;
-
+TEST_P(PaintControllerPaintTestForSPv2, FrameScrollingContents) {
   SetBodyInnerHTML(R"HTML(
     <style>
       ::-webkit-scrollbar { display: none }
@@ -178,30 +161,48 @@
   auto& div3 = *GetLayoutObjectByElementId("div3");
   auto& div4 = *GetLayoutObjectByElementId("div4");
 
-  // Initial cull rect: (0,0 4800x4600)
-  EXPECT_DISPLAY_LIST(RootPaintController().GetDisplayItemList(), 4,
-                      TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
-                      TestDisplayItem(GetLayoutView(), kScrollHitTestType),
-                      TestDisplayItem(div1, kBackgroundType),
-                      TestDisplayItem(div2, kBackgroundType));
+  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
+    // TODO(crbug.com/792577): Cull rect for frame scrolling contents is too
+    // small for RootLayerScrolling.
+    EXPECT_DISPLAY_LIST(
+        RootPaintController().GetDisplayItemList(), 3,
+        TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
+        TestDisplayItem(GetLayoutView(), kScrollHitTestType),
+        TestDisplayItem(div1, kBackgroundType));
+  } else {
+    // Initial cull rect: (0,0 4800x4600).
+    EXPECT_DISPLAY_LIST(
+        RootPaintController().GetDisplayItemList(), 4,
+        TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
+        TestDisplayItem(GetLayoutView(), kScrollHitTestType),
+        TestDisplayItem(div1, kBackgroundType),
+        TestDisplayItem(div2, kBackgroundType));
+  }
 
   GetDocument().View()->LayoutViewportScrollableArea()->SetScrollOffset(
       ScrollOffset(5000, 5000), kProgrammaticScroll);
   GetDocument().View()->UpdateAllLifecyclePhases();
 
-  // Cull rect after scroll: (1000,1000 8800x8600)
-  EXPECT_DISPLAY_LIST(RootPaintController().GetDisplayItemList(), 5,
-                      TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
-                      TestDisplayItem(GetLayoutView(), kScrollHitTestType),
-                      TestDisplayItem(div2, kBackgroundType),
-                      TestDisplayItem(div3, kBackgroundType),
-                      TestDisplayItem(div4, kBackgroundType));
+  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
+    // TODO(crbug.com/792577): Cull rect for frame scrolling contents is too
+    // small for RootLayerScrolling.
+    EXPECT_DISPLAY_LIST(
+        RootPaintController().GetDisplayItemList(), 2,
+        TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
+        TestDisplayItem(GetLayoutView(), kScrollHitTestType));
+  } else {
+    // Cull rect after scroll: (1000,1000 8800x8600).
+    EXPECT_DISPLAY_LIST(
+        RootPaintController().GetDisplayItemList(), 5,
+        TestDisplayItem(GetLayoutView(), kDocumentBackgroundType),
+        TestDisplayItem(GetLayoutView(), kScrollHitTestType),
+        TestDisplayItem(div2, kBackgroundType),
+        TestDisplayItem(div3, kBackgroundType),
+        TestDisplayItem(div4, kBackgroundType));
+  }
 }
 
-// TODO(wangxianzhu): Fix cull rect issue when painting layered contents under
-// overflow clip and add a test case.
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2,
-       BlockScrollingNonLayeredContents) {
+TEST_P(PaintControllerPaintTestForSPv2, BlockScrollingNonLayeredContents) {
   SetBodyInnerHTML(R"HTML(
     <style>
       ::-webkit-scrollbar { display: none }
@@ -244,7 +245,7 @@
                       TestDisplayItem(div4, kBackgroundType));
 }
 
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2, ScrollHitTestOrder) {
+TEST_P(PaintControllerPaintTestForSPv2, ScrollHitTestOrder) {
   SetBodyInnerHTML(R"HTML(
     <style>
       ::-webkit-scrollbar { display: none }
@@ -274,8 +275,7 @@
                       TestDisplayItem(child, kBackgroundType));
 }
 
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2,
-       NonStackingScrollHitTestOrder) {
+TEST_P(PaintControllerPaintTestForSPv2, NonStackingScrollHitTestOrder) {
   SetBodyInnerHTML(R"HTML(
     <style>
       ::-webkit-scrollbar { display: none }
@@ -316,7 +316,7 @@
                       TestDisplayItem(pos_z_child, kBackgroundType));
 }
 
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2, StackingScrollHitTestOrder) {
+TEST_P(PaintControllerPaintTestForSPv2, StackingScrollHitTestOrder) {
   SetBodyInnerHTML(R"HTML(
     <style>
       ::-webkit-scrollbar { display: none }
@@ -355,7 +355,7 @@
                       TestDisplayItem(pos_z_child, kBackgroundType));
 }
 
-TEST_P(PaintControllerPaintTestForSlimmingPaintV2,
+TEST_P(PaintControllerPaintTestForSPv2,
        NonStackingScrollHitTestOrderWithoutBackground) {
   SetBodyInnerHTML(R"HTML(
     <style>
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
index b3fa17b7..01a3367 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
@@ -62,6 +62,16 @@
     return true;
   }
 
+  const DisplayItemClient& ViewBackgroundClient() {
+    if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+        RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
+      // With SPv1* and RLS, the document background uses the scrolling contents
+      // layer as its DisplayItemClient.
+      return *GetLayoutView().Layer()->GraphicsLayerBacking();
+    }
+    return GetLayoutView();
+  }
+
   void Commit() {
     // Only root graphics layer is supported.
     RootPaintController().CommitNewDisplayItems();
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
index 6683b08..5391ded 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -609,7 +609,13 @@
     const ClipRectsContext& context) const {
   if (&layer_ == context.root_layer && !context.ShouldRespectRootLayerClip())
     return false;
-  return HasOverflowClip(layer_);
+  // Embedded objects with border radius need to compute clip rects when
+  // painting child mask layers. We do not have access to paint phases here,
+  // so always claim to clip and ignore it later when painting the foreground
+  // phases.
+  return HasOverflowClip(layer_) ||
+         (layer_.GetLayoutObject().IsLayoutEmbeddedContent() &&
+          layer_.GetLayoutObject().StyleRef().HasBorderRadius());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index cf2a110..67fc9bc3 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -428,8 +428,8 @@
       // all of them in the mask.
       //
       // The paint rect is in this layer's space, so convert it to the clipper's
-      // layer's space. The rootLayer is also changed to the clipper's layer to
-      // simplify coordinate system adjustments. The change to rootLayer must
+      // layer's space. The root_layer is also changed to the clipper's layer to
+      // simplify coordinate system adjustments. The change to root_layer must
       // persist to correctly record the clips.
       paint_layer_for_fragments =
           paint_layer_.EnclosingLayerWithCompositedLayerMapping(kExcludeSelf);
@@ -621,12 +621,25 @@
 bool PaintLayerPainter::NeedsToClip(
     const PaintLayerPaintingInfo& local_painting_info,
     const ClipRect& clip_rect,
-    const PaintLayerFlags& paint_flags) {
-  // Clipping will be applied by property nodes directly for SPv2.
+    const PaintLayerFlags& paint_flags,
+    const LayoutBoxModelObject& layout_object) {
+  // Embedded objects have a clip rect when border radius is present
+  // because we need it for the border radius mask with composited
+  // chidren. However, we do not want to apply the clip when painting
+  // the embedded content itself. Doing so would clip out the
+  // border because LayoutEmbeddedObject does not obey the painting phases
+  // of a normal box object.
+  if (layout_object.IsLayoutEmbeddedContent())
+    return paint_flags & kPaintLayerPaintingChildClippingMaskPhase;
+
+  // Always clip if painting an ancestor clipping mask layer.
+  if (paint_flags & kPaintLayerPaintingAncestorClippingMaskPhase)
+    return true;
+
+  // Other clipping will be applied by property nodes directly for SPv2.
   if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
     return false;
   return clip_rect.Rect() != local_painting_info.paint_dirty_rect ||
-         (paint_flags & kPaintLayerPaintingAncestorClippingMaskPhase) ||
          clip_rect.HasRadius();
 }
 
@@ -752,12 +765,13 @@
   for (const auto& fragment : layer_fragments) {
     Optional<LayerClipRecorder> clip_recorder;
     if (parent_layer && !RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-      if (NeedsToClip(painting_info, fragment.background_rect, paint_flags)) {
+      if (NeedsToClip(painting_info, fragment.background_rect, paint_flags,
+                      paint_layer_.GetLayoutObject())) {
         clip_recorder.emplace(
             context, *parent_layer, DisplayItem::kClipLayerParent,
             fragment.background_rect, painting_info.root_layer,
             fragment.pagination_offset, paint_flags,
-            parent_layer->GetLayoutObject());
+            paint_layer_.GetLayoutObject());
       }
     }
     if (PaintFragmentByApplyingTransform(context, painting_info, paint_flags,
@@ -915,8 +929,8 @@
     LayoutRect cull_rect = fragment.background_rect.Rect();
 
     Optional<LayerClipRecorder> clip_recorder;
-    if (NeedsToClip(local_painting_info, fragment.background_rect,
-                    paint_flags)) {
+    if (NeedsToClip(local_painting_info, fragment.background_rect, paint_flags,
+                    paint_layer_.GetLayoutObject())) {
       clip_recorder.emplace(
           context, paint_layer_, DisplayItem::kClipLayerOverflowControls,
           fragment.background_rect, local_painting_info.root_layer,
@@ -971,8 +985,8 @@
   DisplayItemClient* client = &paint_layer_.GetLayoutObject();
   Optional<LayerClipRecorder> clip_recorder;
   if (clip_state != kHasClipped &&
-      (NeedsToClip(painting_info, clip_rect, paint_flags) ||
-       paint_flags & kPaintLayerPaintingAncestorClippingMaskPhase)) {
+      NeedsToClip(painting_info, clip_rect, paint_flags,
+                  paint_layer_.GetLayoutObject())) {
     DisplayItem::Type clip_type =
         DisplayItem::PaintPhaseToClipLayerFragmentType(phase);
     LayerClipRecorder::BorderRadiusClippingRule clipping_rule;
@@ -998,7 +1012,6 @@
         clipping_rule = LayerClipRecorder::kIncludeSelfForBorderRadius;
         break;
     }
-
     clip_recorder.emplace(context, paint_layer_, clip_type, clip_rect,
                           painting_info.root_layer, fragment.pagination_offset,
                           paint_flags, *client, clipping_rule);
@@ -1082,7 +1095,7 @@
   Optional<LayerClipRecorder> clip_recorder;
   if (should_clip &&
       NeedsToClip(local_painting_info, layer_fragments[0].foreground_rect,
-                  paint_flags)) {
+                  paint_flags, paint_layer_.GetLayoutObject())) {
     clip_recorder.emplace(
         context, paint_layer_, DisplayItem::kClipLayerForeground,
         layer_fragments[0].foreground_rect, local_painting_info.root_layer,
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.h b/third_party/WebKit/Source/core/paint/PaintLayerPainter.h
index dce1b41..7c79aff9 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.h
@@ -17,6 +17,7 @@
 class DisplayItemClient;
 class PaintLayer;
 class GraphicsContext;
+class LayoutBoxModelObject;
 class LayoutPoint;
 
 // This class is responsible for painting self-painting PaintLayer.
@@ -139,7 +140,8 @@
 
   static bool NeedsToClip(const PaintLayerPaintingInfo& local_painting_info,
                           const ClipRect&,
-                          const PaintLayerFlags&);
+                          const PaintLayerFlags&,
+                          const LayoutBoxModelObject&);
 
   // Returns true if the painted output of this PaintLayer and its children is
   // invisible and therefore can't impact painted output.
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index d8b26393..ce4638f2 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -327,12 +327,14 @@
   if (!object.IsBoxModelObject())
     return false;
   const LayoutBoxModelObject& box_model = ToLayoutBoxModelObject(object);
-  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled() &&
-      box_model.IsLayoutView()) {
+
+  if (box_model.IsLayoutView()) {
     // Root layer scrolling always creates a translation node for LayoutView to
     // ensure fixed and absolute contexts use the correct transform space.
-    return true;
+    // Otherwise we have created all needed property nodes on the FrameView.
+    return RuntimeEnabledFeatures::RootLayerScrollingEnabled();
   }
+
   if (box_model.HasLayer() && box_model.Layer()->PaintsWithTransform(
                                   kGlobalPaintFlattenCompositingLayers)) {
     return true;
@@ -918,23 +920,21 @@
       !full_context_.force_subtree_update)
     return;
 
-  auto* rare_paint_data = fragment_data_.GetRarePaintData();
-
   if (!object_.HasLayer() && !NeedsPaintOffsetTranslation(object_)) {
-    if (rare_paint_data)
+    if (auto* rare_paint_data = fragment_data_.GetRarePaintData())
       rare_paint_data->ClearLocalBorderBoxProperties();
   } else {
-    DCHECK(rare_paint_data);
+    auto& rare_paint_data = fragment_data_.EnsureRarePaintData();
     const ClipPaintPropertyNode* clip = context_.current.clip;
-    if (rare_paint_data->PaintProperties() &&
-        rare_paint_data->PaintProperties()->FragmentClip()) {
-      clip = rare_paint_data->PaintProperties()->FragmentClip();
+    if (rare_paint_data.PaintProperties() &&
+        rare_paint_data.PaintProperties()->FragmentClip()) {
+      clip = rare_paint_data.PaintProperties()->FragmentClip();
     }
 
     PropertyTreeState local_border_box = PropertyTreeState(
         context_.current.transform, clip, context_.current_effect);
 
-    rare_paint_data->SetLocalBorderBoxProperties(local_border_box);
+    rare_paint_data.SetLocalBorderBoxProperties(local_border_box);
   }
 }
 
@@ -1455,6 +1455,7 @@
 
   // The filter generated for reflection depends on box size.
   if (box.HasReflection()) {
+    DCHECK(box.HasLayer());
     box.Layer()->SetFilterOnEffectNodeDirty();
     box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
   }
@@ -1560,13 +1561,23 @@
   return context;
 }
 
+void ObjectPaintPropertyTreeBuilder::InitFragmentPaintProperties(
+    FragmentData& fragment,
+    bool needs_paint_properties) {
+  if (needs_paint_properties) {
+    fragment.EnsureRarePaintData().EnsurePaintProperties();
+  } else if (fragment.PaintProperties()) {
+    context_.force_subtree_update = true;
+    fragment.GetRarePaintData()->ClearPaintProperties();
+  }
+}
+
 void ObjectPaintPropertyTreeBuilder::InitSingleFragmentFromParent(
     bool needs_paint_properties) {
   FragmentData& first_fragment =
       object_.GetMutableForPainting().FirstFragment();
   first_fragment.ClearNextFragment();
-  if (needs_paint_properties)
-    first_fragment.EnsureRarePaintData().EnsurePaintProperties();
+  InitFragmentPaintProperties(first_fragment, needs_paint_properties);
   if (context_.fragments.IsEmpty()) {
     context_.fragments.push_back(PaintPropertyTreeBuilderFragmentContext());
   } else {
@@ -1588,92 +1599,75 @@
       NeedsScrollOrScrollTranslation(object_) ||
       NeedsFragmentationClip(object_, *context_.painting_layer);
 
-  bool needs_fragments = NeedsFragmentation(object_, *context_.painting_layer);
-  bool had_paint_properties = object_.FirstFragment().PaintProperties();
-  if (!needs_paint_properties && !needs_fragments && !object_.HasLayer()) {
-    if (had_paint_properties) {
-      context_.force_subtree_update = true;
-      object_.FirstFragment().GetRarePaintData()->ClearPaintProperties();
-    }
+  if (!NeedsFragmentation(object_, *context_.painting_layer)) {
     InitSingleFragmentFromParent(needs_paint_properties);
   } else {
-    if (!needs_fragments) {
-      InitSingleFragmentFromParent(needs_paint_properties);
-    } else {
-      // We need at least the fragments for all fragmented objects, which store
-      // their local border box properties and paint invalidation data (such
-      // as paint offset and visual rect) on each fragment.
-      PaintLayer* paint_layer = object_.PaintingLayer();
-      PaintLayer* enclosing_pagination_layer =
-          paint_layer->EnclosingPaginationLayer();
+    // We need at least the fragments for all fragmented objects, which store
+    // their local border box properties and paint invalidation data (such
+    // as paint offset and visual rect) on each fragment.
+    PaintLayer* paint_layer = object_.PaintingLayer();
+    PaintLayer* enclosing_pagination_layer =
+        paint_layer->EnclosingPaginationLayer();
 
-      LayoutRect object_bounding_box_in_flow_thread =
-          BoundingBoxInPaginationContainer(object_,
-                                           *enclosing_pagination_layer);
-      const LayoutFlowThread& flow_thread =
-          ToLayoutFlowThread(enclosing_pagination_layer->GetLayoutObject());
-      FragmentainerIterator iterator(flow_thread,
-                                     object_bounding_box_in_flow_thread);
+    LayoutRect object_bounding_box_in_flow_thread =
+        BoundingBoxInPaginationContainer(object_, *enclosing_pagination_layer);
+    const LayoutFlowThread& flow_thread =
+        ToLayoutFlowThread(enclosing_pagination_layer->GetLayoutObject());
+    FragmentainerIterator iterator(flow_thread,
+                                   object_bounding_box_in_flow_thread);
 
-      Vector<PaintPropertyTreeBuilderFragmentContext> new_fragment_contexts;
-      FragmentData* current_fragment_data = nullptr;
+    Vector<PaintPropertyTreeBuilderFragmentContext> new_fragment_contexts;
+    FragmentData* current_fragment_data = nullptr;
 
-      int fragment_count = 0;
-      for (; !iterator.AtEnd() && fragment_count < kMaxNumFragments;
-           iterator.Advance(), fragment_count++) {
-        if (!current_fragment_data) {
-          current_fragment_data =
-              &object_.GetMutableForPainting().FirstFragment();
-        } else {
-          current_fragment_data = &current_fragment_data->EnsureNextFragment();
-        }
-
-        RarePaintData& rare_paint_data =
-            current_fragment_data->EnsureRarePaintData();
-
-        if (needs_paint_properties)
-          rare_paint_data.EnsurePaintProperties();
-
-        // 1. Compute clip in flow thread space of the containing flow thread.
-        LayoutRect fragment_clip(iterator.ClipRectInFlowThread());
-        // 2. Convert #1 to visual coordinates in the space of the flow
-        // thread.
-        fragment_clip.Move(iterator.PaginationOffset());
-        // 3. Adust #2 to visual coordinates in the containing "paint offset"
-        // space.
-        {
-          DCHECK(context_.fragments[0].current.paint_offset_root);
-          LayoutPoint pagination_visual_offset =
-              VisualOffsetFromPaintOffsetRoot(context_.fragments[0],
-                                              enclosing_pagination_layer);
-
-          // Adjust for paint offset of the root, which may have a subpixel
-          // component.
-          // The paint offset root never has more than one fragment.
-          pagination_visual_offset.MoveBy(
-              context_.fragments[0]
-                  .current.paint_offset_root->FirstFragment()
-                  .PaintOffset());
-
-          fragment_clip.MoveBy(pagination_visual_offset);
-        }
-        // 4. Match to parent fragments from the same containing flow
-        // thread.
-        new_fragment_contexts.push_back(
-            ContextForFragment(fragment_clip, context_.fragments));
-        // 5. Save off PaginationOffset (which allows us to adjust
-        // logical paint offsets into the space of the current fragment later.
-
-        current_fragment_data->GetRarePaintData()->SetPaginationOffset(
-            ToLayoutPoint(iterator.PaginationOffset()));
-      }
-      if (current_fragment_data) {
-        current_fragment_data->ClearNextFragment();
-        context_.fragments = new_fragment_contexts;
+    int fragment_count = 0;
+    for (; !iterator.AtEnd() && fragment_count < kMaxNumFragments;
+         iterator.Advance(), fragment_count++) {
+      if (!current_fragment_data) {
+        current_fragment_data =
+            &object_.GetMutableForPainting().FirstFragment();
       } else {
-        // This will be an empty fragment - get rid of it?
-        InitSingleFragmentFromParent(needs_paint_properties);
+        current_fragment_data = &current_fragment_data->EnsureNextFragment();
       }
+
+      InitFragmentPaintProperties(*current_fragment_data,
+                                  needs_paint_properties);
+
+      // 1. Compute clip in flow thread space of the containing flow thread.
+      LayoutRect fragment_clip(iterator.ClipRectInFlowThread());
+      // 2. Convert #1 to visual coordinates in the space of the flow thread.
+      fragment_clip.Move(iterator.PaginationOffset());
+      // 3. Adust #2 to visual coordinates in the containing "paint offset"
+      // space.
+      {
+        DCHECK(context_.fragments[0].current.paint_offset_root);
+        LayoutPoint pagination_visual_offset = VisualOffsetFromPaintOffsetRoot(
+            context_.fragments[0], enclosing_pagination_layer);
+
+        // Adjust for paint offset of the root, which may have a subpixel
+        // component.
+        // The paint offset root never has more than one fragment.
+        pagination_visual_offset.MoveBy(
+            context_.fragments[0]
+                .current.paint_offset_root->FirstFragment()
+                .PaintOffset());
+
+        fragment_clip.MoveBy(pagination_visual_offset);
+      }
+      // 4. Match to parent fragments from the same containing flow thread.
+      new_fragment_contexts.push_back(
+          ContextForFragment(fragment_clip, context_.fragments));
+      // 5. Save off PaginationOffset (which allows us to adjust
+      // logical paint offsets into the space of the current fragment later.
+
+      current_fragment_data->EnsureRarePaintData().SetPaginationOffset(
+          ToLayoutPoint(iterator.PaginationOffset()));
+    }
+    if (current_fragment_data) {
+      current_fragment_data->ClearNextFragment();
+      context_.fragments = new_fragment_contexts;
+    } else {
+      // This will be an empty fragment - get rid of it?
+      InitSingleFragmentFromParent(needs_paint_properties);
     }
   }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
index 3634eba..708ddf3 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
@@ -15,6 +15,7 @@
 
 namespace blink {
 
+class FragmentData;
 class LayoutObject;
 class LocalFrameView;
 class PaintLayer;
@@ -155,6 +156,8 @@
   void UpdateForChildren();
 
  private:
+  ALWAYS_INLINE void InitFragmentPaintProperties(FragmentData&,
+                                                 bool needs_paint_properties);
   ALWAYS_INLINE void InitSingleFragmentFromParent(bool needs_paint_properties);
   ALWAYS_INLINE void UpdateFragments();
   ALWAYS_INLINE void UpdatePaintingLayer();
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
index a007cc4..9377666 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -128,7 +128,7 @@
 INSTANTIATE_TEST_CASE_P(
     All,
     PaintPropertyTreeBuilderTest,
-    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
+    ::testing::ValuesIn(kSlimmingPaintNonV1TestConfigurations));
 
 TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
   LoadTestData("fixed-position.html");
@@ -549,7 +549,13 @@
             transform_properties->Transform()->Matrix());
   // The value is zero without a transform property that needs transform-offset.
   EXPECT_EQ(FloatPoint3D(0, 0, 0), transform_properties->Transform()->Origin());
-  EXPECT_EQ(nullptr, transform_properties->PaintOffsetTranslation());
+  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+    EXPECT_EQ(nullptr, transform_properties->PaintOffsetTranslation());
+  } else {
+    // SPv175 creates PaintOffsetTranslation for composited layers.
+    EXPECT_EQ(TransformationMatrix().Translate(50, 100),
+              transform_properties->PaintOffsetTranslation()->Matrix());
+  }
   EXPECT_TRUE(transform_properties->Transform()->HasDirectCompositingReasons());
 
   CHECK_EXACT_VISUAL_RECT(LayoutRect(50, 100, 400, 300),
@@ -1575,8 +1581,14 @@
 
   EXPECT_EQ(FrameContentClip(),
             child.FirstFragment().LocalBorderBoxProperties()->Clip());
-  EXPECT_EQ(FrameScrollTranslation(),
-            child.FirstFragment().LocalBorderBoxProperties()->Transform());
+  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+    EXPECT_EQ(FrameScrollTranslation(),
+              child.FirstFragment().LocalBorderBoxProperties()->Transform());
+  } else {
+    // For SPv1*, |child| is composited so we created PaintOffsetTranslation.
+    EXPECT_EQ(child.FirstFragment().PaintProperties()->PaintOffsetTranslation(),
+              child.FirstFragment().LocalBorderBoxProperties()->Transform());
+  }
   EXPECT_EQ(scroller_properties->Effect(),
             child.FirstFragment().LocalBorderBoxProperties()->Effect());
   CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 800, 10000), &scroller,
@@ -3430,10 +3442,21 @@
   ASSERT_TRUE(multicol_container->FirstFragment().NextFragment());
   ASSERT_FALSE(
       multicol_container->FirstFragment().NextFragment()->NextFragment());
-  EXPECT_EQ(LayoutPoint(8, 8),
-            multicol_container->FirstFragment().PaintOffset());
-  EXPECT_EQ(LayoutPoint(59, -12),
-            multicol_container->FirstFragment().NextFragment()->PaintOffset());
+  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+      !RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
+    EXPECT_EQ(LayoutPoint(8, 8),
+              multicol_container->FirstFragment().PaintOffset());
+    EXPECT_EQ(
+        LayoutPoint(59, -12),
+        multicol_container->FirstFragment().NextFragment()->PaintOffset());
+  } else {
+    // TODO(crbug.com/793051): The paint offsets are incorrect.
+    EXPECT_EQ(LayoutPoint(8, 33),
+              multicol_container->FirstFragment().PaintOffset());
+    EXPECT_EQ(
+        LayoutPoint(59, 13),
+        multicol_container->FirstFragment().NextFragment()->PaintOffset());
+  }
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumn) {
@@ -3636,11 +3659,20 @@
   const ObjectPaintProperties* filter_properties =
       GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
   EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
-  EXPECT_EQ(FrameScrollTranslation(),
-            filter_properties->Filter()->LocalTransformSpace());
   EXPECT_EQ(clip_properties->OverflowClip(),
             filter_properties->Filter()->OutputClip());
-  EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->PaintOffset());
+  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+    EXPECT_EQ(FrameScrollTranslation(),
+              filter_properties->Filter()->LocalTransformSpace());
+    EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->PaintOffset());
+  } else {
+    // For SPv1*, |filter| is composited so we created PaintOffsetTranslation.
+    EXPECT_EQ(filter_properties->PaintOffsetTranslation(),
+              filter_properties->Filter()->LocalTransformSpace());
+    EXPECT_EQ(TransformationMatrix().Translate(8, 8),
+              filter_properties->PaintOffsetTranslation()->Matrix());
+    EXPECT_EQ(FloatPoint(), filter_properties->Filter()->PaintOffset());
+  }
 
   const PropertyTreeState& child_paint_state =
       *GetLayoutObjectByElementId("child")
@@ -3965,8 +3997,16 @@
   EXPECT_EQ(mask_clip, target_properties->Mask()->OutputClip());
 
   const auto* absolute = GetLayoutObjectByElementId("absolute");
-  EXPECT_EQ(FramePreTranslation(),
-            absolute->FirstFragment().LocalBorderBoxProperties()->Transform());
+  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+    EXPECT_EQ(
+        FramePreTranslation(),
+        absolute->FirstFragment().LocalBorderBoxProperties()->Transform());
+  } else {
+    // For SPv1*, |absolute| is composited so we created PaintOffsetTranslation.
+    EXPECT_EQ(
+        absolute->FirstFragment().PaintProperties()->PaintOffsetTranslation(),
+        absolute->FirstFragment().LocalBorderBoxProperties()->Transform());
+  }
   EXPECT_EQ(mask_clip,
             absolute->FirstFragment().LocalBorderBoxProperties()->Clip());
 }
@@ -4169,11 +4209,11 @@
   )HTML");
 
   const auto* target = GetLayoutObjectByElementId("target");
-  EXPECT_EQ(LayoutPoint(60, 50), target->FirstFragment().PaintOffset());
   if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
     EXPECT_EQ(nullptr, target->FirstFragment().PaintProperties());
     EXPECT_EQ(LayoutPoint(60, 50), target->FirstFragment().PaintOffset());
   } else {
+    // For SPv1*, |target| is composited so we created PaintOffsetTranslation.
     const auto* paint_offset_translation =
         target->FirstFragment().PaintProperties()->PaintOffsetTranslation();
     ASSERT_NE(nullptr, paint_offset_translation);
@@ -4212,4 +4252,13 @@
   EXPECT_EQ(nullptr, properties->OverflowClip());
 }
 
+TEST_P(PaintPropertyTreeBuilderTest, NoPropertyForSVGTextWithReflection) {
+  SetBodyInnerHTML(R"HTML(
+    <svg>
+      <text id='target' style='-webkit-box-reflect: below 2px'>X</text>
+    </svg>
+  )HTML");
+  EXPECT_FALSE(PaintPropertiesForElement("target"));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp
index 1972861..53c51c8 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinterTest.cpp
@@ -29,7 +29,7 @@
 INSTANTIATE_TEST_CASE_P(
     All,
     PaintPropertyTreePrinterTest,
-    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
+    ::testing::ValuesIn(kSlimmingPaintNonV1TestConfigurations));
 
 TEST_P(PaintPropertyTreePrinterTest, SimpleTransformTree) {
   SetBodyInnerHTML("hello world");
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
index 798fe7a..fb7b77c 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
@@ -15,7 +15,7 @@
 INSTANTIATE_TEST_CASE_P(
     All,
     PaintPropertyTreeUpdateTest,
-    ::testing::ValuesIn(kSlimmingPaintV2TestConfigurations));
+    ::testing::ValuesIn(kSlimmingPaintNonV1TestConfigurations));
 
 TEST_P(PaintPropertyTreeUpdateTest,
        ThreadedScrollingDisabledMainThreadScrollReason) {
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
index 83c8ee8..e62bd9e 100644
--- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
+++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -62,18 +62,16 @@
   PrePaintTreeWalkContext initial_context;
 
   // GeometryMapper depends on paint properties.
-  if (NeedsTreeBuilderContextUpdate(root_frame, initial_context))
+  bool needs_tree_builder_context_update =
+      NeedsTreeBuilderContextUpdate(root_frame, initial_context);
+  if (needs_tree_builder_context_update)
     GeometryMapper::ClearCache();
 
-#if DCHECK_IS_ON()
-  bool needed_paint_property_update = root_frame.NeedsPaintPropertyUpdate();
-#endif
-
   Walk(root_frame, initial_context);
   paint_invalidator_.ProcessPendingDelayedPaintInvalidations();
 
 #if DCHECK_IS_ON()
-  if (!needed_paint_property_update)
+  if (!needs_tree_builder_context_update)
     return;
   if (VLOG_IS_ON(2) && root_frame.GetLayoutView()) {
     LOG(ERROR) << "PrePaintTreeWalk::Walk(root_frame_view=" << &root_frame
diff --git a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp b/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
index d384e0bc..d688e607 100644
--- a/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/TablePainterTest.cpp
@@ -39,19 +39,9 @@
   IntRect interest_rect(0, 0, 200, 200);
   Paint(&interest_rect);
 
-  DisplayItemClient* background_client = nullptr;
-  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
-      RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    // With SPv1 and RLS, the document background uses the scrolling contents
-    // layer as its DisplayItemClient.
-    background_client = GetLayoutView().Layer()->GraphicsLayerBacking();
-  } else {
-    background_client = &GetLayoutView();
-  }
-
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 2,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(row1, DisplayItem::kBoxDecorationBackground));
 
   GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
@@ -60,7 +50,7 @@
 
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 2,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(row2, DisplayItem::kBoxDecorationBackground));
 }
 
@@ -91,19 +81,9 @@
   IntRect interest_rect(0, 200, 200, 150);
   Paint(&interest_rect);
 
-  DisplayItemClient* background_client = nullptr;
-  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
-      RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    // With SPv1 and RLS, the document background uses the scrolling contents
-    // layer as its DisplayItemClient.
-    background_client = GetLayoutView().Layer()->GraphicsLayerBacking();
-  } else {
-    background_client = &GetLayoutView();
-  }
-
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 3,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(row1, DisplayItem::kBoxDecorationBackground),
       TestDisplayItem(cell1, DisplayItem::kBoxDecorationBackground));
 
@@ -114,7 +94,7 @@
 
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 2,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(row1, DisplayItem::kBoxDecorationBackground));
 
   GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
@@ -124,7 +104,7 @@
 
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 3,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(row2, DisplayItem::kBoxDecorationBackground),
       TestDisplayItem(cell2, DisplayItem::kBoxDecorationBackground));
 }
@@ -154,19 +134,9 @@
   IntRect interest_rect(200, 0, 200, 200);
   Paint(&interest_rect);
 
-  DisplayItemClient* background_client = nullptr;
-  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
-      RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    // With SPv1 and RLS, the document background uses the scrolling contents
-    // layer as its DisplayItemClient.
-    background_client = GetLayoutView().Layer()->GraphicsLayerBacking();
-  } else {
-    background_client = &GetLayoutView();
-  }
-
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 5,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(row, DisplayItem::kBeginCompositing),
       TestDisplayItem(row, DisplayItem::kBoxDecorationBackground),
       TestDisplayItem(cell1, DisplayItem::kBoxDecorationBackground),
@@ -177,9 +147,9 @@
   interest_rect = IntRect(300, 0, 100, 100);
   Paint(&interest_rect);
 
-  EXPECT_DISPLAY_LIST(
-      RootPaintController().GetDisplayItemList(), 1,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground));
+  EXPECT_DISPLAY_LIST(RootPaintController().GetDisplayItemList(), 1,
+                      TestDisplayItem(ViewBackgroundClient(),
+                                      DisplayItem::kDocumentBackground));
 
   GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
   // Intersects cell2 only.
@@ -188,7 +158,7 @@
 
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 5,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(row, DisplayItem::kBeginCompositing),
       TestDisplayItem(row, DisplayItem::kBoxDecorationBackground),
       TestDisplayItem(cell2, DisplayItem::kBoxDecorationBackground),
@@ -216,20 +186,10 @@
   IntRect interest_rect(0, 0, 100, 100);
   Paint(&interest_rect);
 
-  DisplayItemClient* background_client = nullptr;
-  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
-      RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    // With SPv1 and RLS, the document background uses the scrolling contents
-    // layer as its DisplayItemClient.
-    background_client = GetLayoutView().Layer()->GraphicsLayerBacking();
-  } else {
-    background_client = &GetLayoutView();
-  }
-
   // We should paint all display items of cell.
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 4,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(cell, DisplayItem::kBoxDecorationBackground),
       TestDisplayItem(*cell.Row(), DisplayItem::kTableCollapsedBorders),
       TestDisplayItem(cell, DisplayItem::PaintPhaseToDrawingType(
diff --git a/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp b/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp
index ccc9a74..85c8fcb9 100644
--- a/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/ViewPainterTest.cpp
@@ -132,8 +132,9 @@
     EXPECT_EQ(properties->ScrollTranslation(), tree_state.Transform());
     EXPECT_EQ(properties->OverflowClip(), tree_state.Clip());
   } else {
+    EXPECT_EQ(nullptr, properties);
     const auto* frame_view = GetDocument().View();
-    EXPECT_EQ(properties->PaintOffsetTranslation(), tree_state.Transform());
+    EXPECT_EQ(frame_view->ScrollTranslation(), tree_state.Transform());
     EXPECT_EQ(frame_view->ContentClip(), tree_state.Clip());
   }
 }
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
index 4a0e48f..792af10 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
@@ -549,12 +549,15 @@
                    PaintLayerCompositor::FrameContentsCompositor(
                        ToLayoutEmbeddedContent(GetLayoutObject()))) {
       inner_compositor->FrameViewDidChangeSize();
-      // We can floor this point because our frameviews are always aligned to
-      // pixel boundaries.
-      DCHECK(composited_bounds_.Location() ==
-             FlooredIntPoint(composited_bounds_.Location()));
+      FloatPoint parent_posn = child_containment_layer_
+                                   ? child_containment_layer_->GetPosition()
+                                   : FloatPoint();
+      FloatSize offset = FloatPoint(ContentsBox().Location()) - parent_posn;
+      // Assert our frameviews are always aligned to pixel boundaries.
+      DCHECK(offset.Width() == floor(offset.Width()) &&
+             offset.Height() == floor(offset.Height()));
       inner_compositor->FrameViewDidChangeLocation(
-          FlooredIntPoint(ContentsBox().Location()));
+          IntPoint(floor(offset.Width()), floor(offset.Height())));
     }
   }
 }
@@ -1506,16 +1509,30 @@
     return;
   DCHECK(GetLayoutObject().IsBox());
 
-  IntRect clipping_box = PixelSnappedIntRect(
-      ToLayoutBox(GetLayoutObject())
-          .ClippingRect(LayoutPoint(SubpixelAccumulation())));
-  child_containment_layer_->SetSize(FloatSize(clipping_box.Size()));
-  child_containment_layer_->SetOffsetFromLayoutObject(
-      ToIntSize(clipping_box.Location()));
-  IntPoint parent_location(
-      child_containment_layer_->Parent()->OffsetFromLayoutObject());
-  child_containment_layer_->SetPosition(
-      IntPoint(clipping_box.Location() - parent_location));
+  if (GetLayoutObject().IsLayoutEmbeddedContent()) {
+    // Embedded content layers do not have a clipping rect defined,
+    // so use the PaddingBoxRect.
+    IntRect clipping_box =
+        PixelSnappedIntRect(ToLayoutBox(GetLayoutObject()).PaddingBoxRect());
+    child_containment_layer_->SetSize(FloatSize(clipping_box.Size()));
+    child_containment_layer_->SetOffsetFromLayoutObject(
+        ToIntSize(clipping_box.Location()));
+    IntPoint parent_location(
+        child_containment_layer_->Parent()->OffsetFromLayoutObject());
+    child_containment_layer_->SetPosition(
+        IntPoint(clipping_box.Location() - parent_location));
+  } else {
+    IntRect clipping_box = PixelSnappedIntRect(
+        ToLayoutBox(GetLayoutObject())
+            .ClippingRect(LayoutPoint(SubpixelAccumulation())));
+    child_containment_layer_->SetSize(FloatSize(clipping_box.Size()));
+    child_containment_layer_->SetOffsetFromLayoutObject(
+        ToIntSize(clipping_box.Location()));
+    IntPoint parent_location(
+        child_containment_layer_->Parent()->OffsetFromLayoutObject());
+    child_containment_layer_->SetPosition(
+        IntPoint(clipping_box.Location() - parent_location));
+  }
 
   if (child_clipping_mask_layer_ && !scrolling_layer_ &&
       !GetLayoutObject().Style()->ClipPath()) {
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingRequirementsUpdater.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositingRequirementsUpdater.cpp
index b06a753..8ca560a 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositingRequirementsUpdater.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositingRequirementsUpdater.cpp
@@ -26,7 +26,9 @@
 
 #include "core/paint/compositing/CompositingRequirementsUpdater.h"
 
+#include "core/layout/LayoutEmbeddedContent.h"
 #include "core/layout/LayoutView.h"
+#include "core/layout/api/LayoutViewItem.h"
 #include "core/paint/PaintLayer.h"
 #include "core/paint/PaintLayerStackingNode.h"
 #include "core/paint/PaintLayerStackingNodeIterator.h"
@@ -400,7 +402,7 @@
   bool will_be_composited_or_squashed =
       can_be_composited && RequiresCompositingOrSquashing(reasons_to_composite);
   if (will_be_composited_or_squashed) {
-    // This layer now acts as the ancestor for kids.
+    // This layer now acts as the ancestor for child layers.
     child_recursion_data.compositing_ancestor_ = layer;
 
     // Here we know that all children and the layer's own contents can blindly
@@ -496,6 +498,14 @@
         child_recursion_data.has_unisolated_composited_blending_descendant_;
   }
 
+  // Embedded objects treat the embedded document as a child for the purposes
+  // of composited layer decisions. Look into the embedded document to determine
+  // if it is composited.
+  bool contains_composited_iframe =
+      layer->GetLayoutObject().IsLayoutEmbeddedContent() &&
+      ToLayoutEmbeddedContent(layer->GetLayoutObject())
+          .RequiresAcceleratedCompositing();
+
   // Subsequent layers in the parent's stacking context may also need to
   // composite.
   if (child_recursion_data.subtree_is_compositing_)
@@ -503,7 +513,8 @@
 
   // Set the flag to say that this SC has compositing children.
   layer->SetHasCompositingDescendant(
-      child_recursion_data.subtree_is_compositing_);
+      child_recursion_data.subtree_is_compositing_ ||
+      contains_composited_iframe);
 
   if (layer->IsRootLayer()) {
     // The root layer needs to be composited if anything else in the tree is
diff --git a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
index 25b2495..e42a55a 100644
--- a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
@@ -923,9 +923,9 @@
 }
 
 // Return true if the given layer is a stacking context and has compositing
-// child layers that it needs to clip. In this case we insert a clipping
-// GraphicsLayer into the hierarchy between this layer and its children in the
-// z-order hierarchy.
+// child layers that it needs to clip, or is an embedded object with a border
+// radius. In these cases we insert a clipping GraphicsLayer into the hierarchy
+// between this layer and its children in the z-order hierarchy.
 bool PaintLayerCompositor::ClipsCompositingDescendants(
     const PaintLayer* layer) const {
   if (!layer->HasCompositingDescendant())
@@ -933,7 +933,8 @@
   if (!layer->GetLayoutObject().IsBox())
     return false;
   const LayoutBox& box = ToLayoutBox(layer->GetLayoutObject());
-  return box.ShouldClipOverflow() || box.HasClip();
+  return box.ShouldClipOverflow() || box.HasClip() ||
+         (box.IsLayoutEmbeddedContent() && box.StyleRef().HasBorderRadius());
 }
 
 // If an element has composited negative z-index children, those children paint
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc
index d83ddb0..0753b006 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc
@@ -299,7 +299,8 @@
 
     if (BleedAvoidanceIsClipping(box_decoration_data.bleed_avoidance)) {
       state_saver.Save();
-      FloatRoundedRect border = style.GetRoundedBorderFor(paint_rect);
+      FloatRoundedRect border = style.GetRoundedBorderFor(
+          paint_rect, border_edges_.line_left, border_edges_.line_right);
       paint_info.context.ClipRoundedRect(border);
 
       if (box_decoration_data.bleed_avoidance == kBackgroundBleedClipLayer)
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter.cc b/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter.cc
index c9534086..89f7c16 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter.cc
@@ -17,6 +17,29 @@
 
 namespace blink {
 
+namespace {
+
+inline bool ShouldPaintTextFragment(const NGPhysicalTextFragment& text_fragment,
+                                    const ComputedStyle& style) {
+  if (style.Visibility() != EVisibility::kVisible)
+    return false;
+
+  // When painting selection, we want to include a highlight when the
+  // selection spans line breaks. In other cases such as invisible elements
+  // or those with no text that are not line breaks, we can skip painting
+  // wholesale.
+  // TODO(wkorman): Constrain line break painting to appropriate paint phase.
+  // This code path is only called in PaintPhaseForeground whereas we would
+  // expect PaintPhaseSelection. The existing haveSelection logic in paint()
+  // tests for != PaintPhaseTextClip.
+  if (!text_fragment.Length() || !text_fragment.TextShapeResult())
+    return false;
+
+  return true;
+}
+
+}  // namespace
+
 NGTextFragmentPainter::NGTextFragmentPainter(
     const NGPaintFragment& text_fragment)
     : fragment_(text_fragment) {
@@ -26,8 +49,13 @@
 void NGTextFragmentPainter::Paint(const Document& document,
                                   const PaintInfo& paint_info,
                                   const LayoutPoint& paint_offset) {
+  const NGPhysicalTextFragment& text_fragment =
+      ToNGPhysicalTextFragment(fragment_.PhysicalFragment());
   const ComputedStyle& style = fragment_.Style();
 
+  if (!ShouldPaintTextFragment(text_fragment, style))
+    return;
+
   NGPhysicalSize size_;
   NGPhysicalOffset offset_;
 
@@ -79,9 +107,6 @@
   int selection_start = 0;
   int selection_end = 0;
 
-  const NGPhysicalTextFragment& text_fragment =
-      ToNGPhysicalTextFragment(fragment_.PhysicalFragment());
-
   LayoutRect box_rect(box_origin, fragment_.Size().ToLayoutSize());
   Optional<GraphicsContextStateSaver> state_saver;
   NGLineOrientation orientation = text_fragment.LineOrientation();
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc b/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc
index 6882a83d..176004b 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_text_fragment_painter_test.cc
@@ -51,16 +51,6 @@
   IntRect interest_rect(0, 0, 640, 480);
   Paint(&interest_rect);
 
-  DisplayItemClient* background_client = nullptr;
-  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
-      RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    // With SPv1 and RLS, the document background uses the scrolling contents
-    // layer as its DisplayItemClient.
-    background_client = GetLayoutView().Layer()->GraphicsLayerBacking();
-  } else {
-    background_client = &GetLayoutView();
-  }
-
   const NGPaintFragment& root_fragment = *block_flow.PaintFragment();
   EXPECT_EQ(1u, root_fragment.Children().size());
   const NGPaintFragment& line_box_fragment = *root_fragment.Children()[0];
@@ -69,7 +59,7 @@
 
   EXPECT_DISPLAY_LIST(
       RootPaintController().GetDisplayItemList(), 3,
-      TestDisplayItem(*background_client, DisplayItem::kDocumentBackground),
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
       TestDisplayItem(root_fragment, DisplayItem::kBoxDecorationBackground),
       TestDisplayItem(text_fragment, kForegroundType));
 }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index be91131..85feba08 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -268,8 +268,8 @@
 StyleContentAlignmentData ResolvedContentAlignment(
     const StyleContentAlignmentData& value,
     const StyleContentAlignmentData& normal_behaviour) {
-  return (value.GetPosition() == kContentPositionNormal &&
-          value.Distribution() == kContentDistributionDefault)
+  return (value.GetPosition() == ContentPosition::kNormal &&
+          value.Distribution() == ContentDistributionType::kDefault)
              ? normal_behaviour
              : value;
 }
@@ -291,8 +291,8 @@
 static inline ContentPosition ResolvedContentAlignmentPosition(
     const StyleContentAlignmentData& value,
     const StyleContentAlignmentData& normal_value_behavior) {
-  return (value.GetPosition() == kContentPositionNormal &&
-          value.Distribution() == kContentDistributionDefault)
+  return (value.GetPosition() == ContentPosition::kNormal &&
+          value.Distribution() == ContentDistributionType::kDefault)
              ? normal_value_behavior.GetPosition()
              : value.GetPosition();
 }
@@ -300,8 +300,8 @@
 static inline ContentDistributionType ResolvedContentAlignmentDistribution(
     const StyleContentAlignmentData& value,
     const StyleContentAlignmentData& normal_value_behavior) {
-  return (value.GetPosition() == kContentPositionNormal &&
-          value.Distribution() == kContentDistributionDefault)
+  return (value.GetPosition() == ContentPosition::kNormal &&
+          value.Distribution() == ContentDistributionType::kDefault)
              ? normal_value_behavior.Distribution()
              : value.Distribution();
 }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index 0c3005c..7b90d19 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -212,25 +212,25 @@
 
 enum ItemPositionType { kNonLegacyPosition, kLegacyPosition };
 
-enum ContentPosition {
-  kContentPositionNormal,
-  kContentPositionBaseline,
-  kContentPositionLastBaseline,
-  kContentPositionCenter,
-  kContentPositionStart,
-  kContentPositionEnd,
-  kContentPositionFlexStart,
-  kContentPositionFlexEnd,
-  kContentPositionLeft,
-  kContentPositionRight
+enum class ContentPosition : unsigned {
+  kNormal,
+  kBaseline,
+  kLastBaseline,
+  kCenter,
+  kStart,
+  kEnd,
+  kFlexStart,
+  kFlexEnd,
+  kLeft,
+  kRight
 };
 
-enum ContentDistributionType {
-  kContentDistributionDefault,
-  kContentDistributionSpaceBetween,
-  kContentDistributionSpaceAround,
-  kContentDistributionSpaceEvenly,
-  kContentDistributionStretch
+enum class ContentDistributionType : unsigned {
+  kDefault,
+  kSpaceBetween,
+  kSpaceAround,
+  kSpaceEvenly,
+  kStretch
 };
 
 // Reasonable maximum to prevent insane font sizes from causing crashes on some
diff --git a/third_party/WebKit/Source/core/style/StyleContentAlignmentData.h b/third_party/WebKit/Source/core/style/StyleContentAlignmentData.h
index b8123206..e81575de 100644
--- a/third_party/WebKit/Source/core/style/StyleContentAlignmentData.h
+++ b/third_party/WebKit/Source/core/style/StyleContentAlignmentData.h
@@ -21,11 +21,15 @@
       ContentPosition position,
       ContentDistributionType distribution,
       OverflowAlignment overflow = kOverflowAlignmentDefault)
-      : position_(position), distribution_(distribution), overflow_(overflow) {}
+      : position_(static_cast<unsigned>(position)),
+        distribution_(static_cast<unsigned>(distribution)),
+        overflow_(overflow) {}
 
-  void SetPosition(ContentPosition position) { position_ = position; }
+  void SetPosition(ContentPosition position) {
+    position_ = static_cast<unsigned>(position);
+  }
   void SetDistribution(ContentDistributionType distribution) {
-    distribution_ = distribution;
+    distribution_ = static_cast<unsigned>(distribution);
   }
   void SetOverflow(OverflowAlignment overflow) { overflow_ = overflow; }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
index ae75425..7c00d47a 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
@@ -23,7 +23,7 @@
 #include "core/svg/SVGAnimateElement.h"
 
 #include "core/css/CSSComputedStyleDeclaration.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleChangeReason.h"
 #include "core/dom/Document.h"
 #include "core/dom/QualifiedName.h"
diff --git a/third_party/WebKit/Source/core/svg/SVGElementRareData.cpp b/third_party/WebKit/Source/core/svg/SVGElementRareData.cpp
index 096e689..552136d 100644
--- a/third_party/WebKit/Source/core/svg/SVGElementRareData.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGElementRareData.cpp
@@ -4,6 +4,7 @@
 
 #include "core/svg/SVGElementRareData.h"
 
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
 #include "core/svg/SVGElementProxy.h"
diff --git a/third_party/WebKit/Source/core/svg/SVGURIReference.cpp b/third_party/WebKit/Source/core/svg/SVGURIReference.cpp
index 3a1f323..3f4ff48 100644
--- a/third_party/WebKit/Source/core/svg/SVGURIReference.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGURIReference.cpp
@@ -26,6 +26,7 @@
 #include "core/svg/SVGElement.h"
 #include "core/xlink_names.h"
 #include "platform/weborigin/KURL.h"
+#include "platform/wtf/Functional.h"
 
 namespace blink {
 
@@ -35,13 +36,13 @@
  public:
   SVGElementReferenceObserver(TreeScope& tree_scope,
                               const AtomicString& id,
-                              WTF::RepeatingClosure closure)
+                              base::RepeatingClosure closure)
       : IdTargetObserver(tree_scope.GetIdTargetObserverRegistry(), id),
         closure_(std::move(closure)) {}
 
  private:
   void IdTargetChanged() override { closure_.Run(); }
-  WTF::RepeatingClosure closure_;
+  base::RepeatingClosure closure_;
 };
 }
 
@@ -134,7 +135,7 @@
 Element* SVGURIReference::ObserveTarget(Member<IdTargetObserver>& observer,
                                         TreeScope& tree_scope,
                                         const AtomicString& id,
-                                        WTF::RepeatingClosure closure) {
+                                        base::RepeatingClosure closure) {
   DCHECK(!observer);
   if (id.IsEmpty())
     return nullptr;
diff --git a/third_party/WebKit/Source/core/svg/SVGURIReference.h b/third_party/WebKit/Source/core/svg/SVGURIReference.h
index 2911ef0..6b0e0e2b 100644
--- a/third_party/WebKit/Source/core/svg/SVGURIReference.h
+++ b/third_party/WebKit/Source/core/svg/SVGURIReference.h
@@ -22,10 +22,10 @@
 #define SVGURIReference_h
 
 #include <memory>
+#include "base/callback.h"
 #include "core/CoreExport.h"
 #include "core/svg/SVGAnimatedHref.h"
 #include "platform/heap/Handle.h"
-#include "platform/wtf/Functional.h"
 
 namespace blink {
 
@@ -71,7 +71,7 @@
   static Element* ObserveTarget(Member<IdTargetObserver>&,
                                 TreeScope&,
                                 const AtomicString& id,
-                                WTF::RepeatingClosure);
+                                base::RepeatingClosure);
   // Unregister and destroy the observer.
   static void UnobserveTarget(Member<IdTargetObserver>&);
 
diff --git a/third_party/WebKit/Source/core/testing/DictionaryTest.cpp b/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
index 1fa1661..30d6bd22 100644
--- a/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
+++ b/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
@@ -73,6 +73,10 @@
         testing_dictionary.dictionaryMember().GetOwnPropertiesAsStringHashMap(
             exception_state);
   }
+  if (testing_dictionary.hasInternalEnumOrInternalEnumSequenceMember()) {
+    internal_enum_or_internal_enum_sequence_ =
+        testing_dictionary.internalEnumOrInternalEnumSequenceMember();
+  }
 }
 
 void DictionaryTest::get(InternalDictionary& result) {
@@ -119,6 +123,8 @@
     result.setDoubleOrStringSequenceMember(
         double_or_string_sequence_member_.Get());
   result.setEventTargetOrNullMember(event_target_or_null_member_);
+  result.setInternalEnumOrInternalEnumSequenceMember(
+      internal_enum_or_internal_enum_sequence_);
 }
 
 ScriptValue DictionaryTest::getDictionaryMemberProperties(
@@ -219,6 +225,8 @@
   derived_string_member_with_default_ = String();
   required_boolean_member_ = false;
   dictionary_member_properties_ = nullptr;
+  internal_enum_or_internal_enum_sequence_ =
+      InternalEnumOrInternalEnumSequence();
 }
 
 void DictionaryTest::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/testing/DictionaryTest.h b/third_party/WebKit/Source/core/testing/DictionaryTest.h
index ce0cbbb1..c5ae647 100644
--- a/third_party/WebKit/Source/core/testing/DictionaryTest.h
+++ b/third_party/WebKit/Source/core/testing/DictionaryTest.h
@@ -8,6 +8,7 @@
 #include "bindings/core/v8/Nullable.h"
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/double_or_string.h"
+#include "bindings/core/v8/internal_enum_or_internal_enum_sequence.h"
 #include "core/dom/Element.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
@@ -89,6 +90,7 @@
   String derived_derived_string_member_;
   bool required_boolean_member_;
   Nullable<HashMap<String, String>> dictionary_member_properties_;
+  InternalEnumOrInternalEnumSequence internal_enum_or_internal_enum_sequence_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/InternalDictionary.idl b/third_party/WebKit/Source/core/testing/InternalDictionary.idl
index 6596f08..0ea3728 100644
--- a/third_party/WebKit/Source/core/testing/InternalDictionary.idl
+++ b/third_party/WebKit/Source/core/testing/InternalDictionary.idl
@@ -34,4 +34,5 @@
     sequence<(double or DOMString)> doubleOrStringSequenceMember;
     EventTarget? eventTargetOrNullMember = null;
     Dictionary dictionaryMember;
+    (InternalEnum or sequence<InternalEnum>) internalEnumOrInternalEnumSequenceMember;
 };
diff --git a/third_party/WebKit/Source/core/typed_arrays/FlexibleArrayBufferView.h b/third_party/WebKit/Source/core/typed_arrays/FlexibleArrayBufferView.h
index 50280ca..87029a9c 100644
--- a/third_party/WebKit/Source/core/typed_arrays/FlexibleArrayBufferView.h
+++ b/third_party/WebKit/Source/core/typed_arrays/FlexibleArrayBufferView.h
@@ -5,16 +5,15 @@
 #ifndef FlexibleArrayBufferView_h
 #define FlexibleArrayBufferView_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/typed_arrays/DOMArrayBufferView.h"
 #include "platform/heap/Handle.h"
-#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
 class CORE_EXPORT FlexibleArrayBufferView {
   STACK_ALLOCATED();
-  WTF_MAKE_NONCOPYABLE(FlexibleArrayBufferView);
 
  public:
   FlexibleArrayBufferView() : small_data_(nullptr), small_length_(0) {}
@@ -64,6 +63,7 @@
 
   void* small_data_;
   size_t small_length_;
+  DISALLOW_COPY_AND_ASSIGN(FlexibleArrayBufferView);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/typed_arrays/TypedFlexibleArrayBufferView.h b/third_party/WebKit/Source/core/typed_arrays/TypedFlexibleArrayBufferView.h
index 0452a02..0822126 100644
--- a/third_party/WebKit/Source/core/typed_arrays/TypedFlexibleArrayBufferView.h
+++ b/third_party/WebKit/Source/core/typed_arrays/TypedFlexibleArrayBufferView.h
@@ -5,9 +5,9 @@
 #ifndef TypedFlexibleArrayBufferView_h
 #define TypedFlexibleArrayBufferView_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/typed_arrays/FlexibleArrayBufferView.h"
-#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
@@ -15,7 +15,6 @@
 class CORE_TEMPLATE_CLASS_EXPORT TypedFlexibleArrayBufferView final
     : public FlexibleArrayBufferView {
   STACK_ALLOCATED();
-  WTF_MAKE_NONCOPYABLE(TypedFlexibleArrayBufferView);
 
  public:
   using ValueType = typename WTFTypedArray::ValueType;
@@ -30,6 +29,9 @@
     DCHECK_EQ(ByteLength() % sizeof(ValueType), 0u);
     return ByteLength() / sizeof(ValueType);
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TypedFlexibleArrayBufferView);
 };
 
 using FlexibleFloat32ArrayView =
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp
index 1ddf997..9d5d83d22 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp
@@ -83,9 +83,8 @@
 
   auto global_scope_creation_params =
       std::make_unique<GlobalScopeCreationParams>(
-          script_url, user_agent, source_code, nullptr, csp->Headers().get(),
-          referrer_policy, starter_origin, ReleaseWorkerClients(),
-          document->AddressSpace(),
+          script_url, user_agent, csp->Headers().get(), referrer_policy,
+          starter_origin, ReleaseWorkerClients(), document->AddressSpace(),
           OriginTrialContext::GetTokens(document).get(),
           std::make_unique<WorkerSettings>(document->GetSettings()),
           kV8CacheOptionsDefault,
@@ -94,7 +93,7 @@
 
   InitializeWorkerThread(std::move(global_scope_creation_params),
                          CreateBackingThreadStartupData(ToIsolate(document)),
-                         script_url, stack_id);
+                         script_url, stack_id, source_code);
 }
 
 void DedicatedWorkerMessagingProxy::PostMessageToWorkerGlobalScope(
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h
index 98d3e01..d0b23fe8 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h
@@ -6,6 +6,7 @@
 #define DedicatedWorkerMessagingProxy_h
 
 #include <memory>
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/CoreExport.h"
 #include "core/dom/MessagePort.h"
@@ -13,7 +14,6 @@
 #include "core/workers/WorkerBackingThreadStartupData.h"
 #include "platform/heap/Handle.h"
 #include "platform/weborigin/ReferrerPolicy.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/Optional.h"
 
 namespace v8_inspector {
@@ -32,8 +32,6 @@
 // comments on ThreadedMessagingProxyBase for the lifetime and thread affinity.
 class CORE_EXPORT DedicatedWorkerMessagingProxy
     : public ThreadedMessagingProxyBase {
-  WTF_MAKE_NONCOPYABLE(DedicatedWorkerMessagingProxy);
-
  public:
   DedicatedWorkerMessagingProxy(ExecutionContext*,
                                 DedicatedWorker*,
@@ -91,6 +89,7 @@
   // Tasks are queued here until there's a thread object created.
   struct QueuedTask;
   Vector<QueuedTask> queued_early_tasks_;
+  DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerMessagingProxy);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerObjectProxy.h b/third_party/WebKit/Source/core/workers/DedicatedWorkerObjectProxy.h
index f73f652..7754b2e 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerObjectProxy.h
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerObjectProxy.h
@@ -32,6 +32,7 @@
 #define DedicatedWorkerObjectProxy_h
 
 #include <memory>
+#include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "core/CoreExport.h"
 #include "core/dom/MessagePort.h"
@@ -57,7 +58,6 @@
 // ThreadedObjectProxyBase.h for the lifetime and thread affinity.
 class CORE_EXPORT DedicatedWorkerObjectProxy : public ThreadedObjectProxyBase {
   USING_FAST_MALLOC(DedicatedWorkerObjectProxy);
-  WTF_MAKE_NONCOPYABLE(DedicatedWorkerObjectProxy);
 
  public:
   static std::unique_ptr<DedicatedWorkerObjectProxy> Create(
@@ -98,6 +98,7 @@
       messaging_proxy_weak_ptr_;
 
   CrossThreadPersistent<WorkerGlobalScope> worker_global_scope_;
+  DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerObjectProxy);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
index 9f436c6c..10d5781 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
@@ -130,8 +130,7 @@
         ToDocument(GetExecutionContext())->GetSettings());
     InitializeWorkerThread(
         std::make_unique<GlobalScopeCreationParams>(
-            script_url, "fake user agent", source,
-            nullptr /* cached_meta_data */, headers.get(),
+            script_url, "fake user agent", headers.get(),
             kReferrerPolicyDefault, security_origin_.get(),
             nullptr /* worker_clients */, kWebAddressSpaceLocal,
             nullptr /* origin_trial_tokens */, std::move(worker_settings),
@@ -139,7 +138,7 @@
         WorkerBackingThreadStartupData(
             WorkerBackingThreadStartupData::HeapLimitMode::kDefault,
             WorkerBackingThreadStartupData::AtomicsWaitMode::kAllow),
-        script_url, v8_inspector::V8StackTraceId());
+        script_url, v8_inspector::V8StackTraceId(), source);
   }
 
   DedicatedWorkerThreadForTest* GetDedicatedWorkerThread() {
diff --git a/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.cpp b/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.cpp
index 586494dd..5fe3e1e 100644
--- a/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.cpp
+++ b/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.cpp
@@ -13,8 +13,6 @@
 GlobalScopeCreationParams::GlobalScopeCreationParams(
     const KURL& script_url,
     const String& user_agent,
-    const String& source_code,
-    std::unique_ptr<Vector<char>> cached_meta_data,
     const Vector<CSPHeaderAndType>* content_security_policy_parsed_headers,
     ReferrerPolicy referrer_policy,
     const SecurityOrigin* starter_origin,
@@ -27,8 +25,6 @@
         interface_provider_info)
     : script_url(script_url.Copy()),
       user_agent(user_agent.IsolatedCopy()),
-      source_code(source_code.IsolatedCopy()),
-      cached_meta_data(std::move(cached_meta_data)),
       referrer_policy(referrer_policy),
       starter_origin(starter_origin ? starter_origin->IsolatedCopy() : nullptr),
       worker_clients(worker_clients),
diff --git a/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.h b/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.h
index f38a9ce..60ccd2b 100644
--- a/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.h
+++ b/third_party/WebKit/Source/core/workers/GlobalScopeCreationParams.h
@@ -6,6 +6,7 @@
 #define GlobalScopeCreationParams_h
 
 #include <memory>
+#include "base/macros.h"
 #include "bindings/core/v8/V8CacheOptions.h"
 #include "core/CoreExport.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
@@ -16,7 +17,6 @@
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/ReferrerPolicy.h"
 #include "platform/wtf/Forward.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/Optional.h"
 #include "platform/wtf/PtrUtil.h"
 #include "public/platform/WebAddressSpace.h"
@@ -29,15 +29,12 @@
 // GlobalScopeCreationParams contains parameters for initializing
 // WorkerGlobalScope or WorkletGlobalScope.
 struct CORE_EXPORT GlobalScopeCreationParams final {
-  WTF_MAKE_NONCOPYABLE(GlobalScopeCreationParams);
   USING_FAST_MALLOC(GlobalScopeCreationParams);
 
  public:
   GlobalScopeCreationParams(
       const KURL& script_url,
       const String& user_agent,
-      const String& source_code,
-      std::unique_ptr<Vector<char>> cached_meta_data,
       const Vector<CSPHeaderAndType>* content_security_policy_parsed_headers,
       ReferrerPolicy referrer_policy,
       const SecurityOrigin*,
@@ -52,8 +49,6 @@
 
   KURL script_url;
   String user_agent;
-  String source_code;
-  std::unique_ptr<Vector<char>> cached_meta_data;
 
   // |content_security_policy_parsed_headers| and
   // |content_security_policy_raw_headers| are mutually exclusive.
@@ -99,6 +94,8 @@
   V8CacheOptions v8_cache_options;
 
   service_manager::mojom::blink::InterfaceProviderPtrInfo interface_provider;
+
+  DISALLOW_COPY_AND_ASSIGN(GlobalScopeCreationParams);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp b/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp
index 917dfdc1..3cf05a4 100644
--- a/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp
+++ b/third_party/WebKit/Source/core/workers/MainThreadWorkletTest.cpp
@@ -47,12 +47,20 @@
     Document* document = page_->GetFrame().GetDocument();
     document->SetURL(KURL("https://example.com/"));
     document->UpdateSecurityOrigin(SecurityOrigin::Create(document->Url()));
+
+    // Set up the CSP for Document before starting MainThreadWorklet because
+    // MainThreadWorklet inherits the owner Document's CSP.
+    ContentSecurityPolicy* csp = ContentSecurityPolicy::Create();
+    csp->DidReceiveHeader("script-src 'self' https://allowed.example.com",
+                          kContentSecurityPolicyHeaderTypeEnforce,
+                          kContentSecurityPolicyHeaderSourceHTTP);
+    document->InitContentSecurityPolicy(csp);
+
     reporting_proxy_ =
         std::make_unique<MainThreadWorkletReportingProxyForTest>(document);
     auto creation_params = std::make_unique<GlobalScopeCreationParams>(
-        document->Url(), document->UserAgent(), String() /* source_code */,
-        nullptr /* cached_meta_data */,
-        nullptr /* content_security_policy_parsed_headers */,
+        document->Url(), document->UserAgent(),
+        document->GetContentSecurityPolicy()->Headers().get(),
         document->GetReferrerPolicy(), document->GetSecurityOrigin(),
         nullptr /* worker_clients */, document->AddressSpace(),
         OriginTrialContext::GetTokens(document).get(),
@@ -77,6 +85,24 @@
   EXPECT_FALSE(global_scope_->DocumentSecurityOrigin()->IsUnique());
 }
 
+TEST_F(MainThreadWorkletTest, ContentSecurityPolicy) {
+  ContentSecurityPolicy* csp = global_scope_->GetContentSecurityPolicy();
+
+  // The "script-src 'self'" directive is specified but the Worklet has a
+  // unique opaque origin, so this should not be allowed.
+  EXPECT_FALSE(csp->AllowScriptFromSource(
+      global_scope_->Url(), String(), IntegrityMetadataSet(), kParserInserted));
+
+  // The "script-src https://allowed.example.com" should allow this.
+  EXPECT_TRUE(csp->AllowScriptFromSource(KURL("https://allowed.example.com"),
+                                         String(), IntegrityMetadataSet(),
+                                         kParserInserted));
+
+  EXPECT_FALSE(csp->AllowScriptFromSource(
+      KURL("https://disallowed.example.com"), String(), IntegrityMetadataSet(),
+      kParserInserted));
+}
+
 TEST_F(MainThreadWorkletTest, UseCounter) {
   Document& document = *page_->GetFrame().GetDocument();
 
diff --git a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h
index 3e7930a..91b93390 100644
--- a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h
+++ b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.h
@@ -6,12 +6,12 @@
 #define ParentFrameTaskRunners_h
 
 #include <memory>
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/dom/ContextLifecycleObserver.h"
 #include "core/dom/TaskTypeTraits.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Allocator.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/PtrUtil.h"
 
 namespace blink {
@@ -27,7 +27,6 @@
     : public GarbageCollectedFinalized<ParentFrameTaskRunners>,
       public ContextLifecycleObserver {
   USING_GARBAGE_COLLECTED_MIXIN(ParentFrameTaskRunners);
-  WTF_MAKE_NONCOPYABLE(ParentFrameTaskRunners);
 
  public:
   // Returns task runners associated with a given frame. This must be called on
@@ -60,6 +59,7 @@
 
   Mutex task_runners_mutex_;
   TaskRunnerHashMap task_runners_;
+  DISALLOW_COPY_AND_ASSIGN(ParentFrameTaskRunners);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/SharedWorkerReportingProxy.h b/third_party/WebKit/Source/core/workers/SharedWorkerReportingProxy.h
index d7794fd6..a7797d6 100644
--- a/third_party/WebKit/Source/core/workers/SharedWorkerReportingProxy.h
+++ b/third_party/WebKit/Source/core/workers/SharedWorkerReportingProxy.h
@@ -5,6 +5,7 @@
 #ifndef SharedWorkerReportingProxy_h
 #define SharedWorkerReportingProxy_h
 
+#include "base/macros.h"
 #include "core/workers/ParentFrameTaskRunners.h"
 #include "core/workers/WorkerReportingProxy.h"
 #include "platform/heap/GarbageCollected.h"
@@ -19,8 +20,6 @@
 class SharedWorkerReportingProxy final
     : public GarbageCollectedFinalized<SharedWorkerReportingProxy>,
       public WorkerReportingProxy {
-  WTF_MAKE_NONCOPYABLE(SharedWorkerReportingProxy);
-
  public:
   SharedWorkerReportingProxy(WebSharedWorkerImpl*, ParentFrameTaskRunners*);
   ~SharedWorkerReportingProxy() override;
@@ -48,6 +47,7 @@
   WebSharedWorkerImpl* worker_;
 
   Member<ParentFrameTaskRunners> parent_frame_task_runners_;
+  DISALLOW_COPY_AND_ASSIGN(SharedWorkerReportingProxy);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h b/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
index 582d9648..23988412 100644
--- a/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
+++ b/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
@@ -31,10 +31,10 @@
 #ifndef SharedWorkerRepositoryClient_h
 #define SharedWorkerRepositoryClient_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Forward.h"
-#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
@@ -44,7 +44,6 @@
 class SharedWorker;
 
 class CORE_EXPORT SharedWorkerRepositoryClient {
-  WTF_MAKE_NONCOPYABLE(SharedWorkerRepositoryClient);
   DISALLOW_NEW();
 
  public:
@@ -57,6 +56,9 @@
                        const String& name) = 0;
 
   virtual void DocumentDetached(Document*) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SharedWorkerRepositoryClient);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
index 558e912..8107f8e 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
@@ -76,7 +76,8 @@
     std::unique_ptr<GlobalScopeCreationParams> global_scope_creation_params,
     const WTF::Optional<WorkerBackingThreadStartupData>& thread_startup_data,
     const KURL& script_url,
-    const v8_inspector::V8StackTraceId& stack_id) {
+    const v8_inspector::V8StackTraceId& stack_id,
+    const String& source_code) {
   DCHECK(IsParentContextThread());
 
   Document* document = ToDocument(GetExecutionContext());
@@ -87,7 +88,7 @@
       std::make_unique<GlobalScopeInspectorCreationParams>(
           GetWorkerInspectorProxy()->ShouldPauseOnWorkerStart(document),
           stack_id),
-      GetParentFrameTaskRunners());
+      GetParentFrameTaskRunners(), source_code);
   WorkerThreadCreated();
   GetWorkerInspectorProxy()->WorkerThreadCreated(document, GetWorkerThread(),
                                                  script_url);
diff --git a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h
index 789e9120..1ffff1ef 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h
@@ -76,7 +76,8 @@
       std::unique_ptr<GlobalScopeCreationParams>,
       const WTF::Optional<WorkerBackingThreadStartupData>&,
       const KURL& script_url,
-      const v8_inspector::V8StackTraceId&);
+      const v8_inspector::V8StackTraceId&,
+      const String& source_code = String());
   virtual void WorkerThreadCreated();
 
   ThreadableLoadingContext* CreateThreadableLoadingContext() const;
diff --git a/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.h b/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.h
index 2dd10c9..74222496 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedObjectProxyBase.h
@@ -5,6 +5,7 @@
 #ifndef ThreadedObjectProxyBase_h
 #define ThreadedObjectProxyBase_h
 
+#include "base/macros.h"
 #include "bindings/core/v8/SourceLocation.h"
 #include "core/CoreExport.h"
 #include "core/dom/MessagePort.h"
@@ -21,8 +22,6 @@
 // ThreadedMessagingProxyBase always outlives this proxy.
 class CORE_EXPORT ThreadedObjectProxyBase : public WorkerReportingProxy {
   USING_FAST_MALLOC(ThreadedObjectProxyBase);
-  WTF_MAKE_NONCOPYABLE(ThreadedObjectProxyBase);
-
  public:
   ~ThreadedObjectProxyBase() override = default;
 
@@ -49,6 +48,7 @@
   // Used to post a task to ThreadedMessagingProxyBase on the parent context
   // thread.
   CrossThreadPersistent<ParentFrameTaskRunners> parent_frame_task_runners_;
+  DISALLOW_COPY_AND_ASSIGN(ThreadedObjectProxyBase);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp
index a6b5d12..51254bb 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp
@@ -40,8 +40,7 @@
 
   auto global_scope_creation_params =
       std::make_unique<GlobalScopeCreationParams>(
-          document->Url(), document->UserAgent(), String() /* source_code */,
-          nullptr /* cached_meta_data */, csp->Headers().get(),
+          document->Url(), document->UserAgent(), csp->Headers().get(),
           document->GetReferrerPolicy(), document->GetSecurityOrigin(),
           ReleaseWorkerClients(), document->AddressSpace(),
           OriginTrialContext::GetTokens(document).get(),
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h
index e77358ed3..e54808a 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletObjectProxy.h
@@ -5,6 +5,7 @@
 #ifndef ThreadedWorkletObjectProxy_h
 #define ThreadedWorkletObjectProxy_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/workers/ThreadedObjectProxyBase.h"
 #include "core/workers/WorkerReportingProxy.h"
@@ -25,7 +26,6 @@
 // module script loading.
 class CORE_EXPORT ThreadedWorkletObjectProxy : public ThreadedObjectProxyBase {
   USING_FAST_MALLOC(ThreadedWorkletObjectProxy);
-  WTF_MAKE_NONCOPYABLE(ThreadedWorkletObjectProxy);
 
  public:
   static std::unique_ptr<ThreadedWorkletObjectProxy> Create(
@@ -54,6 +54,7 @@
   // the tasks.
   CrossThreadWeakPersistent<ThreadedWorkletMessagingProxy>
       messaging_proxy_weak_ptr_;
+  DISALLOW_COPY_AND_ASSIGN(ThreadedWorkletObjectProxy);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
index e61bb12e..d983e695 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
@@ -88,6 +88,30 @@
         ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop));
   }
 
+  void TestContentSecurityPolicy() {
+    EXPECT_TRUE(IsCurrentThread());
+    ContentSecurityPolicy* csp = GlobalScope()->GetContentSecurityPolicy();
+
+    // The "script-src 'self'" directive is specified but the Worklet has a
+    // unique opaque origin, so this should not be allowed.
+    EXPECT_FALSE(csp->AllowScriptFromSource(GlobalScope()->Url(), String(),
+                                            IntegrityMetadataSet(),
+                                            kParserInserted));
+
+    // The "script-src https://allowed.example.com" should allow this.
+    EXPECT_TRUE(csp->AllowScriptFromSource(KURL("https://allowed.example.com"),
+                                           String(), IntegrityMetadataSet(),
+                                           kParserInserted));
+
+    EXPECT_FALSE(csp->AllowScriptFromSource(
+        KURL("https://disallowed.example.com"), String(),
+        IntegrityMetadataSet(), kParserInserted));
+
+    GetParentFrameTaskRunners()
+        ->Get(TaskType::kUnspecedTimer)
+        ->PostTask(BLINK_FROM_HERE, CrossThreadBind(&testing::ExitRunLoop));
+  }
+
   // Emulates API use on ThreadedWorkletGlobalScope.
   void CountFeature(WebFeature feature) {
     EXPECT_TRUE(IsCurrentThread());
@@ -147,13 +171,12 @@
   void Start() {
     Document* document = ToDocument(GetExecutionContext());
     std::unique_ptr<Vector<char>> cached_meta_data = nullptr;
-    Vector<CSPHeaderAndType> content_security_policy_headers;
     WorkerClients* worker_clients = nullptr;
     std::unique_ptr<WorkerSettings> worker_settings = nullptr;
     InitializeWorkerThread(
         std::make_unique<GlobalScopeCreationParams>(
-            document->Url(), document->UserAgent(), "" /* source_code */,
-            std::move(cached_meta_data), &content_security_policy_headers,
+            document->Url(), document->UserAgent(),
+            document->GetContentSecurityPolicy()->Headers().get(),
             document->GetReferrerPolicy(), document->GetSecurityOrigin(),
             worker_clients, document->AddressSpace(),
             OriginTrialContext::GetTokens(document).get(),
@@ -217,6 +240,26 @@
   testing::EnterRunLoop();
 }
 
+TEST_F(ThreadedWorkletTest, ContentSecurityPolicy) {
+  // Set up the CSP for Document before starting ThreadedWorklet because
+  // ThreadedWorklet inherits the owner Document's CSP.
+  ContentSecurityPolicy* csp = ContentSecurityPolicy::Create();
+  csp->DidReceiveHeader("script-src 'self' https://allowed.example.com",
+                        kContentSecurityPolicyHeaderTypeEnforce,
+                        kContentSecurityPolicyHeaderSourceHTTP);
+  GetDocument().InitContentSecurityPolicy(csp);
+
+  MessagingProxy()->Start();
+
+  GetWorkerThread()
+      ->GetTaskRunner(TaskType::kUnspecedTimer)
+      ->PostTask(BLINK_FROM_HERE,
+                 CrossThreadBind(
+                     &ThreadedWorkletThreadForTest::TestContentSecurityPolicy,
+                     CrossThreadUnretained(GetWorkerThread())));
+  testing::EnterRunLoop();
+}
+
 TEST_F(ThreadedWorkletTest, UseCounter) {
   MessagingProxy()->Start();
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerClients.h b/third_party/WebKit/Source/core/workers/WorkerClients.h
index 37d6db94..82686978 100644
--- a/third_party/WebKit/Source/core/workers/WorkerClients.h
+++ b/third_party/WebKit/Source/core/workers/WorkerClients.h
@@ -31,10 +31,10 @@
 #ifndef WorkerClients_h
 #define WorkerClients_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "platform/Supplementable.h"
 #include "platform/wtf/Forward.h"
-#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
@@ -45,7 +45,6 @@
 class CORE_EXPORT WorkerClients final : public GarbageCollected<WorkerClients>,
                                         public Supplementable<WorkerClients> {
   USING_GARBAGE_COLLECTED_MIXIN(WorkerClients);
-  WTF_MAKE_NONCOPYABLE(WorkerClients);
 
  public:
   static WorkerClients* Create() { return new WorkerClients; }
@@ -56,6 +55,7 @@
 
  private:
   WorkerClients() {}
+  DISALLOW_COPY_AND_ASSIGN(WorkerClients);
 };
 
 extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<WorkerClients>;
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index b125b54..736d0bc 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -382,20 +382,6 @@
       worker_settings_->GetGenericFontFamilySettings());
 }
 
-void WorkerGlobalScope::ApplyContentSecurityPolicyFromVector(
-    const Vector<CSPHeaderAndType>& headers) {
-  if (!GetContentSecurityPolicy()) {
-    ContentSecurityPolicy* csp = ContentSecurityPolicy::Create();
-    SetContentSecurityPolicy(csp);
-  }
-  for (const auto& policy_and_type : headers) {
-    GetContentSecurityPolicy()->DidReceiveHeader(
-        policy_and_type.first, policy_and_type.second,
-        kContentSecurityPolicyHeaderSourceHTTP);
-  }
-  GetContentSecurityPolicy()->BindToExecutionContext(GetExecutionContext());
-}
-
 void WorkerGlobalScope::Trace(blink::Visitor* visitor) {
   visitor->Trace(location_);
   visitor->Trace(navigator_);
@@ -403,7 +389,6 @@
   visitor->Trace(pending_error_events_);
   visitor->Trace(font_selector_);
   WorkerOrWorkletGlobalScope::Trace(visitor);
-  SecurityContext::Trace(visitor);
   Supplementable<WorkerGlobalScope>::Trace(visitor);
 }
 
@@ -411,6 +396,7 @@
     const ScriptWrappableVisitor* visitor) const {
   Supplementable<WorkerGlobalScope>::TraceWrappers(visitor);
   WorkerOrWorkletGlobalScope::TraceWrappers(visitor);
+  visitor->TraceWrappers(navigator_);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
index 4a2cb0b..05c3c19 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -61,16 +61,12 @@
 class CORE_EXPORT WorkerGlobalScope
     : public WorkerOrWorkletGlobalScope,
       public ActiveScriptWrappable<WorkerGlobalScope>,
-      public SecurityContext,
       public Supplementable<WorkerGlobalScope>,
       public DOMWindowBase64 {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(WorkerGlobalScope);
 
  public:
-  using SecurityContext::GetSecurityOrigin;
-  using SecurityContext::GetContentSecurityPolicy;
-
   ~WorkerGlobalScope() override;
 
   // Returns null if caching is not supported.
@@ -153,8 +149,6 @@
 
  private:
   void SetWorkerSettings(std::unique_ptr<WorkerSettings>);
-  void ApplyContentSecurityPolicyFromVector(
-      const Vector<CSPHeaderAndType>& headers);
 
   // |kNotHandled| is used when the script was not in
   // InstalledScriptsManager, which means it was not an installed script.
@@ -185,16 +179,13 @@
   // ExecutionContext
   EventTarget* ErrorEventTarget() final { return this; }
 
-  // SecurityContext
-  void DidUpdateSecurityOrigin() final {}
-
   const KURL url_;
   const String user_agent_;
   const V8CacheOptions v8_cache_options_;
   std::unique_ptr<WorkerSettings> worker_settings_;
 
   mutable Member<WorkerLocation> location_;
-  mutable Member<WorkerNavigator> navigator_;
+  mutable TraceWrapperMember<WorkerNavigator> navigator_;
 
   WorkerThread* thread_;
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h b/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h
index 0b76a33..59906fd 100644
--- a/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h
+++ b/third_party/WebKit/Source/core/workers/WorkerInspectorProxy.h
@@ -5,6 +5,7 @@
 #ifndef WorkerInspectorProxy_h
 #define WorkerInspectorProxy_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/inspector/ThreadDebugger.h"
@@ -75,7 +76,6 @@
 };
 
 struct CORE_EXPORT GlobalScopeInspectorCreationParams final {
-  WTF_MAKE_NONCOPYABLE(GlobalScopeInspectorCreationParams);
   USING_FAST_MALLOC(GlobalScopeInspectorCreationParams);
 
  public:
@@ -88,6 +88,9 @@
 
   WorkerInspectorProxy::PauseOnWorkerStart pause_on_start;
   v8_inspector::V8StackTraceId stack_id;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GlobalScopeInspectorCreationParams);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp b/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp
index b0206c0..a43c515 100644
--- a/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp
@@ -42,4 +42,10 @@
   Supplementable<WorkerNavigator>::Trace(visitor);
 }
 
+void WorkerNavigator::TraceWrappers(
+    const ScriptWrappableVisitor* visitor) const {
+  ScriptWrappable::TraceWrappers(visitor);
+  Supplementable<WorkerNavigator>::TraceWrappers(visitor);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkerNavigator.h b/third_party/WebKit/Source/core/workers/WorkerNavigator.h
index 50c791d..780037b 100644
--- a/third_party/WebKit/Source/core/workers/WorkerNavigator.h
+++ b/third_party/WebKit/Source/core/workers/WorkerNavigator.h
@@ -55,6 +55,7 @@
   String userAgent() const override;
 
   void Trace(blink::Visitor*) override;
+  void TraceWrappers(const ScriptWrappableVisitor*) const override;
 
  private:
   explicit WorkerNavigator(const String&);
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
index 9511324..3d55d621 100644
--- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.cpp
@@ -184,6 +184,20 @@
   return GetThread()->GetTaskRunner(type);
 }
 
+void WorkerOrWorkletGlobalScope::ApplyContentSecurityPolicyFromVector(
+    const Vector<CSPHeaderAndType>& headers) {
+  if (!GetContentSecurityPolicy()) {
+    ContentSecurityPolicy* csp = ContentSecurityPolicy::Create();
+    SetContentSecurityPolicy(csp);
+  }
+  for (const auto& policy_and_type : headers) {
+    GetContentSecurityPolicy()->DidReceiveHeader(
+        policy_and_type.first, policy_and_type.second,
+        kContentSecurityPolicyHeaderSourceHTTP);
+  }
+  GetContentSecurityPolicy()->BindToExecutionContext(GetExecutionContext());
+}
+
 void WorkerOrWorkletGlobalScope::Trace(blink::Visitor* visitor) {
   visitor->Trace(resource_fetcher_);
   visitor->Trace(script_controller_);
@@ -192,6 +206,7 @@
   visitor->Trace(modulator_);
   EventTargetWithInlineData::Trace(visitor);
   ExecutionContext::Trace(visitor);
+  SecurityContext::Trace(visitor);
 }
 
 void WorkerOrWorkletGlobalScope::TraceWrappers(
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
index a3a858a..a082088f 100644
--- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
@@ -7,8 +7,10 @@
 
 #include "bindings/core/v8/V8CacheOptions.h"
 #include "core/dom/ExecutionContext.h"
+#include "core/dom/SecurityContext.h"
 #include "core/dom/events/EventTarget.h"
 #include "core/frame/WebFeatureForward.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerClients.h"
 #include "core/workers/WorkerEventQueue.h"
 #include "platform/wtf/BitVector.h"
@@ -23,8 +25,12 @@
 class WorkerThread;
 
 class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
-                                               public ExecutionContext {
+                                               public ExecutionContext,
+                                               public SecurityContext {
  public:
+  using SecurityContext::GetSecurityOrigin;
+  using SecurityContext::GetContentSecurityPolicy;
+
   WorkerOrWorkletGlobalScope(v8::Isolate*,
                              WorkerClients*,
                              WorkerReportingProxy&);
@@ -49,6 +55,9 @@
   bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) final;
   EventQueue* GetEventQueue() const final;
 
+  // SecurityContext
+  void DidUpdateSecurityOrigin() final {}
+
   // Evaluates the given main script as a classic script (as opposed to a module
   // script).
   // https://html.spec.whatwg.org/multipage/webappapis.html#classic-script
@@ -100,6 +109,10 @@
 
   scoped_refptr<WebTaskRunner> GetTaskRunner(TaskType) override;
 
+ protected:
+  void ApplyContentSecurityPolicyFromVector(
+      const Vector<CSPHeaderAndType>& headers);
+
  private:
   CrossThreadPersistent<WorkerClients> worker_clients_;
   Member<ResourceFetcher> resource_fetcher_;
diff --git a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
index 2c8701e..c59f2f8 100644
--- a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
@@ -95,8 +95,8 @@
     network::mojom::FetchRequestMode fetch_request_mode,
     network::mojom::FetchCredentialsMode fetch_credentials_mode,
     WebAddressSpace creation_address_space,
-    WTF::Closure response_callback,
-    WTF::Closure finished_callback) {
+    base::OnceClosure response_callback,
+    base::OnceClosure finished_callback) {
   DCHECK(response_callback || finished_callback);
   response_callback_ = std::move(response_callback);
   finished_callback_ = std::move(finished_callback);
diff --git a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
index e123989..b67e6b6 100644
--- a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
+++ b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
@@ -73,8 +73,8 @@
                           network::mojom::FetchRequestMode,
                           network::mojom::FetchCredentialsMode,
                           WebAddressSpace,
-                          WTF::Closure response_callback,
-                          WTF::Closure finished_callback);
+                          base::OnceClosure response_callback,
+                          base::OnceClosure finished_callback);
 
   // This will immediately invoke |finishedCallback| if loadAsynchronously()
   // is in progress.
@@ -132,8 +132,8 @@
   void ProcessContentSecurityPolicy(const ResourceResponse&);
 
   // Callbacks for loadAsynchronously().
-  WTF::Closure response_callback_;
-  WTF::Closure finished_callback_;
+  base::OnceClosure response_callback_;
+  base::OnceClosure finished_callback_;
 
   Persistent<ThreadableLoader> threadable_loader_;
   String response_encoding_;
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index d77fccb..0f0cd2d 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -53,7 +53,6 @@
 #include "platform/scheduler/child/worker_global_scope_scheduler.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/wtf/Functional.h"
-#include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/PtrUtil.h"
 #include "platform/wtf/Threading.h"
 #include "platform/wtf/text/WTFString.h"
@@ -101,7 +100,9 @@
     const WTF::Optional<WorkerBackingThreadStartupData>& thread_startup_data,
     std::unique_ptr<GlobalScopeInspectorCreationParams>
         global_scope_inspector_creation_params,
-    ParentFrameTaskRunners* parent_frame_task_runners) {
+    ParentFrameTaskRunners* parent_frame_task_runners,
+    const String& source_code,
+    std::unique_ptr<Vector<char>> cached_meta_data) {
   DCHECK(IsMainThread());
   DCHECK(!parent_frame_task_runners_);
   parent_frame_task_runners_ = parent_frame_task_runners;
@@ -122,7 +123,8 @@
           &WorkerThread::InitializeOnWorkerThread, CrossThreadUnretained(this),
           WTF::Passed(std::move(global_scope_creation_params)),
           thread_startup_data,
-          WTF::Passed(std::move(global_scope_inspector_creation_params))));
+          WTF::Passed(std::move(global_scope_inspector_creation_params)),
+          source_code, WTF::Passed(std::move(cached_meta_data))));
 }
 
 void WorkerThread::Terminate() {
@@ -385,18 +387,14 @@
     std::unique_ptr<GlobalScopeCreationParams> global_scope_creation_params,
     const WTF::Optional<WorkerBackingThreadStartupData>& thread_startup_data,
     std::unique_ptr<GlobalScopeInspectorCreationParams>
-        global_scope_inspector_creation_params) {
+        global_scope_inspector_creation_params,
+    String source_code,
+    std::unique_ptr<Vector<char>> cached_meta_data) {
   DCHECK(IsCurrentThread());
   DCHECK_EQ(ThreadState::kNotStarted, thread_state_);
 
   KURL script_url = global_scope_creation_params->script_url;
 
-  // TODO(nhiroki): Separate these fields from GlobalScopeCreationParams because
-  // these are used not for creating a global scope but for evaluating a script.
-  String source_code = std::move(global_scope_creation_params->source_code);
-  std::unique_ptr<Vector<char>> cached_meta_data =
-      std::move(global_scope_creation_params->cached_meta_data);
-
   {
     MutexLocker lock(thread_state_mutex_);
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.h b/third_party/WebKit/Source/core/workers/WorkerThread.h
index 6bb07a4..d76e0bc 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.h
@@ -88,8 +88,10 @@
 
   // Starts the underlying thread and creates the global scope. Called on the
   // main thread.
-  // Startup data for WorkerBackingThread must be WTF::nullopt if |this| doesn't
-  // own the underlying WorkerBackingThread.
+  // Startup data for WorkerBackingThread is WTF::nullopt if |this| doesn't own
+  // the underlying WorkerBackingThread. |source_code| is empty for module
+  // scripts or installed scripts. |cached_meta_data| is nullptr if the global
+  // scope to be created doesn't use V8 code caching.
   // TODO(nhiroki): We could separate WorkerBackingThread initialization from
   // GlobalScope initialization sequence, that is, InitializeOnWorkerThread().
   // After that, we could remove this startup data for WorkerBackingThread.
@@ -97,7 +99,9 @@
   void Start(std::unique_ptr<GlobalScopeCreationParams>,
              const WTF::Optional<WorkerBackingThreadStartupData>&,
              std::unique_ptr<GlobalScopeInspectorCreationParams>,
-             ParentFrameTaskRunners*);
+             ParentFrameTaskRunners*,
+             const String& source_code = String(),
+             std::unique_ptr<Vector<char>> cached_meta_data = nullptr);
 
   // Closes the global scope and terminates the underlying thread. Called on the
   // main thread.
@@ -237,7 +241,9 @@
   void InitializeOnWorkerThread(
       std::unique_ptr<GlobalScopeCreationParams>,
       const WTF::Optional<WorkerBackingThreadStartupData>&,
-      std::unique_ptr<GlobalScopeInspectorCreationParams>);
+      std::unique_ptr<GlobalScopeInspectorCreationParams>,
+      String source_code,
+      std::unique_ptr<Vector<char>> cached_meta_data);
 
   // These are called in this order during worker thread termination.
   void PrepareForShutdownOnWorkerThread();
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadLifecycleContext.h b/third_party/WebKit/Source/core/workers/WorkerThreadLifecycleContext.h
index df13fe3d..8b2f0ed8 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadLifecycleContext.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadLifecycleContext.h
@@ -5,10 +5,10 @@
 #ifndef WorkerThreadLifecycleContext_h
 #define WorkerThreadLifecycleContext_h
 
+#include "base/macros.h"
 #include "core/CoreExport.h"
 #include "platform/LifecycleNotifier.h"
 #include "platform/heap/GarbageCollected.h"
-#include "platform/wtf/Noncopyable.h"
 
 namespace blink {
 
@@ -22,7 +22,6 @@
       public LifecycleNotifier<WorkerThreadLifecycleContext,
                                WorkerThreadLifecycleObserver> {
   USING_GARBAGE_COLLECTED_MIXIN(WorkerThreadLifecycleContext);
-  WTF_MAKE_NONCOPYABLE(WorkerThreadLifecycleContext);
 
  public:
   WorkerThreadLifecycleContext();
@@ -32,6 +31,7 @@
  private:
   friend class WorkerThreadLifecycleObserver;
   bool was_context_destroyed_ = false;
+  DISALLOW_COPY_AND_ASSIGN(WorkerThreadLifecycleContext);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
index 460a30b..f45ff5cc 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
@@ -298,10 +298,10 @@
 
   auto global_scope_creation_params =
       std::make_unique<GlobalScopeCreationParams>(
-          KURL("http://fake.url/"), "fake user agent", "// fake source code",
-          nullptr /* cachedMetaData */, headers.get(), kReferrerPolicyDefault,
-          security_origin_.get(), nullptr /* workerClients */,
-          kWebAddressSpaceLocal, nullptr /* originTrialToken */,
+          KURL("http://fake.url/"), "fake user agent", headers.get(),
+          kReferrerPolicyDefault, security_origin_.get(),
+          nullptr /* workerClients */, kWebAddressSpaceLocal,
+          nullptr /* originTrialToken */,
           std::make_unique<WorkerSettings>(Settings::Create().get()),
           kV8CacheOptionsDefault);
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
index 9e86f4d..a8c75dcd 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/macros.h"
 #include "bindings/core/v8/SourceLocation.h"
 #include "bindings/core/v8/V8CacheOptions.h"
 #include "bindings/core/v8/V8GCController.h"
@@ -43,7 +44,6 @@
     : public GarbageCollectedFinalized<MockWorkerThreadLifecycleObserver>,
       public WorkerThreadLifecycleObserver {
   USING_GARBAGE_COLLECTED_MIXIN(MockWorkerThreadLifecycleObserver);
-  WTF_MAKE_NONCOPYABLE(MockWorkerThreadLifecycleObserver);
 
  public:
   explicit MockWorkerThreadLifecycleObserver(
@@ -51,6 +51,9 @@
       : WorkerThreadLifecycleObserver(context) {}
 
   MOCK_METHOD1(ContextDestroyed, void(WorkerThreadLifecycleContext*));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockWorkerThreadLifecycleObserver);
 };
 
 class FakeWorkerGlobalScope : public WorkerGlobalScope {
@@ -97,8 +100,8 @@
     headers->push_back(header_and_type);
 
     auto creation_params = std::make_unique<GlobalScopeCreationParams>(
-        KURL("http://fake.url/"), "fake user agent", source, nullptr,
-        headers.get(), kReferrerPolicyDefault, security_origin, worker_clients,
+        KURL("http://fake.url/"), "fake user agent", headers.get(),
+        kReferrerPolicyDefault, security_origin, worker_clients,
         kWebAddressSpaceLocal, nullptr,
         std::make_unique<WorkerSettings>(Settings::Create().get()),
         kV8CacheOptionsDefault);
@@ -107,7 +110,7 @@
           WorkerBackingThreadStartupData::CreateDefault(),
           std::make_unique<GlobalScopeInspectorCreationParams>(
               WorkerInspectorProxy::PauseOnWorkerStart::kDontPause),
-          parent_frame_task_runners);
+          parent_frame_task_runners, source);
   }
 
   void WaitForInit() {
diff --git a/third_party/WebKit/Source/core/workers/Worklet.h b/third_party/WebKit/Source/core/workers/Worklet.h
index b640732..d6b7c90 100644
--- a/third_party/WebKit/Source/core/workers/Worklet.h
+++ b/third_party/WebKit/Source/core/workers/Worklet.h
@@ -5,6 +5,7 @@
 #ifndef Worklet_h
 #define Worklet_h
 
+#include "base/macros.h"
 #include "bindings/core/v8/ScriptPromise.h"
 #include "core/CoreExport.h"
 #include "core/dom/ContextLifecycleObserver.h"
@@ -30,7 +31,6 @@
   // Eager finalization is needed to notify parent object destruction of the
   // GC-managed messaging proxy and to initiate worklet termination.
   EAGERLY_FINALIZE();
-  WTF_MAKE_NONCOPYABLE(Worklet);
 
  public:
   virtual ~Worklet();
@@ -82,6 +82,8 @@
   // on their insertion order. Access to this map should be thread-safe."
   // https://drafts.css-houdini.org/worklets/#module-responses-map
   Member<WorkletModuleResponsesMap> module_responses_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(Worklet);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
index eb190710..5f7e0e8bd 100644
--- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
@@ -43,6 +43,12 @@
 
   // Step 5: "Let inheritedReferrerPolicy be outsideSettings's referrer policy."
   SetReferrerPolicy(creation_params->referrer_policy);
+
+  // https://drafts.css-houdini.org/worklets/#creating-a-workletglobalscope
+  // Step 6: "Invoke the initialize a global object's CSP list algorithm given
+  // workletGlobalScope."
+  ApplyContentSecurityPolicyFromVector(
+      *creation_params->content_security_policy_parsed_headers);
 }
 
 WorkletGlobalScope::~WorkletGlobalScope() = default;
@@ -145,7 +151,6 @@
 
 void WorkletGlobalScope::Trace(blink::Visitor* visitor) {
   visitor->Trace(module_responses_map_proxy_);
-  SecurityContext::Trace(visitor);
   WorkerOrWorkletGlobalScope::Trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
index 05c1a43..f777704 100644
--- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
@@ -9,7 +9,6 @@
 #include "bindings/core/v8/ActiveScriptWrappable.h"
 #include "core/CoreExport.h"
 #include "core/dom/ExecutionContext.h"
-#include "core/dom/SecurityContext.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/workers/WorkerOrWorkletGlobalScope.h"
 #include "core/workers/WorkletModuleResponsesMapProxy.h"
@@ -28,7 +27,6 @@
 
 class CORE_EXPORT WorkletGlobalScope
     : public WorkerOrWorkletGlobalScope,
-      public SecurityContext,
       public ActiveScriptWrappable<WorkletGlobalScope> {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(WorkletGlobalScope);
@@ -58,13 +56,11 @@
   SecurityContext& GetSecurityContext() final { return *this; }
   bool IsSecureContext(String& error_message) const final;
 
-  using SecurityContext::GetSecurityOrigin;
-  using SecurityContext::GetContentSecurityPolicy;
-
   DOMTimerCoordinator* Timers() final {
+    // WorkletGlobalScopes don't have timers.
     NOTREACHED();
     return nullptr;
-  }  // WorkletGlobalScopes don't have timers.
+  }
 
   // Implementation of the "fetch and invoke a worklet script" algorithm:
   // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script
@@ -98,7 +94,6 @@
 
  private:
   EventTarget* ErrorEventTarget() final { return nullptr; }
-  void DidUpdateSecurityOrigin() final {}
 
   // The |url_| and |user_agent_| are inherited from the parent Document.
   const KURL url_;
diff --git a/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js b/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js
index 5722866f..22bef1ed 100644
--- a/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js
+++ b/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js
@@ -325,17 +325,9 @@
   }
 
   function createDatabaseAsync(databaseName) {
-    var callback;
-    var promise = new Promise(fulfill => callback = fulfill);
-    var request = indexedDB.open(databaseName);
-    request.onerror = onIndexedDBError;
-
-    request.onsuccess = function(event) {
-      request.result.close();
-      callback();
-    };
-
-    return promise;
+    return new Promise((resolve) => {
+      createDatabase(resolve, databaseName);
+    });
   }
 
   function upgradeRequestAsync(databaseName, onUpgradeNeeded, callback) {
diff --git a/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js b/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js
index 29e0be9..e5a35561 100644
--- a/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js
+++ b/third_party/WebKit/Source/devtools/front_end/extensions_test_runner/ExtensionsTestRunner.js
@@ -42,16 +42,19 @@
   return UI.inspectorView.showPanel(panelId);
 };
 
-ExtensionsTestRunner.runExtensionTests = async function() {
+ExtensionsTestRunner.evaluateInExtension = function(code) {
+  ExtensionsTestRunner._codeToEvaluateBeforeTests = code;
+};
+
+ExtensionsTestRunner.runExtensionTests = async function(tests) {
   var result = await TestRunner.RuntimeAgent.evaluate('location.href', 'console', false);
 
   if (!result)
     return;
 
+  ExtensionsTestRunner._pendingTests = (ExtensionsTestRunner._codeToEvaluateBeforeTests || '') + tests.join('\n');
   var pageURL = result.value;
-  var extensionURL = ((/^https?:/.test(pageURL) ? pageURL.replace(/^(https?:\/\/[^\/]*\/).*$/, '$1') :
-                                                  pageURL.replace(/\/devtools\/extensions\/[^\/]*$/, '/http/tests'))) +
-      'devtools/resources/extension-main.html';
+  var extensionURL = pageURL.replace(/^(https?:\/\/[^\/]*\/).*$/, '$1') + 'devtools/resources/extension-main.html';
   extensionURL = extensionURL.replace('127.0.0.1', extensionsHost);
 
   InspectorFrontendAPI.addExtensions(
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index 6a22e093f..f8f4342 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -116,16 +116,12 @@
     // Keep this sorted alphabetically: both keys and values.
     Runtime.experiments.register('accessibilityInspection', 'Accessibility Inspection');
     Runtime.experiments.register('applyCustomStylesheet', 'Allow custom UI themes');
-    Runtime.experiments.register('autoAttachToCrossProcessSubframes', 'Auto-attach to cross-process subframes', true);
     Runtime.experiments.register('blackboxJSFramesOnTimeline', 'Blackbox JavaScript frames on Timeline', true);
     Runtime.experiments.register('colorContrastRatio', 'Color contrast ratio line in color picker', true);
-    Runtime.experiments.register('continueToLocationMarkers', 'Continue to location markers', true);
     Runtime.experiments.register('emptySourceMapAutoStepping', 'Empty sourcemap auto-stepping');
     Runtime.experiments.register('inputEventsOnTimelineOverview', 'Input events on Timeline overview', true);
     Runtime.experiments.register('logManagement', 'Log management', true);
-    Runtime.experiments.register('networkGroupingRequests', 'Network request groups support', true);
     Runtime.experiments.register('networkPersistence', 'Override requests with workspace project');
-    Runtime.experiments.register('objectPreviews', 'Object previews', true);
     Runtime.experiments.register('performanceMonitor', 'Performance Monitor', true);
     Runtime.experiments.register('persistence2', 'Persistence 2.0');
     Runtime.experiments.register('sourceDiff', 'Source diff');
@@ -134,7 +130,6 @@
     Runtime.experiments.register('terminalInDrawer', 'Terminal in drawer', true);
 
     // Timeline
-    Runtime.experiments.register('timelineColorByProduct', 'Timeline: color by product', true);
     Runtime.experiments.register('timelineEventInitiators', 'Timeline: event initiators');
     Runtime.experiments.register('timelineFlowEvents', 'Timeline: flow events', true);
     Runtime.experiments.register('timelineInvalidationTracking', 'Timeline: invalidation tracking', true);
@@ -161,9 +156,8 @@
     }
 
     Runtime.experiments.setDefaultExperiments([
-      'continueToLocationMarkers', 'autoAttachToCrossProcessSubframes', 'objectPreviews', 'persistence2',
-      'networkGroupingRequests', 'timelineColorByProduct', 'accessibilityInspection', 'logManagement',
-      'performanceMonitor', 'stepIntoAsync', 'colorContrastRatio'
+      'accessibilityInspection', 'colorContrastRatio', 'logManagement', 'performanceMonitor', 'persistence2',
+      'stepIntoAsync'
     ]);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
index 659b212..d1c6044 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
@@ -301,8 +301,6 @@
     this._isOnInitiatorPath = false;
     this._isOnInitiatedPath = false;
     this._isFromFrame = false;
-    if (!Runtime.experiments.isEnabled('networkGroupingRequests'))
-      return;
     var frame = SDK.ResourceTreeModel.frameForRequest(request);
     this._isFromFrame = frame ? !frame.isMainFrame() : false;
   }
@@ -705,8 +703,6 @@
     element.classList.toggle('network-navigation-row', this._isNavigationRequest);
     super.createCells(element);
     this._updateBackgroundColor();
-    if (!Runtime.experiments.isEnabled('networkGroupingRequests'))
-      return;
     ProductRegistry.instance().then(productRegistry => {
       if (productRegistry.entryForUrl(this._request.parsedURL)) {
         this._isProduct = true;
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 3fe0a3f..ae79b58 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
@@ -189,10 +189,8 @@
         Common.UIString('Hide overview'));
     this._panelToolbar.appendToolbarItem(showOverviewButton);
 
-    if (Runtime.experiments.isEnabled('networkGroupingRequests')) {
-      this._panelToolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
-          Common.moduleSetting('network.group-by-frame'), '', Common.UIString('Group by frame')));
-    }
+    this._panelToolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
+        Common.moduleSetting('network.group-by-frame'), '', Common.UIString('Group by frame')));
 
     this._panelToolbar.appendSeparator();
     this._panelToolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js
index 3cb5a90..f12b43cc 100644
--- a/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js
+++ b/third_party/WebKit/Source/devtools/front_end/object_ui/ObjectPropertiesSection.js
@@ -261,7 +261,7 @@
     } else {
       valueElement = createElementWithClass('span', 'object-value-' + (subtype || type));
       valueElement.title = description || '';
-      if (Runtime.experiments.isEnabled('objectPreviews') && value.preview && showPreview) {
+      if (value.preview && showPreview) {
         var previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter();
         previewFormatter.appendObjectPreview(valueElement, value.preview, false /* isEntry */);
       } else {
@@ -525,11 +525,10 @@
           treeElement, properties, internalProperties, skipProto, targetValue || value, linkifier, emptyPlaceholder);
     }
 
-    var generatePreview = Runtime.experiments.isEnabled('objectPreviews');
     if (flattenProtoChain)
-      value.getAllProperties(false, generatePreview, callback);
+      value.getAllProperties(false /* accessorPropertiesOnly */, true /* generatePreview */, callback);
     else
-      SDK.RemoteObject.loadFromObjectPerProto(value, generatePreview, callback);
+      SDK.RemoteObject.loadFromObjectPerProto(value, true /* generatePreview */, callback);
   }
 
   /**
@@ -1157,7 +1156,7 @@
       if (!arrayFragment || wasThrown)
         return;
       arrayFragment.getAllProperties(
-          false, Runtime.experiments.isEnabled('objectPreviews'), processProperties.bind(this));
+          false /* accessorPropertiesOnly */, true /* generatePreview */, processProperties.bind(this));
     }
 
     /** @this {ObjectUI.ArrayGroupingTreeElement} */
@@ -1215,7 +1214,7 @@
     function processObjectFragment(arrayFragment, wasThrown) {
       if (!arrayFragment || wasThrown)
         return;
-      arrayFragment.getOwnProperties(Runtime.experiments.isEnabled('objectPreviews'), processProperties.bind(this));
+      arrayFragment.getOwnProperties(true /* generatePreview */, processProperties.bind(this));
     }
 
     /**
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 e88c24b2..2d89471 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
@@ -37,11 +37,9 @@
    * @param {boolean} isEntry
    */
   appendObjectPreview(parentElement, preview, isEntry) {
-    const previewExperimentEnabled = Runtime.experiments.isEnabled('objectPreviews');
     var description = preview.description;
     var subTypesWithoutValuePreview = new Set(['null', 'regexp', 'error', 'internal#entry']);
-    if (preview.type !== 'object' || subTypesWithoutValuePreview.has(preview.subtype) ||
-        (previewExperimentEnabled && isEntry)) {
+    if (preview.type !== 'object' || subTypesWithoutValuePreview.has(preview.subtype) || isEntry) {
       parentElement.appendChild(this.renderPropertyPreview(preview.type, preview.subtype, description));
       return;
     }
@@ -54,7 +52,7 @@
         var arrayName = SDK.RemoteObject.arrayNameFromDescription(description);
         text = arrayName === 'Array' ? arrayLengthText : (arrayName + arrayLengthText);
       } else {
-        var hideDescription = previewExperimentEnabled && description === 'Object';
+        var hideDescription = description === 'Object';
         text = hideDescription ? '' : description;
       }
       if (text.length > 0)
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js
index 7d37afd..4517564f 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js
@@ -1299,6 +1299,13 @@
     contextMenu.show();
   }
 
+  _refreshObjectStore() {
+    if (this._view)
+      this._view.refreshData();
+    for (var indexName in this._idbIndexTreeElements)
+      this._idbIndexTreeElements[indexName].refreshIndex();
+  }
+
   async _clearObjectStore() {
     await this._model.clearObjectStore(this._databaseId, this._objectStore.name);
     this.update(this._objectStore, true);
@@ -1317,7 +1324,8 @@
       indexNames[index.name] = true;
       if (!this._idbIndexTreeElements[index.name]) {
         var idbIndexTreeElement = new Resources.IDBIndexTreeElement(
-            this._storagePanel, this._model, this._databaseId, this._objectStore, index);
+            this._storagePanel, this._model, this._databaseId, this._objectStore, index,
+            this._refreshObjectStore.bind(this));
         this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
         this.appendChild(idbIndexTreeElement);
       }
@@ -1357,8 +1365,10 @@
    */
   onselect(selectedByUser) {
     super.onselect(selectedByUser);
-    if (!this._view)
-      this._view = new Resources.IDBDataView(this._model, this._databaseId, this._objectStore, null);
+    if (!this._view) {
+      this._view = new Resources.IDBDataView(
+          this._model, this._databaseId, this._objectStore, null, this._refreshObjectStore.bind(this));
+    }
 
     this.showView(this._view);
     return false;
@@ -1392,13 +1402,15 @@
    * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
    * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
    * @param {!Resources.IndexedDBModel.Index} index
+   * @param {function()} refreshObjectStore
    */
-  constructor(storagePanel, model, databaseId, objectStore, index) {
+  constructor(storagePanel, model, databaseId, objectStore, index, refreshObjectStore) {
     super(storagePanel, index.name, false);
     this._model = model;
     this._databaseId = databaseId;
     this._objectStore = objectStore;
     this._index = index;
+    this._refreshObjectStore = refreshObjectStore;
   }
 
   get itemURL() {
@@ -1411,6 +1423,11 @@
       this._view.markNeedsRefresh();
   }
 
+  refreshIndex() {
+    if (this._view)
+      this._view.refreshData();
+  }
+
   /**
    * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
    * @param {!Resources.IndexedDBModel.Index} index
@@ -1443,8 +1460,10 @@
    */
   onselect(selectedByUser) {
     super.onselect(selectedByUser);
-    if (!this._view)
-      this._view = new Resources.IDBDataView(this._model, this._databaseId, this._objectStore, this._index);
+    if (!this._view) {
+      this._view = new Resources.IDBDataView(
+          this._model, this._databaseId, this._objectStore, this._index, this._refreshObjectStore);
+    }
 
     this.showView(this._view);
     return false;
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js
index 00a0d9f..1206acae 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js
@@ -96,14 +96,10 @@
   }
 
   /**
-   * @param {?IDBKeyRange=} idbKeyRange
-   * @return {?Protocol.IndexedDB.KeyRange}
-   * eturn {?{lower: ?Object, upper: ?Object, lowerOpen: *, upperOpen: *}}
+   * @param {!IDBKeyRange} idbKeyRange
+   * @return {!Protocol.IndexedDB.KeyRange}
    */
-  static keyRangeFromIDBKeyRange(idbKeyRange) {
-    if (typeof idbKeyRange === 'undefined' || idbKeyRange === null)
-      return null;
-
+  static _keyRangeFromIDBKeyRange(idbKeyRange) {
     var keyRange = {};
     keyRange.lower = Resources.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
     keyRange.upper = Resources.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
@@ -204,6 +200,18 @@
   }
 
   /**
+   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
+   * @param {string} objectStoreName
+   * @param {!IDBKeyRange} idbKeyRange
+   * @return {!Promise}
+   */
+  deleteEntries(databaseId, objectStoreName, idbKeyRange) {
+    var keyRange = Resources.IndexedDBModel._keyRangeFromIDBKeyRange(idbKeyRange);
+    return this._indexedDBAgent.deleteObjectStoreEntries(
+        databaseId.securityOrigin, databaseId.name, objectStoreName, keyRange);
+  }
+
+  /**
    * @param {!Common.Event} event
    */
   _securityOriginAdded(event) {
@@ -388,7 +396,7 @@
    * @param {function(!Array.<!Resources.IndexedDBModel.Entry>, boolean)} callback
    */
   async _requestData(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback) {
-    var keyRange = Resources.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange) || undefined;
+    var keyRange = idbKeyRange ? Resources.IndexedDBModel._keyRangeFromIDBKeyRange(idbKeyRange) : undefined;
 
     var response = await this._indexedDBAgent.invoke_requestData({
       securityOrigin: databaseId.securityOrigin,
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
index 88495083..fea82fe 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
@@ -103,20 +103,25 @@
    * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
    * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
    * @param {?Resources.IndexedDBModel.Index} index
+   * @param {function()} refreshObjectStoreCallback
    */
-  constructor(model, databaseId, objectStore, index) {
+  constructor(model, databaseId, objectStore, index, refreshObjectStoreCallback) {
     super(Common.UIString('IDB'));
     this.registerRequiredCSS('resources/indexedDBViews.css');
 
     this._model = model;
     this._databaseId = databaseId;
     this._isIndex = !!index;
+    this._refreshObjectStoreCallback = refreshObjectStoreCallback;
 
     this.element.classList.add('indexed-db-data-view');
 
     this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
     this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
 
+    this._deleteSelectedButton = new UI.ToolbarButton(Common.UIString('Delete selected'), 'largeicon-delete');
+    this._deleteSelectedButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._deleteButtonClicked(null));
+
     this._clearButton = new UI.ToolbarButton(Common.UIString('Clear object store'), 'largeicon-clear');
     this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearButtonClicked, this);
 
@@ -152,8 +157,10 @@
     }
     columns.push({id: 'value', title: Common.UIString('Value'), sortable: false});
 
-    var dataGrid = new DataGrid.DataGrid(columns);
+    var dataGrid = new DataGrid.DataGrid(
+        columns, undefined, this._deleteButtonClicked.bind(this), this._updateData.bind(this, true));
     dataGrid.setStriped(true);
+    dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, event => this._updateToolbarEnablement(), this);
     return dataGrid;
   }
 
@@ -203,6 +210,7 @@
 
     editorToolbar.appendToolbarItem(this._refreshButton);
     editorToolbar.appendToolbarItem(this._clearButton);
+    editorToolbar.appendToolbarItem(this._deleteSelectedButton);
 
     editorToolbar.appendToolbarItem(new UI.ToolbarSeparator());
 
@@ -246,6 +254,10 @@
     window.setTimeout(this._updateData.bind(this, false), 0);
   }
 
+  refreshData() {
+    this._updateData(true);
+  }
+
   /**
    * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
    * @param {?Resources.IndexedDBModel.Index} index
@@ -283,6 +295,8 @@
     var key = this._parseKey(this._keyInputElement.value);
     var pageSize = this._pageSize;
     var skipCount = this._skipCount;
+    var selected = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.data['number'] : 0;
+    selected = Math.max(selected, this._skipCount);  // Page forward should select top entry
     this._refreshButton.setEnabled(false);
     this._clearButton.setEnabled(!this._isIndex);
 
@@ -306,6 +320,7 @@
       this._refreshButton.setEnabled(true);
       this.clear();
       this._entries = entries;
+      var selectedNode = null;
       for (var i = 0; i < entries.length; ++i) {
         var data = {};
         data['number'] = i + skipCount;
@@ -315,11 +330,16 @@
 
         var node = new Resources.IDBDataGridNode(data);
         this._dataGrid.rootNode().appendChild(node);
+        if (data['number'] <= selected)
+          selectedNode = node;
       }
 
+      if (selectedNode)
+        selectedNode.select();
       this._pageBackButton.setEnabled(!!skipCount);
       this._pageForwardButton.setEnabled(hasMore);
       this._needsRefresh.setVisible(false);
+      this._updateToolbarEnablement();
       this._updatedDataForTests();
     }
 
@@ -339,7 +359,7 @@
   }
 
   /**
-   * @param {!Common.Event} event
+   * @param {?Common.Event} event
    */
   _refreshButtonClicked(event) {
     this._updateData(true);
@@ -359,10 +379,31 @@
     this._needsRefresh.setVisible(true);
   }
 
+  /**
+   * @param {?DataGrid.DataGridNode} node
+   */
+  async _deleteButtonClicked(node) {
+    if (!node) {
+      node = this._dataGrid.selectedNode;
+      if (!node)
+        return;
+    }
+    var key = /** @type {!SDK.RemoteObject} */ (this._isIndex ? node.data.primaryKey : node.data.key);
+    var keyValue = /** @type {!Array<?>|!Date|number|string} */ (key.value);
+    await this._model.deleteEntries(this._databaseId, this._objectStore.name, window.IDBKeyRange.only(keyValue));
+    this._refreshObjectStoreCallback();
+  }
+
   clear() {
     this._dataGrid.rootNode().removeChildren();
     this._entries = [];
   }
+
+  _updateToolbarEnablement() {
+    var empty = !this._dataGrid || this._dataGrid.rootNode().children.length === 0;
+    this._clearButton.setEnabled(!empty);
+    this._deleteSelectedButton.setEnabled(!empty && this._dataGrid.selectedNode !== null);
+  }
 };
 
 /**
@@ -374,7 +415,7 @@
    */
   constructor(data) {
     super(data, false);
-    this.selectable = false;
+    this.selectable = true;
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/indexedDBViews.css b/third_party/WebKit/Source/devtools/front_end/resources/indexedDBViews.css
index 360d3ad4..5100428d 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/indexedDBViews.css
+++ b/third_party/WebKit/Source/devtools/front_end/resources/indexedDBViews.css
@@ -55,6 +55,11 @@
     border-bottom: 1px solid #aaa;
 }
 
+.indexed-db-data-view .data-grid:focus .data-container tr.selected {
+    background-color: #cdddf5;
+    color: inherit;
+}
+
 .indexed-db-data-view .section,
 .indexed-db-data-view .section > .header,
 .indexed-db-data-view .section > .header .title {
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 7a40cf6..c8ae57f 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
@@ -405,8 +405,8 @@
 
     parentTarget.registerTargetDispatcher(this);
     this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true});
-    if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes'))
-      this._targetAgent.setAttachToFrames(true);
+    // TODO(dgozman): remove the protocol method and make it default.
+    this._targetAgent.setAttachToFrames(true);
 
     if (!parentTarget.parentTarget()) {
       this._targetAgent.setDiscoverTargets(true);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
index 74812b38..bb88c36 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -56,12 +56,10 @@
     this.textEditor.element.addEventListener('mousemove', this._onMouseMove.bind(this), false);
     this.textEditor.element.addEventListener('mousedown', this._onMouseDown.bind(this), true);
     this.textEditor.element.addEventListener('focusout', this._onBlur.bind(this), false);
-    if (Runtime.experiments.isEnabled('continueToLocationMarkers')) {
-      this.textEditor.element.addEventListener('wheel', event => {
-        if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event))
-          event.preventDefault();
-      }, true);
-    }
+    this.textEditor.element.addEventListener('wheel', event => {
+      if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event))
+        event.preventDefault();
+    }, true);
 
     this.textEditor.addEventListener(
         SourceFrame.SourcesTextEditor.Events.GutterClick, this._handleGutterClick.bind(this), this);
@@ -649,12 +647,10 @@
     if (this.isShowing()) {
       // We need SourcesTextEditor to be initialized prior to this call. @see crbug.com/506566
       setImmediate(() => {
-        if (this._controlDown) {
-          if (Runtime.experiments.isEnabled('continueToLocationMarkers'))
-            this._showContinueToLocations();
-        } else {
+        if (this._controlDown)
+          this._showContinueToLocations();
+        else
           this._generateValuesInSource();
-        }
       });
     }
   }
@@ -683,8 +679,6 @@
   }
 
   _showContinueToLocations() {
-    if (!Runtime.experiments.isEnabled('continueToLocationMarkers'))
-      return;
     this._popoverHelper.hidePopover();
     var executionContext = UI.context.flavor(SDK.ExecutionContext);
     if (!executionContext)
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
index 1a540a51..49af7a5b 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -843,6 +843,8 @@
   _appendUISourceCodeFrameItems(event, contextMenu, target) {
     if (!(target instanceof Sources.UISourceCodeFrame))
       return;
+    if (target.uiSourceCode().contentType().isFromSourceMap())
+      return;
     contextMenu.debugSection().appendAction('debugger.evaluate-selection');
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js b/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js
index 9b044d4..a381da0 100644
--- a/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js
+++ b/third_party/WebKit/Source/devtools/front_end/test_runner/TestRunner.js
@@ -952,14 +952,22 @@
  * @param {function():void} callback
  */
 TestRunner.hardReloadPage = function(callback) {
-  TestRunner._innerReloadPage(true, callback);
+  TestRunner._innerReloadPage(true, undefined, callback);
 };
 
 /**
  * @param {function():void} callback
  */
 TestRunner.reloadPage = function(callback) {
-  TestRunner._innerReloadPage(false, callback);
+  TestRunner._innerReloadPage(false, undefined, callback);
+};
+
+/**
+ * @param {(string|undefined)} injectedScript
+ * @param {function():void} callback
+ */
+TestRunner.reloadPageWithInjectedScript = function(injectedScript, callback) {
+  TestRunner._innerReloadPage(false, injectedScript, callback);
 };
 
 /**
@@ -971,12 +979,13 @@
 
 /**
  * @param {boolean} hardReload
+ * @param {(string|undefined)} injectedScript
  * @param {function():void} callback
  */
-TestRunner._innerReloadPage = function(hardReload, callback) {
+TestRunner._innerReloadPage = function(hardReload, injectedScript, callback) {
   TestRunner._pageLoadedCallback = TestRunner.safeWrap(callback);
   TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, TestRunner.pageLoaded);
-  TestRunner.resourceTreeModel.reloadPage(hardReload);
+  TestRunner.resourceTreeModel.reloadPage(hardReload, injectedScript);
 };
 
 TestRunner.pageLoaded = function() {
@@ -996,6 +1005,18 @@
 /**
  * @param {function():void} callback
  */
+TestRunner.waitForPageLoad = function(callback) {
+  TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, onLoaded);
+
+  function onLoaded() {
+    TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, onLoaded);
+    callback();
+  }
+};
+
+/**
+ * @param {function():void} callback
+ */
 TestRunner.runWhenPageLoads = function(callback) {
   var oldCallback = TestRunner._pageLoadedCallback;
   function chainedCallback() {
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 29b7f4bb..10c1f2f 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
@@ -81,8 +81,6 @@
     this._boundRefresh = this._refresh.bind(this);
 
     this._mainDataProvider.setEventColorMapping(Timeline.TimelineUIUtils.eventColor);
-    if (!Runtime.experiments.isEnabled('timelineColorByProduct'))
-      return;
     this._groupBySetting =
         Common.settings.createSetting('timelineTreeGroupBy', Timeline.AggregatedTimelineTreeView.GroupBy.None);
     this._groupBySetting.addChangeListener(this._updateColorMapper, this);
@@ -95,8 +93,7 @@
     this._urlToColorCache = new Map();
     if (!this._model)
       return;
-    var colorByProduct = Runtime.experiments.isEnabled('timelineColorByProduct') &&
-        this._groupBySetting.get() === Timeline.AggregatedTimelineTreeView.GroupBy.Product;
+    var colorByProduct = this._groupBySetting.get() === Timeline.AggregatedTimelineTreeView.GroupBy.Product;
     this._mainDataProvider.setEventColorMapping(
         colorByProduct ? this._colorByProductForEvent.bind(this) : Timeline.TimelineUIUtils.eventColor);
     this._mainFlameChart.update();
diff --git a/third_party/WebKit/Source/modules/BUILD.gn b/third_party/WebKit/Source/modules/BUILD.gn
index f19cf78..d634f29 100644
--- a/third_party/WebKit/Source/modules/BUILD.gn
+++ b/third_party/WebKit/Source/modules/BUILD.gn
@@ -122,6 +122,7 @@
     "//third_party/WebKit/Source/modules/installation",
     "//third_party/WebKit/Source/modules/installedapp",
     "//third_party/WebKit/Source/modules/keyboard_lock",
+    "//third_party/WebKit/Source/modules/locks",
     "//third_party/WebKit/Source/modules/media_capabilities",
     "//third_party/WebKit/Source/modules/media_controls",
     "//third_party/WebKit/Source/modules/mediacapturefromelement",
@@ -352,6 +353,7 @@
     "//third_party/WebKit/Source/core",
     "//third_party/WebKit/Source/platform",
     "//third_party/WebKit/Source/platform/wtf",
+    "//third_party/WebKit/public:media_devices_mojo_bindings_blink",
     "//v8",
   ]
 }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
index 1a7e367..73ff2f2 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
@@ -1272,8 +1272,8 @@
           mojom::blink::PermissionName::ACCESSIBILITY_EVENTS),
       document_->GetExecutionContext()->GetSecurityOrigin(),
       Frame::HasTransientUserActivation(document_->GetFrame()),
-      ConvertToBaseCallback(WTF::Bind(
-          &AXObjectCacheImpl::OnPermissionStatusChange, WrapPersistent(this))));
+      WTF::Bind(&AXObjectCacheImpl::OnPermissionStatusChange,
+                WrapPersistent(this)));
 }
 
 void AXObjectCacheImpl::ContextDestroyed(ExecutionContext*) {
diff --git a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp
index b0eeace..985af3a 100644
--- a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp
+++ b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletGlobalScopeTest.cpp
@@ -58,8 +58,7 @@
     Document* document = page_->GetFrame().GetDocument();
     thread->Start(
         std::make_unique<GlobalScopeCreationParams>(
-            document->Url(), document->UserAgent(), "" /* source_code */,
-            nullptr /* cached_meta_data */,
+            document->Url(), document->UserAgent(),
             nullptr /* content_security_policy_parsed_headers */,
             document->GetReferrerPolicy(), document->GetSecurityOrigin(),
             clients, document->AddressSpace(),
diff --git a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp
index ea054b6..36bb05e 100644
--- a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp
+++ b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp
@@ -92,8 +92,7 @@
     Document* document = page_->GetFrame().GetDocument();
     thread->Start(
         std::make_unique<GlobalScopeCreationParams>(
-            document->Url(), document->UserAgent(), "" /* source_code */,
-            nullptr /* cached_meta_data */,
+            document->Url(), document->UserAgent(),
             nullptr /* content_security_policy_parsed_headers */,
             document->GetReferrerPolicy(), document->GetSecurityOrigin(),
             clients, document->AddressSpace(),
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.cpp
index c1595fb..69ef90a06 100644
--- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.cpp
+++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.cpp
@@ -53,9 +53,8 @@
       GetSupplementable()->WebRegistration()->RegistrationId(),
       GetSecurityOrigin(), developer_id, std::move(requests),
       mojom::blink::BackgroundFetchOptions::From(options),
-      ConvertToBaseCallback(
-          WTF::Bind(&BackgroundFetchBridge::DidGetRegistration,
-                    WrapPersistent(this), WTF::Passed(std::move(callback)))));
+      WTF::Bind(&BackgroundFetchBridge::DidGetRegistration,
+                WrapPersistent(this), WTF::Passed(std::move(callback))));
 }
 
 void BackgroundFetchBridge::Abort(const String& developer_id,
@@ -63,15 +62,14 @@
                                   AbortCallback callback) {
   GetService()->Abort(GetSupplementable()->WebRegistration()->RegistrationId(),
                       GetSecurityOrigin(), developer_id, unique_id,
-                      ConvertToBaseCallback(std::move(callback)));
+                      std::move(callback));
 }
 
 void BackgroundFetchBridge::UpdateUI(const String& developer_id,
                                      const String& unique_id,
                                      const String& title,
                                      UpdateUICallback callback) {
-  GetService()->UpdateUI(unique_id, title,
-                         ConvertToBaseCallback(std::move(callback)));
+  GetService()->UpdateUI(unique_id, title, std::move(callback));
 }
 
 void BackgroundFetchBridge::GetRegistration(const String& developer_id,
@@ -79,9 +77,8 @@
   GetService()->GetRegistration(
       GetSupplementable()->WebRegistration()->RegistrationId(),
       GetSecurityOrigin(), developer_id,
-      ConvertToBaseCallback(
-          WTF::Bind(&BackgroundFetchBridge::DidGetRegistration,
-                    WrapPersistent(this), WTF::Passed(std::move(callback)))));
+      WTF::Bind(&BackgroundFetchBridge::DidGetRegistration,
+                WrapPersistent(this), WTF::Passed(std::move(callback))));
 }
 
 void BackgroundFetchBridge::DidGetRegistration(
@@ -102,7 +99,7 @@
 void BackgroundFetchBridge::GetDeveloperIds(GetDeveloperIdsCallback callback) {
   GetService()->GetDeveloperIds(
       GetSupplementable()->WebRegistration()->RegistrationId(),
-      GetSecurityOrigin(), ConvertToBaseCallback(std::move(callback)));
+      GetSecurityOrigin(), std::move(callback));
 }
 
 void BackgroundFetchBridge::AddRegistrationObserver(
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.h b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.h
index 3b59d9b..d668e45 100644
--- a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.h
+++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchBridge.h
@@ -30,12 +30,16 @@
   WTF_MAKE_NONCOPYABLE(BackgroundFetchBridge);
 
  public:
-  using AbortCallback = Function<void(mojom::blink::BackgroundFetchError)>;
+  using AbortCallback =
+      base::OnceCallback<void(mojom::blink::BackgroundFetchError)>;
   using GetDeveloperIdsCallback =
-      Function<void(mojom::blink::BackgroundFetchError, const Vector<String>&)>;
-  using RegistrationCallback = Function<void(mojom::blink::BackgroundFetchError,
-                                             BackgroundFetchRegistration*)>;
-  using UpdateUICallback = Function<void(mojom::blink::BackgroundFetchError)>;
+      base::OnceCallback<void(mojom::blink::BackgroundFetchError,
+                              const Vector<String>&)>;
+  using RegistrationCallback =
+      base::OnceCallback<void(mojom::blink::BackgroundFetchError,
+                              BackgroundFetchRegistration*)>;
+  using UpdateUICallback =
+      base::OnceCallback<void(mojom::blink::BackgroundFetchError)>;
 
   static BackgroundFetchBridge* From(ServiceWorkerRegistration*);
   static const char* SupplementName();
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
index 869d94c..6b5a333 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
+++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
@@ -48,8 +48,7 @@
   GetBackgroundSyncServicePtr()->Register(
       std::move(sync_registration),
       registration_->WebRegistration()->RegistrationId(),
-      ConvertToBaseCallback(
-          WTF::Bind(SyncManager::RegisterCallback, WrapPersistent(resolver))));
+      WTF::Bind(SyncManager::RegisterCallback, WrapPersistent(resolver)));
 
   return promise;
 }
@@ -60,8 +59,8 @@
 
   GetBackgroundSyncServicePtr()->GetRegistrations(
       registration_->WebRegistration()->RegistrationId(),
-      ConvertToBaseCallback(WTF::Bind(&SyncManager::GetRegistrationsCallback,
-                                      WrapPersistent(resolver))));
+      WTF::Bind(&SyncManager::GetRegistrationsCallback,
+                WrapPersistent(resolver)));
 
   return promise;
 }
diff --git a/third_party/WebKit/Source/modules/battery/BatteryDispatcher.cpp b/third_party/WebKit/Source/modules/battery/BatteryDispatcher.cpp
index 80930a1..32c10a7b 100644
--- a/third_party/WebKit/Source/modules/battery/BatteryDispatcher.cpp
+++ b/third_party/WebKit/Source/modules/battery/BatteryDispatcher.cpp
@@ -21,8 +21,8 @@
 BatteryDispatcher::BatteryDispatcher() : has_latest_data_(false) {}
 
 void BatteryDispatcher::QueryNextStatus() {
-  monitor_->QueryNextStatus(ConvertToBaseCallback(
-      WTF::Bind(&BatteryDispatcher::OnDidChange, WrapPersistent(this))));
+  monitor_->QueryNextStatus(
+      WTF::Bind(&BatteryDispatcher::OnDidChange, WrapPersistent(this)));
 }
 
 void BatteryDispatcher::OnDidChange(
diff --git a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
index 166c0be..90f11cf29 100644
--- a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
@@ -212,10 +212,10 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
 
-  service_->RequestDevice(std::move(device_options),
-                          ConvertToBaseCallback(WTF::Bind(
-                              &Bluetooth::RequestDeviceCallback,
-                              WrapPersistent(this), WrapPersistent(resolver))));
+  service_->RequestDevice(
+      std::move(device_options),
+      WTF::Bind(&Bluetooth::RequestDeviceCallback, WrapPersistent(this),
+                WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
index 37b6889..65c60e4 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
@@ -132,9 +132,8 @@
       device_->GetBluetooth()->Service();
   service->RemoteCharacteristicReadValue(
       characteristic_->instance_id,
-      ConvertToBaseCallback(
-          WTF::Bind(&BluetoothRemoteGATTCharacteristic::ReadValueCallback,
-                    WrapPersistent(this), WrapPersistent(resolver))));
+      WTF::Bind(&BluetoothRemoteGATTCharacteristic::ReadValueCallback,
+                WrapPersistent(this), WrapPersistent(resolver)));
 
   return promise;
 }
@@ -200,9 +199,8 @@
       device_->GetBluetooth()->Service();
   service->RemoteCharacteristicWriteValue(
       characteristic_->instance_id, value_vector,
-      ConvertToBaseCallback(WTF::Bind(
-          &BluetoothRemoteGATTCharacteristic::WriteValueCallback,
-          WrapPersistent(this), WrapPersistent(resolver), value_vector)));
+      WTF::Bind(&BluetoothRemoteGATTCharacteristic::WriteValueCallback,
+                WrapPersistent(this), WrapPersistent(resolver), value_vector));
 
   return promise;
 }
@@ -254,9 +252,8 @@
 
   service->RemoteCharacteristicStartNotifications(
       characteristic_->instance_id, std::move(ptr_info),
-      ConvertToBaseCallback(
-          WTF::Bind(&BluetoothRemoteGATTCharacteristic::NotificationsCallback,
-                    WrapPersistent(this), WrapPersistent(resolver))));
+      WTF::Bind(&BluetoothRemoteGATTCharacteristic::NotificationsCallback,
+                WrapPersistent(this), WrapPersistent(resolver)));
 
   return promise;
 }
@@ -283,10 +280,9 @@
       device_->GetBluetooth()->Service();
   service->RemoteCharacteristicStopNotifications(
       characteristic_->instance_id,
-      ConvertToBaseCallback(
-          WTF::Bind(&BluetoothRemoteGATTCharacteristic::NotificationsCallback,
-                    WrapPersistent(this), WrapPersistent(resolver),
-                    mojom::blink::WebBluetoothResult::SUCCESS)));
+      WTF::Bind(&BluetoothRemoteGATTCharacteristic::NotificationsCallback,
+                WrapPersistent(this), WrapPersistent(resolver),
+                mojom::blink::WebBluetoothResult::SUCCESS));
   return promise;
 }
 
@@ -349,10 +345,10 @@
       device_->GetBluetooth()->Service();
   service->RemoteCharacteristicGetDescriptors(
       characteristic_->instance_id, quantity, descriptors_uuid,
-      ConvertToBaseCallback(WTF::Bind(
-          &BluetoothRemoteGATTCharacteristic::GetDescriptorsCallback,
-          WrapPersistent(this), descriptors_uuid, characteristic_->instance_id,
-          quantity, WrapPersistent(resolver))));
+      WTF::Bind(&BluetoothRemoteGATTCharacteristic::GetDescriptorsCallback,
+                WrapPersistent(this), descriptors_uuid,
+                characteristic_->instance_id, quantity,
+                WrapPersistent(resolver)));
 
   return promise;
 }
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp
index 5c9f58b1..67036b0 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp
@@ -72,9 +72,8 @@
   GetGatt()->AddToActiveAlgorithms(resolver);
   GetService()->RemoteDescriptorReadValue(
       descriptor_->instance_id,
-      ConvertToBaseCallback(
-          WTF::Bind(&BluetoothRemoteGATTDescriptor::ReadValueCallback,
-                    WrapPersistent(this), WrapPersistent(resolver))));
+      WTF::Bind(&BluetoothRemoteGATTDescriptor::ReadValueCallback,
+                WrapPersistent(this), WrapPersistent(resolver)));
 
   return promise;
 }
@@ -138,9 +137,8 @@
   GetGatt()->AddToActiveAlgorithms(resolver);
   GetService()->RemoteDescriptorWriteValue(
       descriptor_->instance_id, value_vector,
-      ConvertToBaseCallback(WTF::Bind(
-          &BluetoothRemoteGATTDescriptor::WriteValueCallback,
-          WrapPersistent(this), WrapPersistent(resolver), value_vector)));
+      WTF::Bind(&BluetoothRemoteGATTDescriptor::WriteValueCallback,
+                WrapPersistent(this), WrapPersistent(resolver), value_vector));
 
   return promise;
 }
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp
index 8187ff02..99c3b2f 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp
@@ -118,9 +118,8 @@
 
   service->RemoteServerConnect(
       device_->id(), std::move(ptr_info),
-      ConvertToBaseCallback(
-          WTF::Bind(&BluetoothRemoteGATTServer::ConnectCallback,
-                    WrapPersistent(this), WrapPersistent(resolver))));
+      WTF::Bind(&BluetoothRemoteGATTServer::ConnectCallback,
+                WrapPersistent(this), WrapPersistent(resolver)));
 
   return promise;
 }
@@ -235,10 +234,9 @@
       device_->GetBluetooth()->Service();
   service->RemoteServerGetPrimaryServices(
       device_->id(), quantity, services_uuid,
-      ConvertToBaseCallback(
-          WTF::Bind(&BluetoothRemoteGATTServer::GetPrimaryServicesCallback,
-                    WrapPersistent(this), services_uuid, quantity,
-                    WrapPersistent(resolver))));
+      WTF::Bind(&BluetoothRemoteGATTServer::GetPrimaryServicesCallback,
+                WrapPersistent(this), services_uuid, quantity,
+                WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTService.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTService.cpp
index 552c224c..0c18b36 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTService.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTService.cpp
@@ -148,10 +148,9 @@
       device_->GetBluetooth()->Service();
   service->RemoteServiceGetCharacteristics(
       service_->instance_id, quantity, characteristics_uuid,
-      ConvertToBaseCallback(
-          WTF::Bind(&BluetoothRemoteGATTService::GetCharacteristicsCallback,
-                    WrapPersistent(this), service_->instance_id,
-                    characteristics_uuid, quantity, WrapPersistent(resolver))));
+      WTF::Bind(&BluetoothRemoteGATTService::GetCharacteristicsCallback,
+                WrapPersistent(this), service_->instance_id,
+                characteristics_uuid, quantity, WrapPersistent(resolver)));
 
   return promise;
 }
diff --git a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp
index 5e6c96a..27ebfe82 100644
--- a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp
+++ b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp
@@ -124,14 +124,14 @@
   // channel.
   mojom::blink::BroadcastChannelClientAssociatedPtrInfo local_client_info;
   binding_.Bind(mojo::MakeRequest(&local_client_info));
-  binding_.set_connection_error_handler(ConvertToBaseCallback(
-      WTF::Bind(&BroadcastChannel::OnError, WrapWeakPersistent(this))));
+  binding_.set_connection_error_handler(
+      WTF::Bind(&BroadcastChannel::OnError, WrapWeakPersistent(this)));
 
   // Remote BroadcastChannelClient for messages send from this channel to the
   // browser.
   auto remote_cient_request = mojo::MakeRequest(&remote_client_);
-  remote_client_.set_connection_error_handler(ConvertToBaseCallback(
-      WTF::Bind(&BroadcastChannel::OnError, WrapWeakPersistent(this))));
+  remote_client_.set_connection_error_handler(
+      WTF::Bind(&BroadcastChannel::OnError, WrapWeakPersistent(this)));
 
   provider->ConnectToChannel(origin_, name_, std::move(local_client_info),
                              std::move(remote_cient_request));
diff --git a/third_party/WebKit/Source/modules/budget/BudgetService.cpp b/third_party/WebKit/Source/modules/budget/BudgetService.cpp
index 8100bee..4b0539c 100644
--- a/third_party/WebKit/Source/modules/budget/BudgetService.cpp
+++ b/third_party/WebKit/Source/modules/budget/BudgetService.cpp
@@ -50,8 +50,8 @@
   // Set a connection error handler, so that if an embedder doesn't
   // implement a BudgetSerice mojo service, the developer will get a
   // actionable information.
-  service_.set_connection_error_handler(ConvertToBaseCallback(
-      WTF::Bind(&BudgetService::OnConnectionError, WrapWeakPersistent(this))));
+  service_.set_connection_error_handler(
+      WTF::Bind(&BudgetService::OnConnectionError, WrapWeakPersistent(this)));
 }
 
 BudgetService::~BudgetService() {}
@@ -72,9 +72,9 @@
   ScriptPromise promise = resolver->Promise();
 
   // Get the cost for the action from the browser BudgetService.
-  service_->GetCost(type, ConvertToBaseCallback(WTF::Bind(
-                              &BudgetService::GotCost, WrapPersistent(this),
-                              WrapPersistent(resolver))));
+  service_->GetCost(type,
+                    WTF::Bind(&BudgetService::GotCost, WrapPersistent(this),
+                              WrapPersistent(resolver)));
   return promise;
 }
 
@@ -97,10 +97,9 @@
   // Get the budget from the browser BudgetService.
   scoped_refptr<const SecurityOrigin> origin(
       ExecutionContext::From(script_state)->GetSecurityOrigin());
-  service_->GetBudget(
-      origin, ConvertToBaseCallback(WTF::Bind(&BudgetService::GotBudget,
-                                              WrapPersistent(this),
-                                              WrapPersistent(resolver))));
+  service_->GetBudget(origin,
+                      WTF::Bind(&BudgetService::GotBudget, WrapPersistent(this),
+                                WrapPersistent(resolver)));
   return promise;
 }
 
@@ -146,9 +145,8 @@
   scoped_refptr<const SecurityOrigin> origin(
       ExecutionContext::From(script_state)->GetSecurityOrigin());
   service_->Reserve(origin, type,
-                    ConvertToBaseCallback(WTF::Bind(
-                        &BudgetService::GotReservation, WrapPersistent(this),
-                        WrapPersistent(resolver))));
+                    WTF::Bind(&BudgetService::GotReservation,
+                              WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
index c9cc4501..404d659 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
@@ -38,7 +38,7 @@
 #include "bindings/modules/v8/rendering_context.h"
 #include "core/CSSPropertyNames.h"
 #include "core/css/CSSFontSelector.h"
-#include "core/css/CSSPropertyValueSet.h"
+#include "core/css/MutableCSSPropertyValueSet.h"
 #include "core/css/StyleEngine.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/AXObjectCache.h"
diff --git a/third_party/WebKit/Source/modules/cookie_store/CookieStore.cpp b/third_party/WebKit/Source/modules/cookie_store/CookieStore.cpp
index 1760dd5b..efdafb3 100644
--- a/third_party/WebKit/Source/modules/cookie_store/CookieStore.cpp
+++ b/third_party/WebKit/Source/modules/cookie_store/CookieStore.cpp
@@ -301,8 +301,7 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   backend_->GetAllForUrl(
       cookie_url, site_for_cookies, std::move(backend_options),
-      ConvertToBaseCallback(
-          WTF::Bind(backend_result_converter, WrapPersistent(resolver))));
+      WTF::Bind(backend_result_converter, WrapPersistent(resolver)));
   return resolver->Promise();
 }
 
@@ -381,8 +380,8 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   backend_->SetCanonicalCookie(
       std::move(canonical_cookie), cookie_url, site_for_cookies,
-      ConvertToBaseCallback(WTF::Bind(&CookieStore::OnSetCanonicalCookieResult,
-                                      WrapPersistent(resolver))));
+      WTF::Bind(&CookieStore::OnSetCanonicalCookieResult,
+                WrapPersistent(resolver)));
   return resolver->Promise();
 }
 
diff --git a/third_party/WebKit/Source/modules/credentialmanager/WebAuthenticationClient.cpp b/third_party/WebKit/Source/modules/credentialmanager/WebAuthenticationClient.cpp
index 56286bba..43bd921 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/WebAuthenticationClient.cpp
+++ b/third_party/WebKit/Source/modules/credentialmanager/WebAuthenticationClient.cpp
@@ -45,9 +45,9 @@
 
 WebAuthenticationClient::WebAuthenticationClient(LocalFrame& frame) {
   frame.GetInterfaceProvider().GetInterface(mojo::MakeRequest(&authenticator_));
-  authenticator_.set_connection_error_handler(ConvertToBaseCallback(
+  authenticator_.set_connection_error_handler(
       WTF::Bind(&WebAuthenticationClient::OnAuthenticatorConnectionError,
-                WrapWeakPersistent(this))));
+                WrapWeakPersistent(this)));
 }
 
 WebAuthenticationClient::~WebAuthenticationClient() {}
@@ -69,10 +69,9 @@
     return;
   }
 
-  authenticator_->MakeCredential(
-      std::move(options),
-      ConvertToBaseCallback(WTF::Bind(&RespondToPublicKeyCallback,
-                                      WTF::Passed(std::move(callbacks)))));
+  authenticator_->MakeCredential(std::move(options),
+                                 WTF::Bind(&RespondToPublicKeyCallback,
+                                           WTF::Passed(std::move(callbacks))));
 }
 
 void WebAuthenticationClient::GetAssertion(
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
index 0087da7..b96ebc7 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletGlobalScopeProxy.cpp
@@ -29,11 +29,9 @@
   reporting_proxy_ =
       std::make_unique<MainThreadWorkletReportingProxy>(document);
 
-  // TODO(nhiroki): Set CSP headers (https://crbug.com/773786).
   auto creation_params = std::make_unique<GlobalScopeCreationParams>(
-      document->Url(), document->UserAgent(), String() /* source_code */,
-      nullptr /* cached_meta_data */,
-      nullptr /* content_security_policy_parsed_headers */,
+      document->Url(), document->UserAgent(),
+      document->GetContentSecurityPolicy()->Headers().get(),
       document->GetReferrerPolicy(), document->GetSecurityOrigin(),
       nullptr /* worker_clients */, document->AddressSpace(),
       OriginTrialContext::GetTokens(document).get(),
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
index fa5e005..9009b94 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
@@ -57,8 +57,8 @@
   TaskRunnerTimer<SetMediaKeysHandler> timer_;
 };
 
-typedef Function<void()> SuccessCallback;
-typedef Function<void(ExceptionCode, const String&)> FailureCallback;
+typedef base::OnceCallback<void()> SuccessCallback;
+typedef base::OnceCallback<void(ExceptionCode, const String&)> FailureCallback;
 
 // Represents the result used when setContentDecryptionModule() is called.
 // Calls |success| if result is resolved, |failure| if result is rejected.
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl
index 5afa7591..1db2035e5 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeyMessageEvent.idl
@@ -28,7 +28,8 @@
 enum MediaKeyMessageType {
     "license-request",
     "license-renewal",
-    "license-release"
+    "license-release",
+    "individualization-request"
 };
 
 [
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
index d944b9d5..91f7ad69 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
@@ -883,6 +883,10 @@
         kLicenseRelease:
       init.setMessageType("license-release");
       break;
+    case WebContentDecryptionModuleSession::Client::MessageType::
+        kIndividualizationRequest:
+      init.setMessageType("individualization-request");
+      break;
   }
   init.setMessage(DOMArrayBuffer::Create(static_cast<const void*>(message),
                                          message_length));
diff --git a/third_party/WebKit/Source/modules/exported/BUILD.gn b/third_party/WebKit/Source/modules/exported/BUILD.gn
index 029d5bb..3f9eda4e 100644
--- a/third_party/WebKit/Source/modules/exported/BUILD.gn
+++ b/third_party/WebKit/Source/modules/exported/BUILD.gn
@@ -15,7 +15,6 @@
     "WebIDBKey.cpp",
     "WebIDBKeyRange.cpp",
     "WebMediaDeviceChangeObserver.cpp",
-    "WebMediaDevicesRequest.cpp",
     "WebMediaStreamRegistry.cpp",
     "WebSpeechGrammar.cpp",
     "WebSpeechRecognitionHandle.cpp",
diff --git a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp
index 071296a2..f8a05f3 100644
--- a/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/modules/exported/WebEmbeddedWorkerImpl.cpp
@@ -302,7 +302,7 @@
       WebURLRequest::kRequestContextServiceWorker,
       network::mojom::FetchRequestMode::kSameOrigin,
       network::mojom::FetchCredentialsMode::kSameOrigin,
-      worker_start_data_.address_space, WTF::Closure(),
+      worker_start_data_.address_space, base::OnceClosure(),
       Bind(&WebEmbeddedWorkerImpl::OnScriptLoaderFinished,
            WTF::Unretained(this)));
   // Do nothing here since onScriptLoaderFinished() might have been already
@@ -385,6 +385,9 @@
       std::make_unique<WorkerSettings>(document->GetSettings());
 
   std::unique_ptr<GlobalScopeCreationParams> global_scope_creation_params;
+  String source_code;
+  std::unique_ptr<Vector<char>> cached_meta_data;
+
   // |main_script_loader_| isn't created if the InstalledScriptsManager had the
   // script.
   if (main_script_loader_) {
@@ -395,14 +398,14 @@
         main_script_loader_->GetReferrerPolicy());
     global_scope_creation_params = std::make_unique<GlobalScopeCreationParams>(
         worker_start_data_.script_url, worker_start_data_.user_agent,
-        main_script_loader_->SourceText(),
-        main_script_loader_->ReleaseCachedMetadata(),
         document->GetContentSecurityPolicy()->Headers().get(),
         document->GetReferrerPolicy(), starter_origin, worker_clients,
         main_script_loader_->ResponseAddressSpace(),
         main_script_loader_->OriginTrialTokens(), std::move(worker_settings),
         static_cast<V8CacheOptions>(worker_start_data_.v8_cache_options),
         std::move(interface_provider_info_));
+    source_code = main_script_loader_->SourceText();
+    cached_meta_data = main_script_loader_->ReleaseCachedMetadata();
     main_script_loader_ = nullptr;
   } else {
     // ContentSecurityPolicy and ReferrerPolicy are applied to |document| at
@@ -410,7 +413,6 @@
     // script.
     global_scope_creation_params = std::make_unique<GlobalScopeCreationParams>(
         worker_start_data_.script_url, worker_start_data_.user_agent,
-        "" /* SourceText */, nullptr /* CachedMetadata */,
         nullptr /* ContentSecurityPolicy */, kReferrerPolicyDefault,
         starter_origin, worker_clients, worker_start_data_.address_space,
         nullptr /* OriginTrialTokens */, std::move(worker_settings),
@@ -436,7 +438,8 @@
       WorkerBackingThreadStartupData::CreateDefault(),
       std::make_unique<GlobalScopeInspectorCreationParams>(
           worker_inspector_proxy_->ShouldPauseOnWorkerStart(document)),
-      ParentFrameTaskRunners::Create());
+      ParentFrameTaskRunners::Create(), source_code,
+      std::move(cached_meta_data));
 
   worker_inspector_proxy_->WorkerThreadCreated(document, worker_thread_.get(),
                                                worker_start_data_.script_url);
diff --git a/third_party/WebKit/Source/modules/exported/WebMediaDevicesRequest.cpp b/third_party/WebKit/Source/modules/exported/WebMediaDevicesRequest.cpp
deleted file mode 100644
index 09ec9f6..0000000
--- a/third_party/WebKit/Source/modules/exported/WebMediaDevicesRequest.cpp
+++ /dev/null
@@ -1,83 +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. ``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
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "public/web/WebMediaDevicesRequest.h"
-
-#include "modules/mediastream/MediaDevicesRequest.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "platform/wtf/Vector.h"
-#include "public/platform/WebMediaDeviceInfo.h"
-#include "public/platform/WebSecurityOrigin.h"
-#include "public/platform/WebString.h"
-#include "public/platform/WebVector.h"
-#include "public/web/WebDocument.h"
-
-namespace blink {
-
-WebMediaDevicesRequest::WebMediaDevicesRequest(MediaDevicesRequest* request)
-    : private_(request) {}
-
-void WebMediaDevicesRequest::Reset() {
-  private_.Reset();
-}
-
-WebSecurityOrigin WebMediaDevicesRequest::GetSecurityOrigin() const {
-  DCHECK(!IsNull());
-  DCHECK(private_->GetExecutionContext());
-  return WebSecurityOrigin(
-      private_->GetExecutionContext()->GetSecurityOrigin());
-}
-
-WebDocument WebMediaDevicesRequest::OwnerDocument() const {
-  DCHECK(!IsNull());
-  return WebDocument(private_->OwnerDocument());
-}
-
-void WebMediaDevicesRequest::RequestSucceeded(
-    WebVector<WebMediaDeviceInfo> web_devices) {
-  DCHECK(!IsNull());
-
-  MediaDeviceInfoVector devices(web_devices.size());
-  for (size_t i = 0; i < web_devices.size(); ++i)
-    devices[i] = MediaDeviceInfo::Create(web_devices[i]);
-
-  private_->Succeed(devices);
-}
-
-bool WebMediaDevicesRequest::Equals(const WebMediaDevicesRequest& other) const {
-  if (IsNull() || other.IsNull())
-    return false;
-  return private_.Get() == other.private_.Get();
-}
-
-void WebMediaDevicesRequest::Assign(const WebMediaDevicesRequest& other) {
-  private_ = other.private_;
-}
-
-WebMediaDevicesRequest::operator MediaDevicesRequest*() const {
-  return private_.Get();
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp
index a5cda40..f43214f 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.cpp
@@ -57,7 +57,7 @@
 namespace {
 
 void RunCallback(ExecutionContext* execution_context,
-                 WTF::Closure task,
+                 base::OnceClosure task,
                  std::unique_ptr<int> identifier) {
   if (!execution_context)
     return;
@@ -207,7 +207,7 @@
 }
 
 void DOMFileSystem::ScheduleCallback(ExecutionContext* execution_context,
-                                     WTF::Closure task) {
+                                     base::OnceClosure task) {
   DCHECK(execution_context->IsContextThread());
 
   std::unique_ptr<int> identifier = std::make_unique<int>(0);
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h
index 784eae6..303a4292 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h
@@ -86,7 +86,7 @@
   // Schedule a callback. This should not cross threads (should be called on the
   // same context thread).
   static void ScheduleCallback(ExecutionContext* execution_context,
-                               WTF::Closure task);
+                               base::OnceClosure task);
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp
index 2d57722..391ecc7 100644
--- a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.cpp
@@ -112,9 +112,10 @@
   return platform->FileSystem();
 }
 
-void LocalFileSystem::RequestFileSystemAccessInternal(ExecutionContext* context,
-                                                      WTF::Closure allowed,
-                                                      WTF::Closure denied) {
+void LocalFileSystem::RequestFileSystemAccessInternal(
+    ExecutionContext* context,
+    base::OnceClosure allowed,
+    base::OnceClosure denied) {
   if (!context->IsDocument()) {
     if (!Client().RequestFileSystemAccessSync(context)) {
       std::move(denied).Run();
diff --git a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h
index 053d872..77c240b 100644
--- a/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h
+++ b/third_party/WebKit/Source/modules/filesystem/LocalFileSystem.h
@@ -81,8 +81,8 @@
   void FileSystemNotAvailable(ExecutionContext*, CallbackWrapper*);
 
   void RequestFileSystemAccessInternal(ExecutionContext*,
-                                       WTF::Closure allowed,
-                                       WTF::Closure denied);
+                                       base::OnceClosure allowed,
+                                       base::OnceClosure denied);
   void FileSystemNotAllowedInternal(ExecutionContext*, CallbackWrapper*);
   void FileSystemAllowedInternal(ExecutionContext*,
                                  FileSystemType,
diff --git a/third_party/WebKit/Source/modules/gamepad/GamepadHapticActuator.cpp b/third_party/WebKit/Source/modules/gamepad/GamepadHapticActuator.cpp
index 943fc2d..c9496418 100644
--- a/third_party/WebKit/Source/modules/gamepad/GamepadHapticActuator.cpp
+++ b/third_party/WebKit/Source/modules/gamepad/GamepadHapticActuator.cpp
@@ -102,9 +102,8 @@
     return promise;
   }
 
-  auto callback = ConvertToBaseCallback(
-      WTF::Bind(&GamepadHapticActuator::OnPlayEffectCompleted,
-                WrapPersistent(this), WrapPersistent(resolver)));
+  auto callback = WTF::Bind(&GamepadHapticActuator::OnPlayEffectCompleted,
+                            WrapPersistent(this), WrapPersistent(resolver));
 
   GamepadDispatcher::Instance().PlayVibrationEffectOnce(
       pad_index_, EffectTypeFromString(type),
@@ -129,9 +128,8 @@
 ScriptPromise GamepadHapticActuator::reset(ScriptState* script_state) {
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
 
-  auto callback = ConvertToBaseCallback(
-      WTF::Bind(&GamepadHapticActuator::OnResetCompleted, WrapPersistent(this),
-                WrapPersistent(resolver)));
+  auto callback = WTF::Bind(&GamepadHapticActuator::OnResetCompleted,
+                            WrapPersistent(this), WrapPersistent(resolver));
 
   GamepadDispatcher::Instance().ResetVibrationActuator(pad_index_,
                                                        std::move(callback));
diff --git a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
index 2d4fafd..a2649fb 100644
--- a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
+++ b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
@@ -481,16 +481,16 @@
       mojo::MakeRequest(&geolocation_),
       Frame::HasTransientUserActivation(GetFrame()));
 
-  geolocation_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-      &Geolocation::OnGeolocationConnectionError, WrapWeakPersistent(this))));
+  geolocation_.set_connection_error_handler(WTF::Bind(
+      &Geolocation::OnGeolocationConnectionError, WrapWeakPersistent(this)));
   if (enable_high_accuracy_)
     geolocation_->SetHighAccuracy(true);
   QueryNextPosition();
 }
 
 void Geolocation::QueryNextPosition() {
-  geolocation_->QueryNextPosition(ConvertToBaseCallback(
-      WTF::Bind(&Geolocation::OnPositionUpdated, WrapPersistent(this))));
+  geolocation_->QueryNextPosition(
+      WTF::Bind(&Geolocation::OnPositionUpdated, WrapPersistent(this)));
 }
 
 void Geolocation::OnPositionUpdated(
diff --git a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp
index 6b0fafa..7e422ca 100644
--- a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp
+++ b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp
@@ -142,10 +142,9 @@
   // scriptState->getExecutionContext()->getSecurityOrigin()->toString()
   service_->GetPhotoState(
       stream_track_->Component()->Source()->Id(),
-      ConvertToBaseCallback(WTF::Bind(
-          &ImageCapture::OnMojoGetPhotoState, WrapPersistent(this),
-          WrapPersistent(resolver), WTF::Passed(std::move(resolver_cb)),
-          false /* trigger_take_photo */)));
+      WTF::Bind(&ImageCapture::OnMojoGetPhotoState, WrapPersistent(this),
+                WrapPersistent(resolver), WTF::Passed(std::move(resolver_cb)),
+                false /* trigger_take_photo */));
   return promise;
 }
 
@@ -168,10 +167,9 @@
   // scriptState->getExecutionContext()->getSecurityOrigin()->toString()
   service_->GetPhotoState(
       stream_track_->Component()->Source()->Id(),
-      ConvertToBaseCallback(WTF::Bind(
-          &ImageCapture::OnMojoGetPhotoState, WrapPersistent(this),
-          WrapPersistent(resolver), WTF::Passed(std::move(resolver_cb)),
-          false /* trigger_take_photo */)));
+      WTF::Bind(&ImageCapture::OnMojoGetPhotoState, WrapPersistent(this),
+                WrapPersistent(resolver), WTF::Passed(std::move(resolver_cb)),
+                false /* trigger_take_photo */));
   return promise;
 }
 
@@ -246,9 +244,8 @@
 
   service_->SetOptions(
       stream_track_->Component()->Source()->Id(), std::move(settings),
-      ConvertToBaseCallback(
-          WTF::Bind(&ImageCapture::OnMojoSetOptions, WrapPersistent(this),
-                    WrapPersistent(resolver), trigger_take_photo)));
+      WTF::Bind(&ImageCapture::OnMojoSetOptions, WrapPersistent(this),
+                WrapPersistent(resolver), trigger_take_photo));
   return promise;
 }
 
@@ -272,10 +269,10 @@
   // camera;
   // TODO(mcasas) consider sending the security origin as well:
   // scriptState->getExecutionContext()->getSecurityOrigin()->toString()
-  service_->TakePhoto(stream_track_->Component()->Source()->Id(),
-                      ConvertToBaseCallback(WTF::Bind(
-                          &ImageCapture::OnMojoTakePhoto, WrapPersistent(this),
-                          WrapPersistent(resolver))));
+  service_->TakePhoto(
+      stream_track_->Component()->Source()->Id(),
+      WTF::Bind(&ImageCapture::OnMojoTakePhoto, WrapPersistent(this),
+                WrapPersistent(resolver)));
   return promise;
 }
 
@@ -537,9 +534,8 @@
 
   service_->SetOptions(
       stream_track_->Component()->Source()->Id(), std::move(settings),
-      ConvertToBaseCallback(
-          WTF::Bind(&ImageCapture::OnMojoSetOptions, WrapPersistent(this),
-                    WrapPersistent(resolver), false /* trigger_take_photo */)));
+      WTF::Bind(&ImageCapture::OnMojoSetOptions, WrapPersistent(this),
+                WrapPersistent(resolver), false /* trigger_take_photo */));
 }
 
 const MediaTrackConstraintSet& ImageCapture::GetMediaTrackConstraints() const {
@@ -603,15 +599,14 @@
 
   GetFrame()->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_));
 
-  service_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-      &ImageCapture::OnServiceConnectionError, WrapWeakPersistent(this))));
+  service_.set_connection_error_handler(WTF::Bind(
+      &ImageCapture::OnServiceConnectionError, WrapWeakPersistent(this)));
 
   // Launch a retrieval of the current photo state, which arrive asynchronously
   // to avoid blocking the main UI thread.
-  service_->GetPhotoState(
-      stream_track_->Component()->Source()->Id(),
-      ConvertToBaseCallback(WTF::Bind(
-          &ImageCapture::UpdateMediaTrackCapabilities, WrapPersistent(this))));
+  service_->GetPhotoState(stream_track_->Component()->Source()->Id(),
+                          WTF::Bind(&ImageCapture::UpdateMediaTrackCapabilities,
+                                    WrapPersistent(this)));
 }
 
 void ImageCapture::OnMojoGetPhotoState(
@@ -652,10 +647,10 @@
   UpdateMediaTrackCapabilities(std::move(photo_state));
 
   if (trigger_take_photo) {
-    service_->TakePhoto(stream_track_->Component()->Source()->Id(),
-                        ConvertToBaseCallback(WTF::Bind(
-                            &ImageCapture::OnMojoTakePhoto,
-                            WrapPersistent(this), WrapPersistent(resolver))));
+    service_->TakePhoto(
+        stream_track_->Component()->Source()->Id(),
+        WTF::Bind(&ImageCapture::OnMojoTakePhoto, WrapPersistent(this),
+                  WrapPersistent(resolver)));
     return;
   }
 
@@ -680,10 +675,9 @@
   // Retrieve the current device status after setting the options.
   service_->GetPhotoState(
       stream_track_->Component()->Source()->Id(),
-      ConvertToBaseCallback(
-          WTF::Bind(&ImageCapture::OnMojoGetPhotoState, WrapPersistent(this),
-                    WrapPersistent(resolver),
-                    WTF::Passed(std::move(resolver_cb)), trigger_take_photo)));
+      WTF::Bind(&ImageCapture::OnMojoGetPhotoState, WrapPersistent(this),
+                WrapPersistent(resolver), WTF::Passed(std::move(resolver_cb)),
+                trigger_take_photo));
 }
 
 void ImageCapture::OnMojoTakePhoto(ScriptPromiseResolver* resolver,
diff --git a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h
index 1ad84ef9..a54c1e9 100644
--- a/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h
+++ b/third_party/WebKit/Source/modules/imagecapture/ImageCapture.h
@@ -76,7 +76,8 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  using PromiseResolverFunction = Function<void(ScriptPromiseResolver*)>;
+  using PromiseResolverFunction =
+      base::OnceCallback<void(ScriptPromiseResolver*)>;
 
   ImageCapture(ExecutionContext*, MediaStreamTrack*);
 
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
index 105fb15..e86000b 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
@@ -578,9 +578,17 @@
     return nullptr;
   }
 
+  return deleteFunction(script_state, key_range, std::move(metrics));
+}
+
+IDBRequest* IDBObjectStore::deleteFunction(
+    ScriptState* script_state,
+    IDBKeyRange* key_range,
+    IDBRequest::AsyncTraceState metrics) {
   IDBRequest* request =
       IDBRequest::Create(script_state, IDBAny::Create(this), transaction_.Get(),
                          std::move(metrics));
+
   BackendDB()->DeleteRange(transaction_->Id(), Id(), key_range,
                            request->CreateWebCallbacks().release());
   return request;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h
index 44b1c322..a060f080 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.h
@@ -132,6 +132,10 @@
       WebIDBCursorDirection,
       WebIDBTaskType = kWebIDBTaskTypeNormal,
       IDBRequest::AsyncTraceState = IDBRequest::AsyncTraceState());
+  IDBRequest* deleteFunction(
+      ScriptState*,
+      IDBKeyRange*,
+      IDBRequest::AsyncTraceState = IDBRequest::AsyncTraceState());
 
   void MarkDeleted();
   bool IsDeleted() const { return deleted_; }
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp
index bc449040d..557e3ba 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.cpp
@@ -17,9 +17,10 @@
 
 namespace blink {
 
-IDBRequestQueueItem::IDBRequestQueueItem(IDBRequest* request,
-                                         DOMException* error,
-                                         WTF::Closure on_result_load_complete)
+IDBRequestQueueItem::IDBRequestQueueItem(
+    IDBRequest* request,
+    DOMException* error,
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       error_(error),
       on_result_load_complete_(std::move(on_result_load_complete)),
@@ -30,9 +31,10 @@
   request_->queue_item_ = this;
 }
 
-IDBRequestQueueItem::IDBRequestQueueItem(IDBRequest* request,
-                                         int64_t value,
-                                         WTF::Closure on_result_load_complete)
+IDBRequestQueueItem::IDBRequestQueueItem(
+    IDBRequest* request,
+    int64_t value,
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       on_result_load_complete_(std::move(on_result_load_complete)),
       int64_value_(value),
@@ -43,8 +45,9 @@
   request_->queue_item_ = this;
 }
 
-IDBRequestQueueItem::IDBRequestQueueItem(IDBRequest* request,
-                                         WTF::Closure on_result_load_complete)
+IDBRequestQueueItem::IDBRequestQueueItem(
+    IDBRequest* request,
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       on_result_load_complete_(std::move(on_result_load_complete)),
       response_type_(kVoid),
@@ -54,9 +57,10 @@
   request_->queue_item_ = this;
 }
 
-IDBRequestQueueItem::IDBRequestQueueItem(IDBRequest* request,
-                                         IDBKey* key,
-                                         WTF::Closure on_result_load_complete)
+IDBRequestQueueItem::IDBRequestQueueItem(
+    IDBRequest* request,
+    IDBKey* key,
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       key_(key),
       on_result_load_complete_(std::move(on_result_load_complete)),
@@ -67,10 +71,11 @@
   request_->queue_item_ = this;
 }
 
-IDBRequestQueueItem::IDBRequestQueueItem(IDBRequest* request,
-                                         scoped_refptr<IDBValue> value,
-                                         bool attach_loader,
-                                         WTF::Closure on_result_load_complete)
+IDBRequestQueueItem::IDBRequestQueueItem(
+    IDBRequest* request,
+    scoped_refptr<IDBValue> value,
+    bool attach_loader,
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       on_result_load_complete_(std::move(on_result_load_complete)),
       response_type_(kValue),
@@ -87,7 +92,7 @@
     IDBRequest* request,
     const Vector<scoped_refptr<IDBValue>>& values,
     bool attach_loader,
-    WTF::Closure on_result_load_complete)
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       values_(values),
       on_result_load_complete_(std::move(on_result_load_complete)),
@@ -100,12 +105,13 @@
     loader_ = std::make_unique<IDBRequestLoader>(this, &values_);
 }
 
-IDBRequestQueueItem::IDBRequestQueueItem(IDBRequest* request,
-                                         IDBKey* key,
-                                         IDBKey* primary_key,
-                                         scoped_refptr<IDBValue> value,
-                                         bool attach_loader,
-                                         WTF::Closure on_result_load_complete)
+IDBRequestQueueItem::IDBRequestQueueItem(
+    IDBRequest* request,
+    IDBKey* key,
+    IDBKey* primary_key,
+    scoped_refptr<IDBValue> value,
+    bool attach_loader,
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       key_(key),
       primary_key_(primary_key),
@@ -120,13 +126,14 @@
     loader_ = std::make_unique<IDBRequestLoader>(this, &values_);
 }
 
-IDBRequestQueueItem::IDBRequestQueueItem(IDBRequest* request,
-                                         std::unique_ptr<WebIDBCursor> cursor,
-                                         IDBKey* key,
-                                         IDBKey* primary_key,
-                                         scoped_refptr<IDBValue> value,
-                                         bool attach_loader,
-                                         WTF::Closure on_result_load_complete)
+IDBRequestQueueItem::IDBRequestQueueItem(
+    IDBRequest* request,
+    std::unique_ptr<WebIDBCursor> cursor,
+    IDBKey* key,
+    IDBKey* primary_key,
+    scoped_refptr<IDBValue> value,
+    bool attach_loader,
+    base::OnceClosure on_result_load_complete)
     : request_(request),
       key_(key),
       primary_key_(primary_key),
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h
index 6204337..c99d758 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequestQueueItem.h
@@ -48,35 +48,35 @@
  public:
   IDBRequestQueueItem(IDBRequest*,
                       DOMException*,
-                      WTF::Closure on_result_load_complete);
+                      base::OnceClosure on_result_load_complete);
   IDBRequestQueueItem(IDBRequest*,
                       int64_t,
-                      WTF::Closure on_result_load_complete);
-  IDBRequestQueueItem(IDBRequest*, WTF::Closure on_result_load_complete);
+                      base::OnceClosure on_result_load_complete);
+  IDBRequestQueueItem(IDBRequest*, base::OnceClosure on_result_load_complete);
   IDBRequestQueueItem(IDBRequest*,
                       IDBKey*,
-                      WTF::Closure on_result_load_complete);
+                      base::OnceClosure on_result_load_complete);
   IDBRequestQueueItem(IDBRequest*,
                       scoped_refptr<IDBValue>,
                       bool attach_loader,
-                      WTF::Closure on_load_complete);
+                      base::OnceClosure on_load_complete);
   IDBRequestQueueItem(IDBRequest*,
                       const Vector<scoped_refptr<IDBValue>>&,
                       bool attach_loader,
-                      WTF::Closure on_result_load_complete);
+                      base::OnceClosure on_result_load_complete);
   IDBRequestQueueItem(IDBRequest*,
                       IDBKey*,
                       IDBKey* primary_key,
                       scoped_refptr<IDBValue>,
                       bool attach_loader,
-                      WTF::Closure on_result_load_complete);
+                      base::OnceClosure on_result_load_complete);
   IDBRequestQueueItem(IDBRequest*,
                       std::unique_ptr<WebIDBCursor>,
                       IDBKey*,
                       IDBKey* primary_key,
                       scoped_refptr<IDBValue>,
                       bool attach_loader,
-                      WTF::Closure on_result_load_complete);
+                      base::OnceClosure on_result_load_complete);
   ~IDBRequestQueueItem();
 
   // False if this result still requires post-processing.
@@ -155,7 +155,7 @@
   std::unique_ptr<IDBRequestLoader> loader_;
 
   // Called when result post-processing has completed.
-  WTF::Closure on_result_load_complete_;
+  base::OnceClosure on_result_load_complete_;
 
   // The integer value argument to the IDBRequest callback.
   int64_t int64_value_;
diff --git a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
index 5f56e54..180ee80 100644
--- a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
@@ -79,6 +79,8 @@
     RequestDatabaseCallback;
 typedef blink::protocol::IndexedDB::Backend::RequestDataCallback
     RequestDataCallback;
+typedef blink::protocol::IndexedDB::Backend::DeleteObjectStoreEntriesCallback
+    DeleteObjectStoreEntriesCallback;
 typedef blink::protocol::IndexedDB::Backend::ClearObjectStoreCallback
     ClearObjectStoreCallback;
 typedef blink::protocol::IndexedDB::Backend::DeleteDatabaseCallback
@@ -95,6 +97,18 @@
 static const char kIndexedDBObjectGroup[] = "indexeddb";
 static const char kNoDocumentError[] = "No document for given frame found";
 
+static Response AssertIDBFactory(Document* document, IDBFactory*& result) {
+  LocalDOMWindow* dom_window = document->domWindow();
+  if (!dom_window)
+    return Response::Error("No IndexedDB factory for given frame found");
+  IDBFactory* idb_factory = GlobalIndexedDB::indexedDB(*dom_window);
+
+  if (!idb_factory)
+    return Response::Error("No IndexedDB factory for given frame found");
+  result = idb_factory;
+  return Response::OK();
+}
+
 class GetDatabaseNamesCallback final : public EventListener {
   WTF_MAKE_NONCOPYABLE(GetDatabaseNamesCallback);
 
@@ -193,22 +207,47 @@
 class ExecutableWithDatabase
     : public RefCounted<ExecutableWithDatabase<RequestCallback>> {
  public:
-  ExecutableWithDatabase(ScriptState* script_state)
-      : script_state_(script_state) {}
   virtual ~ExecutableWithDatabase() {}
-  void Start(IDBFactory* idb_factory,
-             const SecurityOrigin*,
-             const String& database_name) {
+  virtual void Execute(IDBDatabase*, ScriptState*) = 0;
+  virtual RequestCallback* GetRequestCallback() = 0;
+  void Start(LocalFrame* frame, const String& database_name) {
+    Document* document = frame ? frame->GetDocument() : nullptr;
+    if (!document) {
+      SendFailure(Response::Error(kNoDocumentError));
+      return;
+    }
+    IDBFactory* idb_factory = nullptr;
+    Response response = AssertIDBFactory(document, idb_factory);
+    if (!response.isSuccess()) {
+      SendFailure(response);
+      return;
+    }
+
+    ScriptState* script_state = ToScriptStateForMainWorld(frame);
+    if (!script_state) {
+      SendFailure(Response::InternalError());
+      return;
+    }
+
+    ScriptState::Scope scope(script_state);
+    DoStart(idb_factory, script_state, document->GetSecurityOrigin(),
+            database_name);
+  }
+
+ private:
+  void DoStart(IDBFactory* idb_factory,
+               ScriptState* script_state,
+               const SecurityOrigin*,
+               const String& database_name) {
     OpenDatabaseCallback<RequestCallback>* open_callback =
-        OpenDatabaseCallback<RequestCallback>::Create(this);
+        OpenDatabaseCallback<RequestCallback>::Create(this, script_state);
     UpgradeDatabaseCallback<RequestCallback>* upgrade_callback =
         UpgradeDatabaseCallback<RequestCallback>::Create(this);
     DummyExceptionStateForTesting exception_state;
     IDBOpenDBRequest* idb_open_db_request =
-        idb_factory->open(GetScriptState(), database_name, exception_state);
+        idb_factory->open(script_state, database_name, exception_state);
     if (exception_state.HadException()) {
-      GetRequestCallback()->sendFailure(
-          Response::Error("Could not open database."));
+      SendFailure(Response::Error("Could not open database."));
       return;
     }
     idb_open_db_request->addEventListener(EventTypeNames::upgradeneeded,
@@ -216,23 +255,19 @@
     idb_open_db_request->addEventListener(EventTypeNames::success,
                                           open_callback, false);
   }
-  virtual void Execute(IDBDatabase*) = 0;
-  virtual RequestCallback* GetRequestCallback() = 0;
-  ExecutionContext* Context() const {
-    return ExecutionContext::From(script_state_.get());
-  }
-  ScriptState* GetScriptState() const { return script_state_.get(); }
 
- private:
-  scoped_refptr<ScriptState> script_state_;
+  void SendFailure(Response response) {
+    GetRequestCallback()->sendFailure(response);
+  }
 };
 
 template <typename RequestCallback>
 class OpenDatabaseCallback final : public EventListener {
  public:
   static OpenDatabaseCallback* Create(
-      ExecutableWithDatabase<RequestCallback>* executable_with_database) {
-    return new OpenDatabaseCallback(executable_with_database);
+      ExecutableWithDatabase<RequestCallback>* executable_with_database,
+      scoped_refptr<ScriptState> script_state) {
+    return new OpenDatabaseCallback(executable_with_database, script_state);
   }
 
   ~OpenDatabaseCallback() override {}
@@ -258,20 +293,21 @@
     }
 
     IDBDatabase* idb_database = request_result->IdbDatabase();
-    executable_with_database_->Execute(idb_database);
-    V8PerIsolateData::From(
-        executable_with_database_->GetScriptState()->GetIsolate())
-        ->RunEndOfScopeTasks();
+    executable_with_database_->Execute(idb_database, script_state_.get());
+    V8PerIsolateData::From(script_state_->GetIsolate())->RunEndOfScopeTasks();
     idb_database->close();
   }
 
  private:
   OpenDatabaseCallback(
-      ExecutableWithDatabase<RequestCallback>* executable_with_database)
+      ExecutableWithDatabase<RequestCallback>* executable_with_database,
+      scoped_refptr<ScriptState> script_state)
       : EventListener(EventListener::kCPPEventListenerType),
-        executable_with_database_(executable_with_database) {}
+        executable_with_database_(executable_with_database),
+        script_state_(script_state) {}
   scoped_refptr<ExecutableWithDatabase<RequestCallback>>
       executable_with_database_;
+  scoped_refptr<ScriptState> script_state_;
 };
 
 template <typename RequestCallback>
@@ -384,15 +420,13 @@
     : public ExecutableWithDatabase<RequestDatabaseCallback> {
  public:
   static scoped_refptr<DatabaseLoader> Create(
-      ScriptState* script_state,
       std::unique_ptr<RequestDatabaseCallback> request_callback) {
-    return base::AdoptRef(
-        new DatabaseLoader(script_state, std::move(request_callback)));
+    return base::AdoptRef(new DatabaseLoader(std::move(request_callback)));
   }
 
   ~DatabaseLoader() override {}
 
-  void Execute(IDBDatabase* idb_database) override {
+  void Execute(IDBDatabase* idb_database, ScriptState*) override {
     const IDBDatabaseMetadata database_metadata = idb_database->Metadata();
 
     std::unique_ptr<protocol::Array<protocol::IndexedDB::ObjectStore>>
@@ -444,10 +478,8 @@
   }
 
  private:
-  DatabaseLoader(ScriptState* script_state,
-                 std::unique_ptr<RequestDatabaseCallback> request_callback)
-      : ExecutableWithDatabase(script_state),
-        request_callback_(std::move(request_callback)) {}
+  DatabaseLoader(std::unique_ptr<RequestDatabaseCallback> request_callback)
+      : request_callback_(std::move(request_callback)) {}
   std::unique_ptr<RequestDatabaseCallback> request_callback_;
 };
 
@@ -632,7 +664,6 @@
  public:
   static scoped_refptr<DataLoader> Create(
       v8_inspector::V8InspectorSession* v8_session,
-      ScriptState* script_state,
       std::unique_ptr<RequestDataCallback> request_callback,
       const String& object_store_name,
       const String& index_name,
@@ -640,15 +671,15 @@
       int skip_count,
       unsigned page_size) {
     return base::AdoptRef(new DataLoader(
-        v8_session, script_state, std::move(request_callback),
-        object_store_name, index_name, idb_key_range, skip_count, page_size));
+        v8_session, std::move(request_callback), object_store_name, index_name,
+        idb_key_range, skip_count, page_size));
   }
 
   ~DataLoader() override {}
 
-  void Execute(IDBDatabase* idb_database) override {
-    IDBTransaction* idb_transaction = TransactionForDatabase(
-        GetScriptState(), idb_database, object_store_name_);
+  void Execute(IDBDatabase* idb_database, ScriptState* script_state) override {
+    IDBTransaction* idb_transaction =
+        TransactionForDatabase(script_state, idb_database, object_store_name_);
     if (!idb_transaction) {
       request_callback_->sendFailure(
           Response::Error("Could not get transaction"));
@@ -670,15 +701,15 @@
         return;
       }
 
-      idb_request = idb_index->openCursor(
-          GetScriptState(), idb_key_range_.Get(), kWebIDBCursorDirectionNext);
+      idb_request = idb_index->openCursor(script_state, idb_key_range_.Get(),
+                                          kWebIDBCursorDirectionNext);
     } else {
       idb_request = idb_object_store->openCursor(
-          GetScriptState(), idb_key_range_.Get(), kWebIDBCursorDirectionNext);
+          script_state, idb_key_range_.Get(), kWebIDBCursorDirectionNext);
     }
     OpenCursorCallback* open_cursor_callback = OpenCursorCallback::Create(
-        v8_session_, GetScriptState(), std::move(request_callback_),
-        skip_count_, page_size_);
+        v8_session_, script_state, std::move(request_callback_), skip_count_,
+        page_size_);
     idb_request->addEventListener(EventTypeNames::success, open_cursor_callback,
                                   false);
   }
@@ -687,15 +718,13 @@
     return request_callback_.get();
   }
   DataLoader(v8_inspector::V8InspectorSession* v8_session,
-             ScriptState* script_state,
              std::unique_ptr<RequestDataCallback> request_callback,
              const String& object_store_name,
              const String& index_name,
              IDBKeyRange* idb_key_range,
              int skip_count,
              unsigned page_size)
-      : ExecutableWithDatabase(script_state),
-        v8_session_(v8_session),
+      : v8_session_(v8_session),
         request_callback_(std::move(request_callback)),
         object_store_name_(object_store_name),
         index_name_(index_name),
@@ -748,18 +777,6 @@
   return Response::OK();
 }
 
-static Response AssertIDBFactory(Document* document, IDBFactory*& result) {
-  LocalDOMWindow* dom_window = document->domWindow();
-  if (!dom_window)
-    return Response::Error("No IndexedDB factory for given frame found");
-  IDBFactory* idb_factory = GlobalIndexedDB::indexedDB(*dom_window);
-
-  if (!idb_factory)
-    return Response::Error("No IndexedDB factory for given frame found");
-  result = idb_factory;
-  return Response::OK();
-}
-
 void InspectorIndexedDBAgent::requestDatabaseNames(
     const String& security_origin,
     std::unique_ptr<RequestDatabaseNamesCallback> request_callback) {
@@ -803,31 +820,11 @@
     const String& security_origin,
     const String& database_name,
     std::unique_ptr<RequestDatabaseCallback> request_callback) {
-  LocalFrame* frame =
-      inspected_frames_->FrameWithSecurityOrigin(security_origin);
-  Document* document = frame ? frame->GetDocument() : nullptr;
-  if (!document) {
-    request_callback->sendFailure(Response::Error(kNoDocumentError));
-    return;
-  }
-  IDBFactory* idb_factory = nullptr;
-  Response response = AssertIDBFactory(document, idb_factory);
-  if (!response.isSuccess()) {
-    request_callback->sendFailure(response);
-    return;
-  }
-
-  ScriptState* script_state = ToScriptStateForMainWorld(frame);
-  if (!script_state) {
-    request_callback->sendFailure(Response::InternalError());
-    return;
-  }
-
-  ScriptState::Scope scope(script_state);
   scoped_refptr<DatabaseLoader> database_loader =
-      DatabaseLoader::Create(script_state, std::move(request_callback));
-  database_loader->Start(idb_factory, document->GetSecurityOrigin(),
-                         database_name);
+      DatabaseLoader::Create(std::move(request_callback));
+  database_loader->Start(
+      inspected_frames_->FrameWithSecurityOrigin(security_origin),
+      database_name);
 }
 
 void InspectorIndexedDBAgent::requestData(
@@ -839,20 +836,6 @@
     int page_size,
     Maybe<protocol::IndexedDB::KeyRange> key_range,
     std::unique_ptr<RequestDataCallback> request_callback) {
-  LocalFrame* frame =
-      inspected_frames_->FrameWithSecurityOrigin(security_origin);
-  Document* document = frame ? frame->GetDocument() : nullptr;
-  if (!document) {
-    request_callback->sendFailure(Response::Error(kNoDocumentError));
-    return;
-  }
-  IDBFactory* idb_factory = nullptr;
-  Response response = AssertIDBFactory(document, idb_factory);
-  if (!response.isSuccess()) {
-    request_callback->sendFailure(response);
-    return;
-  }
-
   IDBKeyRange* idb_key_range =
       key_range.isJust() ? IdbKeyRangeFromKeyRange(key_range.fromJust())
                          : nullptr;
@@ -861,17 +844,122 @@
     return;
   }
 
-  ScriptState* script_state = ToScriptStateForMainWorld(frame);
-  if (!script_state) {
-    request_callback->sendFailure(Response::InternalError());
-    return;
+  scoped_refptr<DataLoader> data_loader = DataLoader::Create(
+      v8_session_, std::move(request_callback), object_store_name, index_name,
+      idb_key_range, skip_count, page_size);
+
+  data_loader->Start(
+      inspected_frames_->FrameWithSecurityOrigin(security_origin),
+      database_name);
+}
+
+class DeleteObjectStoreEntriesListener final : public EventListener {
+  WTF_MAKE_NONCOPYABLE(DeleteObjectStoreEntriesListener);
+
+ public:
+  static DeleteObjectStoreEntriesListener* Create(
+      std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback) {
+    return new DeleteObjectStoreEntriesListener(std::move(request_callback));
   }
 
-  ScriptState::Scope scope(script_state);
-  scoped_refptr<DataLoader> data_loader = DataLoader::Create(
-      v8_session_, script_state, std::move(request_callback), object_store_name,
-      index_name, idb_key_range, skip_count, page_size);
-  data_loader->Start(idb_factory, document->GetSecurityOrigin(), database_name);
+  ~DeleteObjectStoreEntriesListener() override {}
+
+  bool operator==(const EventListener& other) const override {
+    return this == &other;
+  }
+
+  void handleEvent(ExecutionContext*, Event* event) override {
+    if (event->type() != EventTypeNames::success) {
+      request_callback_->sendFailure(
+          Response::Error("Failed to delete specified entries"));
+      return;
+    }
+
+    request_callback_->sendSuccess();
+  }
+
+  virtual void Trace(blink::Visitor* visitor) { EventListener::Trace(visitor); }
+
+ private:
+  DeleteObjectStoreEntriesListener(
+      std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback)
+      : EventListener(EventListener::kCPPEventListenerType),
+        request_callback_(std::move(request_callback)) {}
+
+  std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback_;
+};
+
+class DeleteObjectStoreEntries final
+    : public ExecutableWithDatabase<DeleteObjectStoreEntriesCallback> {
+ public:
+  static scoped_refptr<DeleteObjectStoreEntries> Create(
+      const String& object_store_name,
+      IDBKeyRange* idb_key_range,
+      std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback) {
+    return AdoptRef(new DeleteObjectStoreEntries(
+        object_store_name, idb_key_range, std::move(request_callback)));
+  }
+
+  DeleteObjectStoreEntries(
+      const String& object_store_name,
+      IDBKeyRange* idb_key_range,
+      std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback)
+      : object_store_name_(object_store_name),
+        idb_key_range_(idb_key_range),
+        request_callback_(std::move(request_callback)) {}
+
+  void Execute(IDBDatabase* idb_database, ScriptState* script_state) override {
+    IDBTransaction* idb_transaction =
+        TransactionForDatabase(script_state, idb_database, object_store_name_,
+                               IndexedDBNames::readwrite);
+    if (!idb_transaction) {
+      request_callback_->sendFailure(
+          Response::Error("Could not get transaction"));
+      return;
+    }
+    IDBObjectStore* idb_object_store =
+        ObjectStoreForTransaction(idb_transaction, object_store_name_);
+    if (!idb_object_store) {
+      request_callback_->sendFailure(
+          Response::Error("Could not get object store"));
+      return;
+    }
+
+    IDBRequest* idb_request =
+        idb_object_store->deleteFunction(script_state, idb_key_range_.Get());
+    idb_request->addEventListener(
+        EventTypeNames::success,
+        DeleteObjectStoreEntriesListener::Create(std::move(request_callback_)),
+        false);
+  }
+
+  DeleteObjectStoreEntriesCallback* GetRequestCallback() override {
+    return request_callback_.get();
+  }
+
+ private:
+  const String object_store_name_;
+  Persistent<IDBKeyRange> idb_key_range_;
+  std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback_;
+};
+
+void InspectorIndexedDBAgent::deleteObjectStoreEntries(
+    const String& security_origin,
+    const String& database_name,
+    const String& object_store_name,
+    std::unique_ptr<protocol::IndexedDB::KeyRange> key_range,
+    std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback) {
+  IDBKeyRange* idb_key_range = IdbKeyRangeFromKeyRange(key_range.get());
+  if (!idb_key_range) {
+    request_callback->sendFailure(Response::Error("Can not parse key range"));
+    return;
+  }
+  scoped_refptr<DeleteObjectStoreEntries> delete_object_store_entries =
+      DeleteObjectStoreEntries::Create(object_store_name, idb_key_range,
+                                       std::move(request_callback));
+  delete_object_store_entries->Start(
+      inspected_frames_->FrameWithSecurityOrigin(security_origin),
+      database_name);
 }
 
 class ClearObjectStoreListener final : public EventListener {
@@ -913,24 +1001,21 @@
     : public ExecutableWithDatabase<ClearObjectStoreCallback> {
  public:
   static scoped_refptr<ClearObjectStore> Create(
-      ScriptState* script_state,
       const String& object_store_name,
       std::unique_ptr<ClearObjectStoreCallback> request_callback) {
-    return base::AdoptRef(new ClearObjectStore(script_state, object_store_name,
-                                               std::move(request_callback)));
+    return base::AdoptRef(
+        new ClearObjectStore(object_store_name, std::move(request_callback)));
   }
 
-  ClearObjectStore(ScriptState* script_state,
-                   const String& object_store_name,
+  ClearObjectStore(const String& object_store_name,
                    std::unique_ptr<ClearObjectStoreCallback> request_callback)
-      : ExecutableWithDatabase(script_state),
-        object_store_name_(object_store_name),
+      : object_store_name_(object_store_name),
         request_callback_(std::move(request_callback)) {}
 
-  void Execute(IDBDatabase* idb_database) override {
+  void Execute(IDBDatabase* idb_database, ScriptState* script_state) override {
     IDBTransaction* idb_transaction =
-        TransactionForDatabase(GetScriptState(), idb_database,
-                               object_store_name_, IndexedDBNames::readwrite);
+        TransactionForDatabase(script_state, idb_database, object_store_name_,
+                               IndexedDBNames::readwrite);
     if (!idb_transaction) {
       request_callback_->sendFailure(
           Response::Error("Could not get transaction"));
@@ -945,7 +1030,7 @@
     }
 
     DummyExceptionStateForTesting exception_state;
-    idb_object_store->clear(GetScriptState(), exception_state);
+    idb_object_store->clear(script_state, exception_state);
     DCHECK(!exception_state.HadException());
     if (exception_state.HadException()) {
       ExceptionCode ec = exception_state.Code();
@@ -973,31 +1058,11 @@
     const String& database_name,
     const String& object_store_name,
     std::unique_ptr<ClearObjectStoreCallback> request_callback) {
-  LocalFrame* frame =
-      inspected_frames_->FrameWithSecurityOrigin(security_origin);
-  Document* document = frame ? frame->GetDocument() : nullptr;
-  if (!document) {
-    request_callback->sendFailure(Response::Error(kNoDocumentError));
-    return;
-  }
-  IDBFactory* idb_factory = nullptr;
-  Response response = AssertIDBFactory(document, idb_factory);
-  if (!response.isSuccess()) {
-    request_callback->sendFailure(response);
-    return;
-  }
-
-  ScriptState* script_state = ToScriptStateForMainWorld(frame);
-  if (!script_state) {
-    request_callback->sendFailure(Response::InternalError());
-    return;
-  }
-
-  ScriptState::Scope scope(script_state);
-  scoped_refptr<ClearObjectStore> clear_object_store = ClearObjectStore::Create(
-      script_state, object_store_name, std::move(request_callback));
-  clear_object_store->Start(idb_factory, document->GetSecurityOrigin(),
-                            database_name);
+  scoped_refptr<ClearObjectStore> clear_object_store =
+      ClearObjectStore::Create(object_store_name, std::move(request_callback));
+  clear_object_store->Start(
+      inspected_frames_->FrameWithSecurityOrigin(security_origin),
+      database_name);
 }
 
 void InspectorIndexedDBAgent::deleteDatabase(
diff --git a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h
index 6890b3c..4d53253 100644
--- a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h
+++ b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.h
@@ -69,6 +69,12 @@
                    int page_size,
                    protocol::Maybe<protocol::IndexedDB::KeyRange>,
                    std::unique_ptr<RequestDataCallback>) override;
+  void deleteObjectStoreEntries(
+      const String& security_origin,
+      const String& database_name,
+      const String& object_store_name,
+      std::unique_ptr<protocol::IndexedDB::KeyRange>,
+      std::unique_ptr<DeleteObjectStoreEntriesCallback>) override;
   void clearObjectStore(const String& security_origin,
                         const String& database_name,
                         const String& object_store_name,
diff --git a/third_party/WebKit/Source/modules/installedapp/InstalledAppController.cpp b/third_party/WebKit/Source/modules/installedapp/InstalledAppController.cpp
index 1e3f7d5..cf188482 100644
--- a/third_party/WebKit/Source/modules/installedapp/InstalledAppController.cpp
+++ b/third_party/WebKit/Source/modules/installedapp/InstalledAppController.cpp
@@ -115,9 +115,8 @@
 
   provider_->FilterInstalledApps(
       std::move(mojo_related_apps),
-      ConvertToBaseCallback(
-          WTF::Bind(&InstalledAppController::OnFilterInstalledApps,
-                    WrapPersistent(this), WTF::Passed(std::move(callbacks)))));
+      WTF::Bind(&InstalledAppController::OnFilterInstalledApps,
+                WrapPersistent(this), WTF::Passed(std::move(callbacks))));
 }
 
 void InstalledAppController::OnFilterInstalledApps(
diff --git a/third_party/WebKit/Source/modules/keyboard_lock/NavigatorKeyboardLock.cpp b/third_party/WebKit/Source/modules/keyboard_lock/NavigatorKeyboardLock.cpp
index 3bfef1b..5aeb559d 100644
--- a/third_party/WebKit/Source/modules/keyboard_lock/NavigatorKeyboardLock.cpp
+++ b/third_party/WebKit/Source/modules/keyboard_lock/NavigatorKeyboardLock.cpp
@@ -56,9 +56,8 @@
 
   request_keylock_resolver_ = ScriptPromiseResolver::Create(state);
   service_->RequestKeyboardLock(
-      keycodes,
-      ConvertToBaseCallback(WTF::Bind(
-          &NavigatorKeyboardLock::LockRequestFinished, WrapPersistent(this))));
+      keycodes, WTF::Bind(&NavigatorKeyboardLock::LockRequestFinished,
+                          WrapPersistent(this)));
   return request_keylock_resolver_->Promise();
 }
 
diff --git a/third_party/WebKit/Source/modules/locks/BUILD.gn b/third_party/WebKit/Source/modules/locks/BUILD.gn
new file mode 100644
index 0000000..a6b8893
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/modules/modules.gni")
+
+blink_modules_sources("locks") {
+  sources = [
+    "Lock.cpp",
+    "Lock.h",
+    "LockManager.cpp",
+    "LockManager.h",
+    "NavigatorLocks.cpp",
+    "NavigatorLocks.h",
+  ]
+}
diff --git a/third_party/WebKit/Source/modules/locks/DEPS b/third_party/WebKit/Source/modules/locks/DEPS
new file mode 100644
index 0000000..e3ed309
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+    "-modules",
+    "+modules/ModulesExport.h",
+    "+modules/locks",
+    "+mojo/public/cpp/bindings/binding.h",
+]
diff --git a/third_party/WebKit/Source/modules/locks/Lock.cpp b/third_party/WebKit/Source/modules/locks/Lock.cpp
new file mode 100644
index 0000000..6cec6f5f
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/Lock.cpp
@@ -0,0 +1,130 @@
+// 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 "modules/locks/Lock.h"
+
+#include "bindings/core/v8/ScriptPromise.h"
+#include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "core/dom/ExecutionContext.h"
+#include "platform/bindings/ScriptState.h"
+
+namespace blink {
+
+namespace {
+const char* kLockModeNameExclusive = "exclusive";
+const char* kLockModeNameShared = "shared";
+}  // namespace
+
+class Lock::ThenFunction final : public ScriptFunction {
+ public:
+  enum ResolveType {
+    Fulfilled,
+    Rejected,
+  };
+
+  static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
+                                                Lock* lock,
+                                                ResolveType type) {
+    ThenFunction* self = new ThenFunction(script_state, lock, type);
+    return self->BindToV8Function();
+  }
+
+  virtual void Trace(blink::Visitor* visitor) {
+    visitor->Trace(lock_);
+    ScriptFunction::Trace(visitor);
+  }
+
+ private:
+  ThenFunction(ScriptState* script_state, Lock* lock, ResolveType type)
+      : ScriptFunction(script_state), lock_(lock), resolve_type_(type) {}
+
+  ScriptValue Call(ScriptValue value) override {
+    DCHECK(lock_);
+    DCHECK(resolve_type_ == Fulfilled || resolve_type_ == Rejected);
+    lock_->ReleaseIfHeld();
+    if (resolve_type_ == Fulfilled)
+      lock_->resolver_->Resolve(value);
+    else
+      lock_->resolver_->Reject(value);
+    lock_ = nullptr;
+    return value;
+  }
+
+  Member<Lock> lock_;
+  ResolveType resolve_type_;
+};
+
+// static
+Lock* Lock::Create(ScriptState* script_state,
+                   const Vector<String>& scope,
+                   mojom::blink::LockManager::LockMode mode,
+                   mojom::blink::LockHandlePtr handle) {
+  return new Lock(script_state, scope, mode, std::move(handle));
+}
+
+Lock::Lock(ScriptState* script_state,
+           const Vector<String>& scope,
+           mojom::blink::LockManager::LockMode mode,
+           mojom::blink::LockHandlePtr handle)
+    : PausableObject(ExecutionContext::From(script_state)),
+      scope_(scope),
+      mode_(mode),
+      handle_(std::move(handle)) {
+  PauseIfNeeded();
+}
+
+Lock::~Lock() = default;
+
+String Lock::mode() const {
+  return ModeToString(mode_);
+}
+
+void Lock::HoldUntil(ScriptPromise promise, ScriptPromiseResolver* resolver) {
+  DCHECK(handle_.is_bound());
+  DCHECK(!resolver_);
+
+  ScriptState* script_state = resolver->GetScriptState();
+  resolver_ = resolver;
+  promise.Then(
+      ThenFunction::CreateFunction(script_state, this, ThenFunction::Fulfilled),
+      ThenFunction::CreateFunction(script_state, this, ThenFunction::Rejected));
+}
+
+// static
+mojom::blink::LockManager::LockMode Lock::StringToMode(const String& string) {
+  if (string == kLockModeNameShared)
+    return mojom::blink::LockManager::LockMode::SHARED;
+  if (string == kLockModeNameExclusive)
+    return mojom::blink::LockManager::LockMode::EXCLUSIVE;
+  NOTREACHED();
+  return mojom::blink::LockManager::LockMode::SHARED;
+}
+
+// static
+String Lock::ModeToString(mojom::blink::LockManager::LockMode mode) {
+  switch (mode) {
+    case mojom::blink::LockManager::LockMode::SHARED:
+      return kLockModeNameShared;
+    case mojom::blink::LockManager::LockMode::EXCLUSIVE:
+      return kLockModeNameExclusive;
+  }
+  NOTREACHED();
+  return g_empty_string;
+}
+
+void Lock::ContextDestroyed(ExecutionContext* context) {
+  ReleaseIfHeld();
+}
+
+void Lock::Trace(blink::Visitor* visitor) {
+  PausableObject::Trace(visitor);
+  ScriptWrappable::Trace(visitor);
+  visitor->Trace(resolver_);
+}
+
+void Lock::ReleaseIfHeld() {
+  handle_.reset();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/locks/Lock.h b/third_party/WebKit/Source/modules/locks/Lock.h
new file mode 100644
index 0000000..4993442
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/Lock.h
@@ -0,0 +1,69 @@
+// 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 Lock_h
+#define Lock_h
+
+#include "core/dom/PausableObject.h"
+#include "platform/bindings/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
+#include "platform/wtf/Vector.h"
+#include "platform/wtf/text/WTFString.h"
+#include "public/platform/modules/locks/lock_manager.mojom-blink.h"
+
+namespace blink {
+
+class ScriptPromise;
+class ScriptPromiseResolver;
+class ScriptState;
+
+class Lock final : public ScriptWrappable, public PausableObject {
+  DEFINE_WRAPPERTYPEINFO();
+  USING_GARBAGE_COLLECTED_MIXIN(Lock);
+
+ public:
+  static Lock* Create(ScriptState*,
+                      const Vector<String>& scope,
+                      mojom::blink::LockManager::LockMode,
+                      mojom::blink::LockHandlePtr);
+
+  ~Lock() override;
+
+  virtual void Trace(blink::Visitor*);
+  EAGERLY_FINALIZE();
+
+  // Lock.idl
+  Vector<String> scope() const { return scope_; }
+  String mode() const;
+
+  // PausableObject
+  void ContextDestroyed(ExecutionContext*) override;
+
+  // The lock is held until the passed promise resolves. When it is released,
+  // the passed resolver is invoked with the promise's result.
+  void HoldUntil(ScriptPromise, ScriptPromiseResolver*);
+
+  static mojom::blink::LockManager::LockMode StringToMode(const String&);
+  static String ModeToString(mojom::blink::LockManager::LockMode);
+
+ private:
+  class ThenFunction;
+
+  Lock(ScriptState*,
+       const Vector<String>& scope,
+       mojom::blink::LockManager::LockMode,
+       mojom::blink::LockHandlePtr);
+
+  void ReleaseIfHeld();
+
+  Member<ScriptPromiseResolver> resolver_;
+
+  const Vector<String> scope_;
+  const mojom::blink::LockManager::LockMode mode_;
+  mojom::blink::LockHandlePtr handle_;
+};
+
+}  // namespace blink
+
+#endif  // Lock_h
diff --git a/third_party/WebKit/Source/modules/locks/Lock.idl b/third_party/WebKit/Source/modules/locks/Lock.idl
new file mode 100644
index 0000000..6919f60e
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/Lock.idl
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/inexorabletash/web-locks
+[
+    SecureContext,
+    Exposed=(Window,Worker),
+    RuntimeEnabled=LocksAPI
+] interface Lock {
+    readonly attribute FrozenArray<DOMString> scope;
+    readonly attribute LockMode mode;
+};
diff --git a/third_party/WebKit/Source/modules/locks/LockManager.cpp b/third_party/WebKit/Source/modules/locks/LockManager.cpp
new file mode 100644
index 0000000..d5b38f91
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/LockManager.cpp
@@ -0,0 +1,242 @@
+// 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 "modules/locks/LockManager.h"
+
+#include <algorithm>
+#include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "bindings/modules/v8/v8_lock_granted_callback.h"
+#include "core/dom/DOMException.h"
+#include "core/dom/ExceptionCode.h"
+#include "modules/locks/Lock.h"
+#include "modules/locks/LockOptions.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "platform/bindings/Microtask.h"
+#include "platform/bindings/ScriptState.h"
+#include "platform/bindings/TraceWrapperMember.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
+
+namespace blink {
+
+class LockManager::LockRequestImpl final
+    : public GarbageCollectedFinalized<LockRequestImpl>,
+      public TraceWrapperBase,
+      public mojom::blink::LockRequest {
+  WTF_MAKE_NONCOPYABLE(LockRequestImpl);
+  EAGERLY_FINALIZE();
+
+ public:
+  LockRequestImpl(V8LockGrantedCallback* callback,
+                  ScriptPromiseResolver* resolver,
+                  const Vector<String>& scope,
+                  mojom::blink::LockManager::LockMode mode,
+                  mojom::blink::LockRequestRequest request,
+                  LockManager* manager)
+      : callback_(callback),
+        resolver_(resolver),
+        scope_(scope),
+        mode_(mode),
+        binding_(this, std::move(request)),
+        manager_(manager) {}
+
+  ~LockRequestImpl() = default;
+
+  void Trace(blink::Visitor* visitor) {
+    visitor->Trace(resolver_);
+    visitor->Trace(manager_);
+    visitor->Trace(callback_);
+  }
+
+  // Wrapper tracing is needed for callbacks. The reference chain is
+  // NavigatorLocksImpl -> LockManager -> LockRequestImpl ->
+  // V8LockGrantedCallback.
+  void TraceWrappers(const ScriptWrappableVisitor* visitor) const override {
+    visitor->TraceWrappers(callback_);
+  }
+
+  // Called to immediately close the pipe which signals the back-end,
+  // unblocking further requests, without waiting for GC finalize the object.
+  void Cancel() { binding_.Close(); }
+
+  void Abort(const String& reason) override {
+    manager_->RemovePendingRequest(this);
+    binding_.Close();
+
+    if (!resolver_->GetScriptState()->ContextIsValid())
+      return;
+
+    resolver_->Reject(DOMException::Create(kAbortError, reason));
+  }
+
+  void Failed() override {
+    manager_->RemovePendingRequest(this);
+    binding_.Close();
+
+    ScriptState* script_state = resolver_->GetScriptState();
+    if (!script_state->ContextIsValid())
+      return;
+
+    // Lock was not granted e.g. because ifAvailable was specified but
+    // the lock was not available.
+    ScriptState::Scope scope(script_state);
+    v8::TryCatch try_catch(script_state->GetIsolate());
+    v8::Maybe<ScriptValue> result = callback_->Invoke(nullptr, nullptr);
+    if (try_catch.HasCaught()) {
+      resolver_->Reject(try_catch.Exception());
+    } else if (!result.IsNothing()) {
+      resolver_->Resolve(result.FromJust());
+    }
+  }
+
+  void Granted(mojom::blink::LockHandlePtr handle) override {
+    DCHECK(binding_.is_bound());
+    DCHECK(handle.is_bound());
+
+    manager_->RemovePendingRequest(this);
+    binding_.Close();
+
+    ScriptState* script_state = resolver_->GetScriptState();
+    if (!script_state->ContextIsValid()) {
+      // If a handle was returned, it will be automatically be released.
+      return;
+    }
+
+    Lock* lock = Lock::Create(script_state, scope_, mode_, std::move(handle));
+
+    ScriptState::Scope scope(script_state);
+    v8::TryCatch try_catch(script_state->GetIsolate());
+    v8::Maybe<ScriptValue> result = callback_->Invoke(nullptr, lock);
+    if (try_catch.HasCaught()) {
+      lock->HoldUntil(
+          ScriptPromise::Reject(script_state, try_catch.Exception()),
+          resolver_);
+    } else if (!result.IsNothing()) {
+      lock->HoldUntil(ScriptPromise::Cast(script_state, result.FromJust()),
+                      resolver_);
+    }
+  }
+
+ private:
+  // Callback passed by script; invoked when the lock is granted.
+  TraceWrapperMember<V8LockGrantedCallback> callback_;
+
+  // Rejects if the request was aborted, otherwise resolves/rejects with
+  // |callback_|'s result.
+  Member<ScriptPromiseResolver> resolver_;
+
+  // Held to stamp the Lock object's |scope| property.
+  Vector<String> scope_;
+
+  // Held to stamp the Lock object's |mode| property.
+  mojom::blink::LockManager::LockMode mode_;
+
+  mojo::Binding<mojom::blink::LockRequest> binding_;
+
+  // The |manager_| keeps |this| alive until a response comes in and this is
+  // registered. If the context is destroyed then |manager_| will dispose of
+  // |this| which terminates the request on the service side.
+  Member<LockManager> manager_;
+};
+
+LockManager::LockManager(ExecutionContext* context)
+    : ContextLifecycleObserver(context) {}
+
+ScriptPromise LockManager::acquire(ScriptState* script_state,
+                                   const StringOrStringSequence& scope_union,
+                                   V8LockGrantedCallback* callback,
+                                   ExceptionState& exception_state) {
+  return acquire(script_state, scope_union, LockOptions(), callback,
+                 exception_state);
+}
+ScriptPromise LockManager::acquire(ScriptState* script_state,
+                                   const StringOrStringSequence& scope_union,
+                                   const LockOptions& options,
+                                   V8LockGrantedCallback* callback,
+                                   ExceptionState& exception_state) {
+  ExecutionContext* context = ExecutionContext::From(script_state);
+  DCHECK(context->IsContextThread());
+
+  if (!context->GetSecurityOrigin()->CanAccessLocks()) {
+    exception_state.ThrowSecurityError(
+        "Access to the Locks API is denied in this context.");
+    return ScriptPromise();
+  }
+
+  if (!service_.get()) {
+    if (auto* provider = context->GetInterfaceProvider())
+      provider->GetInterface(mojo::MakeRequest(&service_));
+    if (!service_.get()) {
+      exception_state.ThrowTypeError("Service not available.");
+      return ScriptPromise();
+    }
+  }
+
+  // Compute the scope (set of named resources); remove duplicates.
+  HashSet<String> set;
+  if (scope_union.IsString()) {
+    set.insert(scope_union.GetAsString());
+  } else if (scope_union.IsStringSequence()) {
+    for (const auto& name : scope_union.GetAsStringSequence())
+      set.insert(name);
+  } else {
+    NOTREACHED();
+    return ScriptPromise();
+  }
+
+  if (set.IsEmpty()) {
+    exception_state.ThrowTypeError("Scope must not be empty.");
+    return ScriptPromise();
+  }
+
+  Vector<String> scope;
+  for (const auto& name : set)
+    scope.push_back(name);
+  std::sort(scope.begin(), scope.end(), WTF::CodePointCompareLessThan);
+
+  mojom::blink::LockManager::LockMode mode = Lock::StringToMode(options.mode());
+
+  mojom::blink::LockManager::WaitMode wait =
+      options.ifAvailable() ? mojom::blink::LockManager::WaitMode::NO_WAIT
+                            : mojom::blink::LockManager::WaitMode::WAIT;
+
+  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  ScriptPromise promise = resolver->Promise();
+
+  mojom::blink::LockRequestPtr request_ptr;
+  AddPendingRequest(new LockRequestImpl(callback, resolver, scope, mode,
+                                        mojo::MakeRequest(&request_ptr), this));
+
+  service_->RequestLock(
+      ExecutionContext::From(script_state)->GetSecurityOrigin(), scope, mode,
+      wait, std::move(request_ptr));
+
+  return promise;
+}
+
+void LockManager::AddPendingRequest(LockRequestImpl* request) {
+  pending_requests_.insert(request);
+}
+
+void LockManager::RemovePendingRequest(LockRequestImpl* request) {
+  pending_requests_.erase(request);
+}
+
+void LockManager::Trace(blink::Visitor* visitor) {
+  ScriptWrappable::Trace(visitor);
+  ContextLifecycleObserver::Trace(visitor);
+  visitor->Trace(pending_requests_);
+}
+
+void LockManager::TraceWrappers(const ScriptWrappableVisitor* visitor) const {
+  for (auto request : pending_requests_)
+    visitor->TraceWrappers(request);
+}
+
+void LockManager::ContextDestroyed(ExecutionContext*) {
+  for (auto request : pending_requests_)
+    request->Cancel();
+  pending_requests_.clear();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/locks/LockManager.h b/third_party/WebKit/Source/modules/locks/LockManager.h
new file mode 100644
index 0000000..5593937
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/LockManager.h
@@ -0,0 +1,66 @@
+// 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 LockManager_h
+#define LockManager_h
+
+#include "bindings/modules/v8/string_or_string_sequence.h"
+#include "modules/ModulesExport.h"
+#include "modules/locks/LockOptions.h"
+#include "platform/bindings/ScriptWrappable.h"
+#include "platform/heap/HeapAllocator.h"
+#include "public/platform/modules/locks/lock_manager.mojom-blink.h"
+
+namespace blink {
+
+class ScriptPromise;
+class ScriptState;
+class V8LockGrantedCallback;
+
+class LockManager final : public ScriptWrappable,
+                          public ContextLifecycleObserver {
+  WTF_MAKE_NONCOPYABLE(LockManager);
+  DEFINE_WRAPPERTYPEINFO();
+  USING_GARBAGE_COLLECTED_MIXIN(LockManager);
+
+ public:
+  explicit LockManager(ExecutionContext*);
+
+  ScriptPromise acquire(ScriptState*,
+                        const StringOrStringSequence& scope,
+                        V8LockGrantedCallback*,
+                        ExceptionState&);
+  ScriptPromise acquire(ScriptState*,
+                        const StringOrStringSequence& scope,
+                        const LockOptions&,
+                        V8LockGrantedCallback*,
+                        ExceptionState&);
+
+  void Trace(blink::Visitor*);
+
+  // Wrapper tracing is needed for callbacks. The reference chain is
+  // NavigatorLocksImpl -> LockManager -> LockRequestImpl ->
+  // V8LockGrantedCallback.
+  void TraceWrappers(const ScriptWrappableVisitor*) const override;
+
+  // Terminate all outstanding requests when the context is destroyed, since
+  // this can unblock requests by other contexts.
+  void ContextDestroyed(ExecutionContext*) override;
+
+ private:
+  class LockRequestImpl;
+
+  // Track pending requests so that they can be cancelled if the context is
+  // terminated.
+  void AddPendingRequest(LockRequestImpl*);
+  void RemovePendingRequest(LockRequestImpl*);
+
+  HeapHashSet<TraceWrapperMember<LockRequestImpl>> pending_requests_;
+
+  mojom::blink::LockManagerPtr service_;
+};
+
+}  // namespace blink
+
+#endif  // LockManager_h
diff --git a/third_party/WebKit/Source/modules/locks/LockManager.idl b/third_party/WebKit/Source/modules/locks/LockManager.idl
new file mode 100644
index 0000000..eaedad9e
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/LockManager.idl
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/inexorabletash/web-locks
+typedef (DOMString or sequence<DOMString>) LockScope;
+callback LockGrantedCallback = any (Lock lock);
+[
+    SecureContext,
+    Exposed=(Window,Worker),
+    RuntimeEnabled=LocksAPI
+] interface LockManager {
+    [CallWith=ScriptState, RaisesException] Promise<Lock> acquire(
+        LockScope scope,
+        LockGrantedCallback callback);
+    [CallWith=ScriptState, RaisesException] Promise<Lock> acquire(
+        LockScope scope,
+        LockOptions options,
+        LockGrantedCallback callback);
+};
diff --git a/third_party/WebKit/Source/modules/locks/LockOptions.idl b/third_party/WebKit/Source/modules/locks/LockOptions.idl
new file mode 100644
index 0000000..18d4ed2
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/LockOptions.idl
@@ -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.
+
+// https://github.com/inexorabletash/web-locks
+enum LockMode { "shared", "exclusive" };
+
+dictionary LockOptions {
+    LockMode mode = "exclusive";
+    boolean ifAvailable = false;
+    // TODO(jsbell): AbortSignal signal;
+};
diff --git a/third_party/WebKit/Source/modules/locks/NavigatorLocks.cpp b/third_party/WebKit/Source/modules/locks/NavigatorLocks.cpp
new file mode 100644
index 0000000..274046f
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/NavigatorLocks.cpp
@@ -0,0 +1,76 @@
+// 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 "modules/locks/NavigatorLocks.h"
+
+#include "core/frame/Navigator.h"
+#include "core/workers/WorkerNavigator.h"
+#include "modules/locks/LockManager.h"
+#include "platform/Supplementable.h"
+#include "platform/bindings/ScriptState.h"
+#include "platform/bindings/TraceWrapperMember.h"
+
+namespace blink {
+
+namespace {
+
+template <typename T>
+class NavigatorLocksImpl final : public GarbageCollected<NavigatorLocksImpl<T>>,
+                                 public Supplement<T>,
+                                 public TraceWrapperBase {
+  USING_GARBAGE_COLLECTED_MIXIN(NavigatorLocksImpl);
+
+ public:
+  static NavigatorLocksImpl& From(T& navigator) {
+    NavigatorLocksImpl* supplement = static_cast<NavigatorLocksImpl*>(
+        Supplement<T>::From(navigator, SupplementName()));
+    if (!supplement) {
+      supplement = new NavigatorLocksImpl(navigator);
+      Supplement<T>::ProvideTo(navigator, SupplementName(), supplement);
+    }
+    return *supplement;
+  }
+
+  LockManager* GetLockManager(ExecutionContext* context) const {
+    if (!lock_manager_ && context) {
+      lock_manager_ = new LockManager(context);
+    }
+    return lock_manager_.Get();
+  }
+
+  virtual void Trace(blink::Visitor* visitor) {
+    visitor->Trace(lock_manager_);
+    Supplement<T>::Trace(visitor);
+  }
+
+  // Wrapper tracing is needed for callbacks. The reference chain is
+  // NavigatorLocksImpl -> LockManager -> LockRequestImpl ->
+  // V8LockGrantedCallback.
+  void TraceWrappers(const ScriptWrappableVisitor* visitor) const {
+    visitor->TraceWrappers(lock_manager_);
+  }
+
+ private:
+  explicit NavigatorLocksImpl(T& navigator) : Supplement<T>(navigator) {}
+
+  static const char* SupplementName() { return "NavigatorLocksImpl"; }
+
+  mutable TraceWrapperMember<LockManager> lock_manager_;
+};
+
+}  // namespace
+
+LockManager* NavigatorLocks::locks(ScriptState* script_state,
+                                   Navigator& navigator) {
+  return NavigatorLocksImpl<Navigator>::From(navigator).GetLockManager(
+      ExecutionContext::From(script_state));
+}
+
+LockManager* NavigatorLocks::locks(ScriptState* script_state,
+                                   WorkerNavigator& navigator) {
+  return NavigatorLocksImpl<WorkerNavigator>::From(navigator).GetLockManager(
+      ExecutionContext::From(script_state));
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/locks/NavigatorLocks.h b/third_party/WebKit/Source/modules/locks/NavigatorLocks.h
new file mode 100644
index 0000000..cf5744a
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/NavigatorLocks.h
@@ -0,0 +1,27 @@
+// 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 NavigatorLocks_h
+#define NavigatorLocks_h
+
+#include "platform/wtf/Allocator.h"
+
+namespace blink {
+
+class LockManager;
+class Navigator;
+class ScriptState;
+class WorkerNavigator;
+
+class NavigatorLocks final {
+  STATIC_ONLY(NavigatorLocks);
+
+ public:
+  static LockManager* locks(ScriptState*, Navigator&);
+  static LockManager* locks(ScriptState*, WorkerNavigator&);
+};
+
+}  // namespace blink
+
+#endif  // NavigatorLocks_h
diff --git a/third_party/WebKit/Source/modules/locks/NavigatorLocks.idl b/third_party/WebKit/Source/modules/locks/NavigatorLocks.idl
new file mode 100644
index 0000000..443d9d313
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/NavigatorLocks.idl
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/inexorabletash/web-locks
+[
+    SecureContext,
+    Exposed=Window,
+    ImplementedAs=NavigatorLocks,
+    RuntimeEnabled=LocksAPI
+] partial interface Navigator {
+    [CallWith=ScriptState] readonly attribute LockManager locks;
+};
diff --git a/third_party/WebKit/Source/modules/locks/OWNERS b/third_party/WebKit/Source/modules/locks/OWNERS
new file mode 100644
index 0000000..c60c1f5
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/OWNERS
@@ -0,0 +1 @@
+file://content/browser/locks/OWNERS
diff --git a/third_party/WebKit/Source/modules/locks/WorkerNavigatorLocks.idl b/third_party/WebKit/Source/modules/locks/WorkerNavigatorLocks.idl
new file mode 100644
index 0000000..788db43
--- /dev/null
+++ b/third_party/WebKit/Source/modules/locks/WorkerNavigatorLocks.idl
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/inexorabletash/web-locks
+[
+    SecureContext,
+    Exposed=Worker,
+    ImplementedAs=NavigatorLocks,
+    RuntimeEnabled=LocksAPI
+] partial interface WorkerNavigator {
+    [CallWith=ScriptState] readonly attribute LockManager locks;
+};
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp
index c9b9af7..9aa6284 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegate.cpp
@@ -219,9 +219,9 @@
   DCHECK(!monitor_.is_bound());
   Platform::Current()->GetConnector()->BindInterface(
       device::mojom::blink::kServiceName, mojo::MakeRequest(&monitor_));
-  monitor_->IsAutoRotateEnabledByUser(ConvertToBaseCallback(WTF::Bind(
+  monitor_->IsAutoRotateEnabledByUser(WTF::Bind(
       &MediaControlsOrientationLockDelegate::GotIsAutoRotateEnabledByUser,
-      WrapPersistent(this))));
+      WrapPersistent(this)));
 #else
   GotIsAutoRotateEnabledByUser(true);  // Assume always enabled on other OSes.
 #endif  // defined(OS_ANDROID)
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsWindowEventListener.h b/third_party/WebKit/Source/modules/media_controls/MediaControlsWindowEventListener.h
index 963ed98..d69cdbe 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsWindowEventListener.h
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsWindowEventListener.h
@@ -5,8 +5,8 @@
 #ifndef MediaControlsWindowEventListener_h
 #define MediaControlsWindowEventListener_h
 
+#include "base/callback.h"
 #include "core/dom/events/EventListener.h"
-#include "platform/wtf/Functional.h"
 
 namespace blink {
 
@@ -14,7 +14,7 @@
 
 class MediaControlsWindowEventListener final : public EventListener {
  public:
-  using Callback = WTF::RepeatingFunction<void()>;
+  using Callback = base::RepeatingCallback<void()>;
 
   static MediaControlsWindowEventListener* Create(MediaControlsImpl*, Callback);
 
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaDownloadInProductHelpManager.cpp b/third_party/WebKit/Source/modules/media_controls/MediaDownloadInProductHelpManager.cpp
index 21c40166..43fd8db 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaDownloadInProductHelpManager.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaDownloadInProductHelpManager.cpp
@@ -78,9 +78,9 @@
   if (!media_in_product_help_.is_bound()) {
     frame->Client()->GetInterfaceProvider()->GetInterface(
         mojo::MakeRequest(&media_in_product_help_));
-    media_in_product_help_.set_connection_error_handler(ConvertToBaseCallback(
+    media_in_product_help_.set_connection_error_handler(
         WTF::Bind(&MediaDownloadInProductHelpManager::DismissInProductHelp,
-                  WrapWeakPersistent(this))));
+                  WrapWeakPersistent(this)));
     DCHECK(media_in_product_help_.is_bound());
   }
 
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css
index cb70c0b..1534bd7b 100644
--- a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css
+++ b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css
@@ -394,8 +394,8 @@
 }
 
 label[pseudo="-internal-media-controls-overflow-menu-list-item"] input {
-  margin-left: -22px;
-  margin-right: 2px;
+  margin-left: -9px;
+  margin-right: 6px;
 }
 
 audio::-internal-media-controls-text-track-list-header:hover,
diff --git a/third_party/WebKit/Source/modules/mediastream/BUILD.gn b/third_party/WebKit/Source/modules/mediastream/BUILD.gn
index 43027c0..94890c6 100644
--- a/third_party/WebKit/Source/modules/mediastream/BUILD.gn
+++ b/third_party/WebKit/Source/modules/mediastream/BUILD.gn
@@ -15,8 +15,6 @@
     "MediaDeviceInfo.h",
     "MediaDevices.cpp",
     "MediaDevices.h",
-    "MediaDevicesRequest.cpp",
-    "MediaDevicesRequest.h",
     "MediaErrorState.cpp",
     "MediaErrorState.h",
     "MediaStream.cpp",
diff --git a/third_party/WebKit/Source/modules/mediastream/DEPS b/third_party/WebKit/Source/modules/mediastream/DEPS
index 151648c68..6d93e62 100644
--- a/third_party/WebKit/Source/modules/mediastream/DEPS
+++ b/third_party/WebKit/Source/modules/mediastream/DEPS
@@ -5,4 +5,5 @@
     "+modules/ModulesExport.h",
     "+modules/imagecapture",
     "+modules/mediastream",
+    "+mojo/public/cpp/bindings/binding.h",
 ]
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp
index 607c06b..09fa401 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp
@@ -28,44 +28,53 @@
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/V8ObjectBuilder.h"
 #include "platform/bindings/ScriptState.h"
-#include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
-MediaDeviceInfo* MediaDeviceInfo::Create(
-    const WebMediaDeviceInfo& web_media_device_info) {
-  DCHECK(!web_media_device_info.IsNull());
-  return new MediaDeviceInfo(web_media_device_info);
+MediaDeviceInfo* MediaDeviceInfo::Create(const String& device_id,
+                                         const String& label,
+                                         const String& group_id,
+                                         MediaDeviceType device_type) {
+  return new MediaDeviceInfo(device_id, label, group_id, device_type);
 }
 
-MediaDeviceInfo::MediaDeviceInfo(
-    const WebMediaDeviceInfo& web_media_device_info)
-    : web_media_device_info_(web_media_device_info) {}
+MediaDeviceInfo::MediaDeviceInfo(const String& device_id,
+                                 const String& label,
+                                 const String& group_id,
+                                 MediaDeviceType device_type)
+    : device_id_(device_id),
+      label_(label),
+      group_id_(group_id),
+      device_type_(device_type) {}
 
 String MediaDeviceInfo::deviceId() const {
-  return web_media_device_info_.DeviceId();
+  return device_id_;
 }
 
 String MediaDeviceInfo::kind() const {
-  switch (web_media_device_info_.Kind()) {
-    case WebMediaDeviceInfo::kMediaDeviceKindAudioInput:
+  switch (device_type_) {
+    case MediaDeviceType::MEDIA_AUDIO_INPUT:
       return "audioinput";
-    case WebMediaDeviceInfo::kMediaDeviceKindAudioOutput:
+    case MediaDeviceType::MEDIA_AUDIO_OUTPUT:
       return "audiooutput";
-    case WebMediaDeviceInfo::kMediaDeviceKindVideoInput:
+    case MediaDeviceType::MEDIA_VIDEO_INPUT:
       return "videoinput";
+    default:
+      NOTREACHED();
+      return String();
   }
-
-  NOTREACHED();
-  return String();
 }
 
 String MediaDeviceInfo::label() const {
-  return web_media_device_info_.Label();
+  return label_;
 }
 
 String MediaDeviceInfo::groupId() const {
-  return web_media_device_info_.GroupId();
+  return group_id_;
+}
+
+MediaDeviceType MediaDeviceInfo::DeviceType() const {
+  return device_type_;
 }
 
 ScriptValue MediaDeviceInfo::toJSONForBinding(ScriptState* script_state) {
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h
index b20009b..0e87479a 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h
+++ b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h
@@ -28,8 +28,11 @@
 
 #include "modules/ModulesExport.h"
 #include "platform/bindings/ScriptWrappable.h"
-#include "platform/heap/Handle.h"
-#include "public/platform/WebMediaDeviceInfo.h"
+#include "platform/heap/HeapAllocator.h"
+#include "platform/wtf/text/WTFString.h"
+#include "public/platform/modules/mediastream/media_devices.mojom-blink.h"
+
+using blink::mojom::blink::MediaDeviceType;
 
 namespace blink {
 
@@ -40,22 +43,34 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static MediaDeviceInfo* Create(const WebMediaDeviceInfo&);
+  static MediaDeviceInfo* Create(const String& device_id,
+                                 const String& label,
+                                 const String& group_id,
+                                 MediaDeviceType);
 
   String deviceId() const;
   String kind() const;
   String label() const;
   String groupId() const;
 
+  // Used for testing only.
+  MediaDeviceType DeviceType() const;
+
   ScriptValue toJSONForBinding(ScriptState*);
 
  private:
-  explicit MediaDeviceInfo(const WebMediaDeviceInfo&);
+  MediaDeviceInfo(const String& device_id,
+                  const String& label,
+                  const String& group_id,
+                  MediaDeviceType);
 
-  WebMediaDeviceInfo web_media_device_info_;
+  String device_id_;
+  String label_;
+  String group_id_;
+  MediaDeviceType device_type_;
 };
 
-typedef HeapVector<Member<MediaDeviceInfo>> MediaDeviceInfoVector;
+using MediaDeviceInfoVector = HeapVector<Member<MediaDeviceInfo>>;
 
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDevices.cpp b/third_party/WebKit/Source/modules/mediastream/MediaDevices.cpp
index fe3f93db..e504f2a1 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaDevices.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/MediaDevices.cpp
@@ -11,7 +11,7 @@
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/events/Event.h"
-#include "modules/mediastream/MediaDevicesRequest.h"
+#include "core/frame/LocalFrame.h"
 #include "modules/mediastream/MediaErrorState.h"
 #include "modules/mediastream/MediaStream.h"
 #include "modules/mediastream/MediaStreamConstraints.h"
@@ -21,6 +21,10 @@
 #include "modules/mediastream/UserMediaController.h"
 #include "modules/mediastream/UserMediaRequest.h"
 #include "platform/bindings/ScriptState.h"
+#include "platform/wtf/Functional.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
+
+using blink::mojom::blink::MediaDeviceType;
 
 namespace blink {
 
@@ -83,19 +87,23 @@
 MediaDevices::~MediaDevices() {}
 
 ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state) {
-  Document* document = ToDocument(ExecutionContext::From(script_state));
-  UserMediaController* user_media =
-      UserMediaController::From(document->GetFrame());
-  if (!user_media)
+  LocalFrame* frame =
+      ToDocument(ExecutionContext::From(script_state))->GetFrame();
+  if (!frame) {
     return ScriptPromise::RejectWithDOMException(
         script_state,
-        DOMException::Create(kNotSupportedError,
-                             "No media device controller available; is this a "
-                             "detached window?"));
+        DOMException::Create(kNotSupportedError, "Current frame is detached."));
+  }
 
-  MediaDevicesRequest* request =
-      MediaDevicesRequest::Create(script_state, user_media);
-  return request->Start();
+  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  ScriptPromise promise = resolver->Promise();
+  requests_.insert(resolver);
+
+  GetDispatcherHost(frame)->EnumerateDevices(
+      true /* audio input */, true /* video input */, true /* audio output */,
+      WTF::Bind(&MediaDevices::DevicesEnumerated, WrapPersistent(this),
+                WrapPersistent(resolver)));
+  return promise;
 }
 
 ScriptPromise MediaDevices::getUserMedia(ScriptState* script_state,
@@ -193,6 +201,8 @@
 
   stopped_ = true;
   StopObserving();
+  requests_.clear();
+  dispatcher_host_.reset();
 }
 
 void MediaDevices::Pause() {
@@ -252,9 +262,75 @@
   StopObserving();
 }
 
+void MediaDevices::DevicesEnumerated(
+    ScriptPromiseResolver* resolver,
+    Vector<Vector<mojom::blink::MediaDeviceInfoPtr>> enumeration) {
+  if (!requests_.Contains(resolver))
+    return;
+
+  requests_.erase(resolver);
+
+  if (!resolver->GetExecutionContext() ||
+      resolver->GetExecutionContext()->IsContextDestroyed()) {
+    return;
+  }
+
+  DCHECK_EQ(static_cast<size_t>(MediaDeviceType::NUM_MEDIA_DEVICE_TYPES),
+            enumeration.size());
+
+  MediaDeviceInfoVector media_devices;
+  for (size_t i = 0;
+       i < static_cast<size_t>(MediaDeviceType::NUM_MEDIA_DEVICE_TYPES); ++i) {
+    for (const auto& device_info : enumeration[i]) {
+      media_devices.push_back(MediaDeviceInfo::Create(
+          device_info->device_id, device_info->label, device_info->group_id,
+          static_cast<MediaDeviceType>(i)));
+    }
+  }
+
+  if (enumerate_devices_test_callback_)
+    std::move(enumerate_devices_test_callback_).Run(media_devices);
+
+  resolver->Resolve(media_devices);
+}
+
+void MediaDevices::OnDispatcherHostConnectionError() {
+  for (ScriptPromiseResolver* resolver : requests_) {
+    resolver->Reject(
+        DOMException::Create(kAbortError, "enumerateDevices() failed."));
+  }
+  requests_.clear();
+  dispatcher_host_.reset();
+
+  if (connection_error_test_callback_)
+    std::move(connection_error_test_callback_).Run();
+}
+
+const mojom::blink::MediaDevicesDispatcherHostPtr&
+MediaDevices::GetDispatcherHost(LocalFrame* frame) {
+  if (!dispatcher_host_) {
+    frame->GetInterfaceProvider().GetInterface(
+        mojo::MakeRequest(&dispatcher_host_));
+    dispatcher_host_.set_connection_error_handler(
+        WTF::Bind(&MediaDevices::OnDispatcherHostConnectionError,
+                  WrapWeakPersistent(this)));
+  }
+
+  return dispatcher_host_;
+}
+
+void MediaDevices::SetDispatcherHostForTesting(
+    mojom::blink::MediaDevicesDispatcherHostPtr dispatcher_host) {
+  dispatcher_host_ = std::move(dispatcher_host);
+  dispatcher_host_.set_connection_error_handler(
+      WTF::Bind(&MediaDevices::OnDispatcherHostConnectionError,
+                WrapWeakPersistent(this)));
+}
+
 void MediaDevices::Trace(blink::Visitor* visitor) {
   visitor->Trace(dispatch_scheduled_event_runner_);
   visitor->Trace(scheduled_events_);
+  visitor->Trace(requests_);
   EventTargetWithInlineData::Trace(visitor);
   PausableObject::Trace(visitor);
 }
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDevices.h b/third_party/WebKit/Source/modules/mediastream/MediaDevices.h
index cd1af75..ae6a06bd 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaDevices.h
+++ b/third_party/WebKit/Source/modules/mediastream/MediaDevices.h
@@ -5,18 +5,24 @@
 #ifndef MediaDevices_h
 #define MediaDevices_h
 
+#include "base/callback.h"
 #include "bindings/core/v8/ActiveScriptWrappable.h"
-#include "bindings/core/v8/ScriptPromise.h"
 #include "core/dom/PausableObject.h"
 #include "core/dom/events/EventTarget.h"
 #include "modules/EventTargetModules.h"
 #include "modules/ModulesExport.h"
+#include "modules/mediastream/MediaDeviceInfo.h"
 #include "platform/AsyncMethodRunner.h"
+#include "platform/heap/HeapAllocator.h"
+#include "public/platform/modules/mediastream/media_devices.mojom-blink.h"
 
 namespace blink {
 
+class LocalFrame;
 class MediaStreamConstraints;
 class MediaTrackSupportedConstraints;
+class ScriptPromise;
+class ScriptPromiseResolver;
 class ScriptState;
 class UserMediaController;
 
@@ -52,6 +58,21 @@
   void Pause() override;
   void Unpause() override;
 
+  // Callback for testing only.
+  using EnumerateDevicesTestCallback =
+      base::OnceCallback<void(const MediaDeviceInfoVector&)>;
+
+  void SetDispatcherHostForTesting(mojom::blink::MediaDevicesDispatcherHostPtr);
+
+  void SetEnumerateDevicesCallbackForTesting(
+      EnumerateDevicesTestCallback test_callback) {
+    enumerate_devices_test_callback_ = std::move(test_callback);
+  }
+
+  void SetConnectionErrorCallbackForTesting(base::OnceClosure test_callback) {
+    connection_error_test_callback_ = std::move(test_callback);
+  }
+
   virtual void Trace(blink::Visitor*);
 
   DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange);
@@ -71,11 +92,21 @@
   void StopObserving();
   UserMediaController* GetUserMediaController();
   void Dispose();
+  void DevicesEnumerated(ScriptPromiseResolver*,
+                         Vector<Vector<mojom::blink::MediaDeviceInfoPtr>>);
+  void OnDispatcherHostConnectionError();
+  const mojom::blink::MediaDevicesDispatcherHostPtr& GetDispatcherHost(
+      LocalFrame*);
 
   bool observing_;
   bool stopped_;
   Member<AsyncMethodRunner<MediaDevices>> dispatch_scheduled_event_runner_;
   HeapVector<Member<Event>> scheduled_events_;
+  mojom::blink::MediaDevicesDispatcherHostPtr dispatcher_host_;
+  HeapHashSet<Member<ScriptPromiseResolver>> requests_;
+
+  EnumerateDevicesTestCallback enumerate_devices_test_callback_;
+  base::OnceClosure connection_error_test_callback_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.cpp b/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.cpp
deleted file mode 100644
index 1f0062b..0000000
--- a/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.cpp
+++ /dev/null
@@ -1,83 +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. ``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
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "modules/mediastream/MediaDevicesRequest.h"
-
-#include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "core/dom/DOMException.h"
-#include "core/dom/Document.h"
-#include "modules/mediastream/UserMediaController.h"
-#include "platform/bindings/ScriptState.h"
-
-namespace blink {
-
-MediaDevicesRequest* MediaDevicesRequest::Create(
-    ScriptState* state,
-    UserMediaController* controller) {
-  return new MediaDevicesRequest(state, controller);
-}
-
-MediaDevicesRequest::MediaDevicesRequest(ScriptState* state,
-                                         UserMediaController* controller)
-    : ContextLifecycleObserver(ExecutionContext::From(state)),
-      controller_(controller),
-      resolver_(ScriptPromiseResolver::Create(state)) {}
-
-MediaDevicesRequest::~MediaDevicesRequest() {}
-
-Document* MediaDevicesRequest::OwnerDocument() {
-  if (ExecutionContext* context = GetExecutionContext()) {
-    return ToDocument(context);
-  }
-
-  return nullptr;
-}
-
-ScriptPromise MediaDevicesRequest::Start() {
-  DCHECK(controller_);
-  resolver_->KeepAliveWhilePending();
-  controller_->RequestMediaDevices(this);
-  return resolver_->Promise();
-}
-
-void MediaDevicesRequest::Succeed(const MediaDeviceInfoVector& media_devices) {
-  if (!GetExecutionContext() || !resolver_)
-    return;
-
-  resolver_->Resolve(media_devices);
-}
-
-void MediaDevicesRequest::ContextDestroyed(ExecutionContext*) {
-  controller_.Clear();
-  resolver_.Clear();
-}
-
-void MediaDevicesRequest::Trace(blink::Visitor* visitor) {
-  visitor->Trace(controller_);
-  visitor->Trace(resolver_);
-  ContextLifecycleObserver::Trace(visitor);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.h b/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.h
deleted file mode 100644
index 6c4644f..0000000
--- a/third_party/WebKit/Source/modules/mediastream/MediaDevicesRequest.h
+++ /dev/null
@@ -1,71 +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. ``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
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaDevicesRequest_h
-#define MediaDevicesRequest_h
-
-#include "bindings/core/v8/ScriptPromise.h"
-#include "core/dom/ContextLifecycleObserver.h"
-#include "modules/ModulesExport.h"
-#include "modules/mediastream/MediaDeviceInfo.h"
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class Document;
-class UserMediaController;
-class ScriptState;
-class ScriptPromiseResolver;
-
-class MODULES_EXPORT MediaDevicesRequest final
-    : public GarbageCollectedFinalized<MediaDevicesRequest>,
-      public ContextLifecycleObserver {
-  USING_GARBAGE_COLLECTED_MIXIN(MediaDevicesRequest);
-
- public:
-  static MediaDevicesRequest* Create(ScriptState*, UserMediaController*);
-  virtual ~MediaDevicesRequest();
-
-  Document* OwnerDocument();
-
-  ScriptPromise Start();
-
-  void Succeed(const MediaDeviceInfoVector&);
-
-  // ContextLifecycleObserver
-  void ContextDestroyed(ExecutionContext*) override;
-
-  virtual void Trace(blink::Visitor*);
-
- private:
-  MediaDevicesRequest(ScriptState*, UserMediaController*);
-
-  Member<UserMediaController> controller_;
-  Member<ScriptPromiseResolver> resolver_;
-};
-
-}  // namespace blink
-
-#endif  // MediaDevicesRequest_h
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDevicesTest.cpp b/third_party/WebKit/Source/modules/mediastream/MediaDevicesTest.cpp
index 78b6189..8620321 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaDevicesTest.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/MediaDevicesTest.cpp
@@ -7,10 +7,112 @@
 #include "core/testing/NullExecutionContext.h"
 #include "modules/mediastream/MediaDevices.h"
 #include "modules/mediastream/MediaStreamConstraints.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "platform/testing/TestingPlatformSupport.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using blink::mojom::blink::MediaDeviceInfoPtr;
+using blink::mojom::blink::MediaDeviceType;
+
 namespace blink {
 
+const char kFakeAudioInputDeviceId1[] = "fake_audio_input 1";
+const char kFakeAudioInputDeviceId2[] = "fake_audio_input 2";
+const char kFakeVideoInputDeviceId1[] = "fake_video_input 1";
+const char kFakeVideoInputDeviceId2[] = "fake_video_input 2";
+const char kFakeAudioOutputDeviceId1[] = "fake_audio_output 1";
+
+class MockMediaDevicesDispatcherHost
+    : public mojom::blink::MediaDevicesDispatcherHost {
+ public:
+  MockMediaDevicesDispatcherHost() : binding_(this) {}
+
+  void EnumerateDevices(bool request_audio_input,
+                        bool request_video_input,
+                        bool request_audio_output,
+                        EnumerateDevicesCallback callback) override {
+    Vector<Vector<mojom::blink::MediaDeviceInfoPtr>> enumeration(
+        static_cast<size_t>(MediaDeviceType::NUM_MEDIA_DEVICE_TYPES));
+    MediaDeviceInfoPtr device_info;
+    if (request_audio_input) {
+      device_info = mojom::blink::MediaDeviceInfo::New();
+      device_info->device_id = kFakeAudioInputDeviceId1;
+      device_info->label = "Fake Audio Input 1";
+      device_info->group_id = "fake_group 1";
+      enumeration[static_cast<size_t>(MediaDeviceType::MEDIA_AUDIO_INPUT)]
+          .push_back(std::move(device_info));
+
+      device_info = mojom::blink::MediaDeviceInfo::New();
+      device_info->device_id = kFakeAudioInputDeviceId2;
+      device_info->label = "Fake Audio Input 2";
+      device_info->group_id = "fake_group 2";
+      enumeration[static_cast<size_t>(MediaDeviceType::MEDIA_AUDIO_INPUT)]
+          .push_back(std::move(device_info));
+    }
+    if (request_video_input) {
+      device_info = mojom::blink::MediaDeviceInfo::New();
+      device_info->device_id = kFakeVideoInputDeviceId1;
+      device_info->label = "Fake Video Input 1";
+      device_info->group_id = "";
+      enumeration[static_cast<size_t>(MediaDeviceType::MEDIA_VIDEO_INPUT)]
+          .push_back(std::move(device_info));
+
+      device_info = mojom::blink::MediaDeviceInfo::New();
+      device_info->device_id = kFakeVideoInputDeviceId2;
+      device_info->label = "Fake Video Input 2";
+      device_info->group_id = "";
+      enumeration[static_cast<size_t>(MediaDeviceType::MEDIA_VIDEO_INPUT)]
+          .push_back(std::move(device_info));
+    }
+    if (request_audio_output) {
+      device_info = mojom::blink::MediaDeviceInfo::New();
+      device_info->device_id = kFakeAudioOutputDeviceId1;
+      device_info->label = "Fake Audio Input 1";
+      device_info->group_id = "fake_group 1";
+      enumeration[static_cast<size_t>(MediaDeviceType::MEDIA_AUDIO_OUTPUT)]
+          .push_back(std::move(device_info));
+    }
+    std::move(callback).Run(std::move(enumeration));
+  }
+
+  void GetVideoInputCapabilities(GetVideoInputCapabilitiesCallback) override {
+    NOTREACHED();
+  }
+
+  void GetAllVideoInputDeviceFormats(
+      const String&,
+      GetAllVideoInputDeviceFormatsCallback) override {
+    NOTREACHED();
+  }
+
+  void GetAvailableVideoInputDeviceFormats(
+      const String&,
+      GetAvailableVideoInputDeviceFormatsCallback) override {
+    NOTREACHED();
+  }
+
+  void GetAudioInputCapabilities(GetAudioInputCapabilitiesCallback) override {
+    NOTREACHED();
+  }
+
+  MOCK_METHOD2(SubscribeDeviceChangeNotifications,
+               void(MediaDeviceType type, uint32_t subscription_id));
+  MOCK_METHOD2(UnsubscribeDeviceChangeNotifications,
+               void(MediaDeviceType type, uint32_t subscription_id));
+
+  mojom::blink::MediaDevicesDispatcherHostPtr CreateInterfacePtrAndBind() {
+    mojom::blink::MediaDevicesDispatcherHostPtr ptr;
+    binding_.Bind(mojo::MakeRequest(&ptr));
+    return ptr;
+  }
+
+  void CloseBinding() { binding_.Close(); }
+
+ private:
+  mojo::Binding<mojom::blink::MediaDevicesDispatcherHost> binding_;
+};
+
 class PromiseObserver {
  public:
   PromiseObserver(ScriptState* script_state, ScriptPromise promise)
@@ -60,12 +162,60 @@
   ScriptValue saved_arg_;
 };
 
-TEST(MediaDevicesTest, GetUserMediaCanBeCalled) {
+class MediaDevicesTest : public ::testing::Test {
+ public:
+  using MediaDeviceInfos = PersistentHeapVector<Member<MediaDeviceInfo>>;
+
+  MediaDevicesTest() {}
+
+  MediaDevices* GetMediaDevices(ExecutionContext* context) {
+    if (!media_devices_) {
+      media_devices_ = MediaDevices::Create(context);
+      media_devices_->SetDispatcherHostForTesting(
+          dispatcher_host_.CreateInterfacePtrAndBind());
+    }
+    return media_devices_;
+  }
+
+  void DevicesEnumerated(const MediaDeviceInfoVector& device_infos) {
+    devices_enumerated_ = true;
+    for (size_t i = 0; i < device_infos.size(); i++) {
+      device_infos_.push_back(MediaDeviceInfo::Create(
+          device_infos[i]->deviceId(), device_infos[i]->label(),
+          device_infos[i]->groupId(), device_infos[i]->DeviceType()));
+    }
+  }
+
+  void OnDispatcherHostConnectionError() { connection_error_ = true; }
+
+  void CloseBinding() { dispatcher_host_.CloseBinding(); }
+
+  const MediaDeviceInfos& device_infos() const { return device_infos_; }
+
+  bool devices_enumerated() const { return devices_enumerated_; }
+
+  bool connection_error() const { return connection_error_; }
+
+  ScopedTestingPlatformSupport<TestingPlatformSupport>& platform() {
+    return platform_;
+  }
+
+ private:
+  ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
+  MockMediaDevicesDispatcherHost dispatcher_host_;
+  MediaDeviceInfos device_infos_;
+  bool devices_enumerated_ = false;
+  bool connection_error_ = false;
+  Persistent<MediaDevices> media_devices_;
+};
+
+TEST_F(MediaDevicesTest, GetUserMediaCanBeCalled) {
   V8TestingScope scope;
-  auto devices = MediaDevices::Create(scope.GetExecutionContext());
   MediaStreamConstraints constraints;
-  ScriptPromise promise = devices->getUserMedia(
-      scope.GetScriptState(), constraints, scope.GetExceptionState());
+  ScriptPromise promise =
+      GetMediaDevices(scope.GetExecutionContext())
+          ->getUserMedia(scope.GetScriptState(), constraints,
+                         scope.GetExceptionState());
   ASSERT_FALSE(promise.IsEmpty());
   PromiseObserver promise_observer(scope.GetScriptState(), promise);
   EXPECT_FALSE(promise_observer.isDecided());
@@ -86,4 +236,101 @@
                               .ToLocalChecked());
 }
 
+TEST_F(MediaDevicesTest, EnumerateDevices) {
+  V8TestingScope scope;
+  auto media_devices = GetMediaDevices(scope.GetExecutionContext());
+  media_devices->SetEnumerateDevicesCallbackForTesting(
+      WTF::Bind(&MediaDevicesTest::DevicesEnumerated, WTF::Unretained(this)));
+  ScriptPromise promise =
+      media_devices->enumerateDevices(scope.GetScriptState());
+  platform()->RunUntilIdle();
+  ASSERT_FALSE(promise.IsEmpty());
+
+  EXPECT_TRUE(devices_enumerated());
+  EXPECT_EQ(5u, device_infos().size());
+
+  // Audio input device with matched output ID.
+  Member<MediaDeviceInfo> device = device_infos()[0];
+  EXPECT_FALSE(device->deviceId().IsEmpty());
+  EXPECT_EQ("audioinput", device->kind());
+  EXPECT_FALSE(device->label().IsEmpty());
+  EXPECT_FALSE(device->groupId().IsEmpty());
+
+  // Audio input device without matched output ID.
+  device = device_infos()[1];
+  EXPECT_FALSE(device->deviceId().IsEmpty());
+  EXPECT_EQ("audioinput", device->kind());
+  EXPECT_FALSE(device->label().IsEmpty());
+  EXPECT_FALSE(device->groupId().IsEmpty());
+
+  // Video input devices.
+  device = device_infos()[2];
+  EXPECT_FALSE(device->deviceId().IsEmpty());
+  EXPECT_EQ("videoinput", device->kind());
+  EXPECT_FALSE(device->label().IsEmpty());
+  EXPECT_TRUE(device->groupId().IsEmpty());
+
+  device = device_infos()[3];
+  EXPECT_FALSE(device->deviceId().IsEmpty());
+  EXPECT_EQ("videoinput", device->kind());
+  EXPECT_FALSE(device->label().IsEmpty());
+  EXPECT_TRUE(device->groupId().IsEmpty());
+
+  // Audio output device.
+  device = device_infos()[4];
+  EXPECT_FALSE(device->deviceId().IsEmpty());
+  EXPECT_EQ("audiooutput", device->kind());
+  EXPECT_FALSE(device->label().IsEmpty());
+  EXPECT_FALSE(device->groupId().IsEmpty());
+
+  // Verfify group IDs.
+  EXPECT_EQ(device_infos()[0]->groupId(), device_infos()[4]->groupId());
+  EXPECT_NE(device_infos()[1]->groupId(), device_infos()[4]->groupId());
+}
+
+TEST_F(MediaDevicesTest, EnumerateDevicesAfterConnectionError) {
+  V8TestingScope scope;
+  auto media_devices = GetMediaDevices(scope.GetExecutionContext());
+  media_devices->SetEnumerateDevicesCallbackForTesting(
+      WTF::Bind(&MediaDevicesTest::DevicesEnumerated, WTF::Unretained(this)));
+  media_devices->SetConnectionErrorCallbackForTesting(
+      WTF::Bind(&MediaDevicesTest::OnDispatcherHostConnectionError,
+                WTF::Unretained(this)));
+  EXPECT_FALSE(connection_error());
+
+  // Simulate a connection error by closing the binding.
+  CloseBinding();
+  platform()->RunUntilIdle();
+
+  ScriptPromise promise =
+      media_devices->enumerateDevices(scope.GetScriptState());
+  platform()->RunUntilIdle();
+  ASSERT_FALSE(promise.IsEmpty());
+  EXPECT_TRUE(connection_error());
+  EXPECT_FALSE(devices_enumerated());
+}
+
+TEST_F(MediaDevicesTest, EnumerateDevicesBeforeConnectionError) {
+  V8TestingScope scope;
+  auto media_devices = GetMediaDevices(scope.GetExecutionContext());
+  media_devices->SetEnumerateDevicesCallbackForTesting(
+      WTF::Bind(&MediaDevicesTest::DevicesEnumerated, WTF::Unretained(this)));
+  media_devices->SetConnectionErrorCallbackForTesting(
+      WTF::Bind(&MediaDevicesTest::OnDispatcherHostConnectionError,
+                WTF::Unretained(this)));
+  EXPECT_FALSE(connection_error());
+
+  ScriptPromise promise =
+      media_devices->enumerateDevices(scope.GetScriptState());
+  platform()->RunUntilIdle();
+  ASSERT_FALSE(promise.IsEmpty());
+
+  // Simulate a connection error by closing the binding.
+  CloseBinding();
+  platform()->RunUntilIdle();
+
+  EXPECT_TRUE(connection_error());
+  EXPECT_TRUE(devices_enumerated());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/mediastream/NavigatorMediaStream.cpp b/third_party/WebKit/Source/modules/mediastream/NavigatorMediaStream.cpp
index 57da2214..25a2d3c 100644
--- a/third_party/WebKit/Source/modules/mediastream/NavigatorMediaStream.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/NavigatorMediaStream.cpp
@@ -31,7 +31,6 @@
 #include "core/frame/Navigator.h"
 #include "core/frame/Settings.h"
 #include "core/page/Page.h"
-#include "modules/mediastream/MediaDevicesRequest.h"
 #include "modules/mediastream/MediaErrorState.h"
 #include "modules/mediastream/MediaStreamConstraints.h"
 #include "modules/mediastream/NavigatorUserMediaErrorCallback.h"
diff --git a/third_party/WebKit/Source/modules/mediastream/UserMediaClient.cpp b/third_party/WebKit/Source/modules/mediastream/UserMediaClient.cpp
index ce990de..b56e308 100644
--- a/third_party/WebKit/Source/modules/mediastream/UserMediaClient.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/UserMediaClient.cpp
@@ -36,7 +36,6 @@
 #include "public/web/WebApplyConstraintsRequest.h"
 #include "public/web/WebFrameClient.h"
 #include "public/web/WebMediaDeviceChangeObserver.h"
-#include "public/web/WebMediaDevicesRequest.h"
 #include "public/web/WebUserMediaClient.h"
 #include "public/web/WebUserMediaRequest.h"
 
@@ -59,11 +58,6 @@
     client_->CancelUserMediaRequest(WebUserMediaRequest(request));
 }
 
-void UserMediaClient::RequestMediaDevices(MediaDevicesRequest* request) {
-  if (client_)
-    client_->RequestMediaDevices(request);
-}
-
 void UserMediaClient::SetMediaDeviceChangeObserver(MediaDevices* observer) {
   if (client_) {
     client_->SetMediaDeviceChangeObserver(
diff --git a/third_party/WebKit/Source/modules/mediastream/UserMediaClient.h b/third_party/WebKit/Source/modules/mediastream/UserMediaClient.h
index b0a38d2..dfa43ae 100644
--- a/third_party/WebKit/Source/modules/mediastream/UserMediaClient.h
+++ b/third_party/WebKit/Source/modules/mediastream/UserMediaClient.h
@@ -43,7 +43,6 @@
 class ApplyConstraintsRequest;
 class LocalFrame;
 class MediaDevices;
-class MediaDevicesRequest;
 class MediaStreamComponent;
 class UserMediaRequest;
 class WebUserMediaClient;
@@ -56,7 +55,6 @@
 
   void RequestUserMedia(UserMediaRequest*);
   void CancelUserMediaRequest(UserMediaRequest*);
-  void RequestMediaDevices(MediaDevicesRequest*);
   void SetMediaDeviceChangeObserver(MediaDevices*);
   void ApplyConstraints(ApplyConstraintsRequest*);
   void StopTrack(MediaStreamComponent*);
diff --git a/third_party/WebKit/Source/modules/mediastream/UserMediaController.h b/third_party/WebKit/Source/modules/mediastream/UserMediaController.h
index 240f312..b34040f7 100644
--- a/third_party/WebKit/Source/modules/mediastream/UserMediaController.h
+++ b/third_party/WebKit/Source/modules/mediastream/UserMediaController.h
@@ -34,7 +34,6 @@
 
 class ApplyConstraintsRequest;
 class MediaDevices;
-class MediaDevicesRequest;
 class MediaStreamComponent;
 class UserMediaRequest;
 
@@ -51,7 +50,6 @@
 
   void RequestUserMedia(UserMediaRequest*);
   void CancelUserMediaRequest(UserMediaRequest*);
-  void RequestMediaDevices(MediaDevicesRequest*);
   void SetMediaDeviceChangeObserver(MediaDevices*);
   void ApplyConstraints(ApplyConstraintsRequest*);
   void StopTrack(MediaStreamComponent*);
@@ -75,11 +73,6 @@
   client_->CancelUserMediaRequest(request);
 }
 
-inline void UserMediaController::RequestMediaDevices(
-    MediaDevicesRequest* request) {
-  client_->RequestMediaDevices(request);
-}
-
 inline void UserMediaController::SetMediaDeviceChangeObserver(
     MediaDevices* observer) {
   client_->SetMediaDeviceChangeObserver(observer);
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni
index ae504e3..0ddd413 100644
--- a/third_party/WebKit/Source/modules/modules_idl_files.gni
+++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -169,6 +169,8 @@
           "indexeddb/IDBTransaction.idl",
           "indexeddb/IDBVersionChangeEvent.idl",
           "installedapp/RelatedApplication.idl",
+          "locks/Lock.idl",
+          "locks/LockManager.idl",
           "media_capabilities/MediaCapabilities.idl",
           "media_capabilities/MediaCapabilitiesInfo.idl",
           "mediacapturefromelement/CanvasCaptureMediaStreamTrack.idl",
@@ -501,6 +503,7 @@
                     "indexeddb/IDBObjectStoreParameters.idl",
                     "indexeddb/IDBObserverInit.idl",
                     "indexeddb/IDBVersionChangeEventInit.idl",
+                    "locks/LockOptions.idl",
                     "media_capabilities/AudioConfiguration.idl",
                     "media_capabilities/MediaConfiguration.idl",
                     "media_capabilities/MediaDecodingConfiguration.idl",
@@ -681,6 +684,8 @@
           "indexeddb/WorkerGlobalScopeIndexedDatabase.idl",
           "installedapp/NavigatorInstalledApp.idl",
           "keyboard_lock/NavigatorKeyboardLock.idl",
+          "locks/NavigatorLocks.idl",
+          "locks/WorkerNavigatorLocks.idl",
           "media_capabilities/NavigatorMediaCapabilities.idl",
           "mediacapturefromelement/HTMLCanvasElementCapture.idl",
           "mediacapturefromelement/HTMLMediaElementCapture.idl",
diff --git a/third_party/WebKit/Source/modules/nfc/NFC.cpp b/third_party/WebKit/Source/modules/nfc/NFC.cpp
index 92bfe960..3ed74ed 100644
--- a/third_party/WebKit/Source/modules/nfc/NFC.cpp
+++ b/third_party/WebKit/Source/modules/nfc/NFC.cpp
@@ -645,8 +645,8 @@
     return;
 
   frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&nfc_));
-  nfc_.set_connection_error_handler(ConvertToBaseCallback(
-      WTF::Bind(&NFC::OnConnectionError, WrapWeakPersistent(this))));
+  nfc_.set_connection_error_handler(
+      WTF::Bind(&NFC::OnConnectionError, WrapWeakPersistent(this)));
   device::mojom::blink::NFCClientPtr client;
   client_binding_.Bind(mojo::MakeRequest(&client));
   nfc_->SetClient(std::move(client));
@@ -717,9 +717,8 @@
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   requests_.insert(resolver);
-  auto callback = ConvertToBaseCallback(WTF::Bind(&NFC::OnRequestCompleted,
-                                                  WrapPersistent(this),
-                                                  WrapPersistent(resolver)));
+  auto callback = WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
+                            WrapPersistent(resolver));
   nfc_->Push(std::move(message),
              device::mojom::blink::NFCPushOptions::From(options),
              std::move(callback));
@@ -735,9 +734,8 @@
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   requests_.insert(resolver);
-  auto callback = ConvertToBaseCallback(WTF::Bind(&NFC::OnRequestCompleted,
-                                                  WrapPersistent(this),
-                                                  WrapPersistent(resolver)));
+  auto callback = WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
+                            WrapPersistent(resolver));
   nfc_->CancelPush(mojo::toNFCPushTarget(target), std::move(callback));
 
   return resolver->Promise();
@@ -764,9 +762,9 @@
   callback->SetScriptState(script_state);
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   requests_.insert(resolver);
-  auto watch_callback = ConvertToBaseCallback(
+  auto watch_callback =
       WTF::Bind(&NFC::OnWatchRegistered, WrapPersistent(this),
-                WrapPersistent(callback), WrapPersistent(resolver)));
+                WrapPersistent(callback), WrapPersistent(resolver));
   nfc_->Watch(device::mojom::blink::NFCWatchOptions::From(options),
               std::move(watch_callback));
   return resolver->Promise();
@@ -787,9 +785,9 @@
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   requests_.insert(resolver);
-  nfc_->CancelWatch(id, ConvertToBaseCallback(WTF::Bind(
-                            &NFC::OnRequestCompleted, WrapPersistent(this),
-                            WrapPersistent(resolver))));
+  nfc_->CancelWatch(id,
+                    WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
+                              WrapPersistent(resolver)));
   return resolver->Promise();
 }
 
@@ -803,9 +801,9 @@
   callbacks_.clear();
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   requests_.insert(resolver);
-  nfc_->CancelAllWatches(ConvertToBaseCallback(
-      WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
-                WrapPersistent(resolver))));
+  nfc_->CancelAllWatches(WTF::Bind(&NFC::OnRequestCompleted,
+                                   WrapPersistent(this),
+                                   WrapPersistent(resolver)));
   return resolver->Promise();
 }
 
diff --git a/third_party/WebKit/Source/modules/notifications/Notification.cpp b/third_party/WebKit/Source/modules/notifications/Notification.cpp
index 202342b..4faaf98 100644
--- a/third_party/WebKit/Source/modules/notifications/Notification.cpp
+++ b/third_party/WebKit/Source/modules/notifications/Notification.cpp
@@ -118,6 +118,11 @@
   if (exception_state.HadException())
     return nullptr;
 
+  if (context->IsContextDestroyed()) {
+    exception_state.ThrowTypeError("Illegal invocation.");
+    return nullptr;
+  }
+
   Notification* notification =
       new Notification(context, Type::kNonPersistent, data);
   notification->SchedulePrepareShow();
@@ -186,11 +191,17 @@
 void Notification::DidLoadResources(NotificationResourcesLoader* loader) {
   DCHECK_EQ(loader, loader_.Get());
 
-  const SecurityOrigin* origin = GetExecutionContext()->GetSecurityOrigin();
+  ExecutionContext* execution_context = GetExecutionContext();
+  const SecurityOrigin* origin = execution_context->GetSecurityOrigin();
   DCHECK(origin);
 
-  GetWebNotificationManager()->Show(WebSecurityOrigin(origin), data_,
-                                    loader->GetResources(), this);
+  if (RuntimeEnabledFeatures::NotificationsWithMojoEnabled()) {
+    NotificationManager::From(execution_context)
+        ->DisplayNonPersistentNotification(data_.title);
+  } else {
+    GetWebNotificationManager()->Show(WebSecurityOrigin(origin), data_,
+                                      loader->GetResources(), this);
+  }
   loader_.Clear();
 
   state_ = State::kShowing;
@@ -209,7 +220,11 @@
                                               WrapPersistent(this)));
     state_ = State::kClosing;
 
-    GetWebNotificationManager()->Close(this);
+    if (RuntimeEnabledFeatures::NotificationsWithMojoEnabled()) {
+      // TODO(crbug.com/595685): Implement Close path via Mojo.
+    } else {
+      GetWebNotificationManager()->Close(this);
+    }
     return;
   }
 
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h
index a10eb56..cc8152f5 100644
--- a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h
+++ b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h
@@ -32,7 +32,7 @@
 
   // The bitmap may be empty if the request failed or the image data could not
   // be decoded.
-  using ImageCallback = Function<void(const SkBitmap&)>;
+  using ImageCallback = base::OnceCallback<void(const SkBitmap&)>;
 
   explicit NotificationImageLoader(Type);
   ~NotificationImageLoader() override;
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationManager.cpp b/third_party/WebKit/Source/modules/notifications/NotificationManager.cpp
index 3e16e66..7bc802f 100644
--- a/third_party/WebKit/Source/modules/notifications/NotificationManager.cpp
+++ b/third_party/WebKit/Source/modules/notifications/NotificationManager.cpp
@@ -69,9 +69,9 @@
   if (!permission_service_) {
     ConnectToPermissionService(context,
                                mojo::MakeRequest(&permission_service_));
-    permission_service_.set_connection_error_handler(ConvertToBaseCallback(
+    permission_service_.set_connection_error_handler(
         WTF::Bind(&NotificationManager::OnPermissionServiceConnectionError,
-                  WrapWeakPersistent(this))));
+                  WrapWeakPersistent(this)));
   }
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
@@ -82,10 +82,9 @@
       CreatePermissionDescriptor(mojom::blink::PermissionName::NOTIFICATIONS),
       context->GetSecurityOrigin(),
       Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
-      ConvertToBaseCallback(
-          WTF::Bind(&NotificationManager::OnPermissionRequestComplete,
-                    WrapPersistent(this), WrapPersistent(resolver),
-                    WrapPersistent(deprecated_callback))));
+      WTF::Bind(&NotificationManager::OnPermissionRequestComplete,
+                WrapPersistent(this), WrapPersistent(resolver),
+                WrapPersistent(deprecated_callback)));
 
   return promise;
 }
@@ -109,15 +108,21 @@
   permission_service_.reset();
 }
 
+void NotificationManager::DisplayNonPersistentNotification(
+    const String& title) {
+  // TODO(crbug.com/595685): Pass the rest of the notification properties here.
+  GetNotificationService()->DisplayNonPersistentNotification(title);
+}
+
 const mojom::blink::NotificationServicePtr&
 NotificationManager::GetNotificationService() {
   if (!notification_service_) {
     if (auto* provider = GetSupplementable()->GetInterfaceProvider()) {
       provider->GetInterface(mojo::MakeRequest(&notification_service_));
 
-      notification_service_.set_connection_error_handler(ConvertToBaseCallback(
+      notification_service_.set_connection_error_handler(
           WTF::Bind(&NotificationManager::OnNotificationServiceConnectionError,
-                    WrapWeakPersistent(this))));
+                    WrapWeakPersistent(this)));
     }
   }
 
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationManager.h b/third_party/WebKit/Source/modules/notifications/NotificationManager.h
index c7cb250..c62c39e 100644
--- a/third_party/WebKit/Source/modules/notifications/NotificationManager.h
+++ b/third_party/WebKit/Source/modules/notifications/NotificationManager.h
@@ -42,6 +42,9 @@
       ScriptState*,
       NotificationPermissionCallback* deprecated_callback);
 
+  // Shows a notification that is not tied to any service worker.
+  void DisplayNonPersistentNotification(const String& title);
+
   virtual void Trace(blink::Visitor*);
 
  private:
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.h b/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.h
index f64aff6a1..bae7c57a5 100644
--- a/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.h
+++ b/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.h
@@ -32,7 +32,8 @@
   // Called when all fetches have finished. Passes a pointer to the
   // NotificationResourcesLoader so callers that use multiple loaders can use
   // the same function to handle the callbacks.
-  using CompletionCallback = Function<void(NotificationResourcesLoader*)>;
+  using CompletionCallback =
+      base::OnceCallback<void(NotificationResourcesLoader*)>;
 
   explicit NotificationResourcesLoader(CompletionCallback);
   ~NotificationResourcesLoader();
diff --git a/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp b/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp
index 6fce098..403d2e8 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp
@@ -82,9 +82,9 @@
   ScriptPromise promise = resolver->Promise();
 
   manager_->DeletePaymentInstrument(
-      instrument_key, ConvertToBaseCallback(WTF::Bind(
-                          &PaymentInstruments::onDeletePaymentInstrument,
-                          WrapPersistent(this), WrapPersistent(resolver))));
+      instrument_key,
+      WTF::Bind(&PaymentInstruments::onDeletePaymentInstrument,
+                WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
@@ -100,9 +100,9 @@
   ScriptPromise promise = resolver->Promise();
 
   manager_->GetPaymentInstrument(
-      instrument_key, ConvertToBaseCallback(WTF::Bind(
-                          &PaymentInstruments::onGetPaymentInstrument,
-                          WrapPersistent(this), WrapPersistent(resolver))));
+      instrument_key,
+      WTF::Bind(&PaymentInstruments::onGetPaymentInstrument,
+                WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
@@ -116,9 +116,9 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
 
-  manager_->KeysOfPaymentInstruments(ConvertToBaseCallback(
+  manager_->KeysOfPaymentInstruments(
       WTF::Bind(&PaymentInstruments::onKeysOfPaymentInstruments,
-                WrapPersistent(this), WrapPersistent(resolver))));
+                WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
@@ -134,9 +134,9 @@
   ScriptPromise promise = resolver->Promise();
 
   manager_->HasPaymentInstrument(
-      instrument_key, ConvertToBaseCallback(WTF::Bind(
-                          &PaymentInstruments::onHasPaymentInstrument,
-                          WrapPersistent(this), WrapPersistent(resolver))));
+      instrument_key,
+      WTF::Bind(&PaymentInstruments::onHasPaymentInstrument,
+                WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
@@ -205,9 +205,8 @@
 
   manager_->SetPaymentInstrument(
       instrument_key, std::move(instrument),
-      ConvertToBaseCallback(
-          WTF::Bind(&PaymentInstruments::onSetPaymentInstrument,
-                    WrapPersistent(this), WrapPersistent(resolver))));
+      WTF::Bind(&PaymentInstruments::onSetPaymentInstrument,
+                WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
@@ -221,9 +220,9 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
 
-  manager_->ClearPaymentInstruments(ConvertToBaseCallback(
+  manager_->ClearPaymentInstruments(
       WTF::Bind(&PaymentInstruments::onClearPaymentInstruments,
-                WrapPersistent(this), WrapPersistent(resolver))));
+                WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/payments/PaymentManager.cpp b/third_party/WebKit/Source/modules/payments/PaymentManager.cpp
index 0eaeb0f..753863f 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentManager.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentManager.cpp
@@ -50,8 +50,8 @@
     }
   }
 
-  manager_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-      &PaymentManager::OnServiceConnectionError, WrapWeakPersistent(this))));
+  manager_.set_connection_error_handler(WTF::Bind(
+      &PaymentManager::OnServiceConnectionError, WrapWeakPersistent(this)));
   manager_->Init(registration_->GetExecutionContext()->Url().GetString(),
                  registration_->scope());
 }
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
index 302f708..d60d107 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -1040,9 +1040,9 @@
 
   GetFrame()->GetInterfaceProvider().GetInterface(
       mojo::MakeRequest(&payment_provider_));
-  payment_provider_.set_connection_error_handler(ConvertToBaseCallback(
+  payment_provider_.set_connection_error_handler(
       WTF::Bind(&PaymentRequest::OnError, WrapWeakPersistent(this),
-                PaymentErrorReason::UNKNOWN)));
+                PaymentErrorReason::UNKNOWN));
 
   payments::mojom::blink::PaymentRequestClientPtr client;
   client_binding_.Bind(mojo::MakeRequest(&client));
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
index 07de959..823a0cb 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -514,7 +514,8 @@
     return;
   }
 
-  peer_handler_ = Platform::Current()->CreateRTCPeerConnectionHandler(this);
+  peer_handler_ = Platform::Current()->CreateRTCPeerConnectionHandler(
+      this, document->GetTaskRunner(TaskType::kUnthrottled));
   if (!peer_handler_) {
     closed_ = true;
     stopped_ = true;
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
index d88ef48..fc08d635 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
@@ -229,7 +229,7 @@
   FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest,
                            GetTrackRemoveStreamAndGCWithPersistentStream);
 
-  typedef Function<bool()> BoolFunction;
+  typedef base::OnceCallback<bool()> BoolFunction;
   class EventWrapper : public GarbageCollectedFinalized<EventWrapper> {
    public:
     EventWrapper(Event*, BoolFunction);
diff --git a/third_party/WebKit/Source/modules/permissions/Permissions.cpp b/third_party/WebKit/Source/modules/permissions/Permissions.cpp
index 52451e9..2b1c534 100644
--- a/third_party/WebKit/Source/modules/permissions/Permissions.cpp
+++ b/third_party/WebKit/Source/modules/permissions/Permissions.cpp
@@ -172,10 +172,9 @@
   GetService(ExecutionContext::From(script_state))
       .HasPermission(std::move(descriptor),
                      ExecutionContext::From(script_state)->GetSecurityOrigin(),
-                     ConvertToBaseCallback(WTF::Bind(
-                         &Permissions::TaskComplete, WrapPersistent(this),
-                         WrapPersistent(resolver),
-                         WTF::Passed(std::move(descriptor_copy)))));
+                     WTF::Bind(&Permissions::TaskComplete, WrapPersistent(this),
+                               WrapPersistent(resolver),
+                               WTF::Passed(std::move(descriptor_copy))));
   return promise;
 }
 
@@ -198,13 +197,13 @@
   Document* doc = ToDocumentOrNull(context);
   Frame* frame = doc ? doc->GetFrame() : nullptr;
   GetService(ExecutionContext::From(script_state))
-      .RequestPermission(std::move(descriptor), context->GetSecurityOrigin(),
-                         Frame::HasTransientUserActivation(
-                             frame, true /* checkIfMainThread */),
-                         ConvertToBaseCallback(WTF::Bind(
-                             &Permissions::TaskComplete, WrapPersistent(this),
-                             WrapPersistent(resolver),
-                             WTF::Passed(std::move(descriptor_copy)))));
+      .RequestPermission(
+          std::move(descriptor), context->GetSecurityOrigin(),
+          Frame::HasTransientUserActivation(frame,
+                                            true /* checkIfMainThread */),
+          WTF::Bind(&Permissions::TaskComplete, WrapPersistent(this),
+                    WrapPersistent(resolver),
+                    WTF::Passed(std::move(descriptor_copy))));
   return promise;
 }
 
@@ -226,10 +225,9 @@
       .RevokePermission(
           std::move(descriptor),
           ExecutionContext::From(script_state)->GetSecurityOrigin(),
-          ConvertToBaseCallback(
-              WTF::Bind(&Permissions::TaskComplete, WrapPersistent(this),
-                        WrapPersistent(resolver),
-                        WTF::Passed(std::move(descriptor_copy)))));
+          WTF::Bind(&Permissions::TaskComplete, WrapPersistent(this),
+                    WrapPersistent(resolver),
+                    WTF::Passed(std::move(descriptor_copy))));
   return promise;
 }
 
@@ -282,11 +280,10 @@
           std::move(internal_permissions), context->GetSecurityOrigin(),
           Frame::HasTransientUserActivation(frame,
                                             true /* checkIfMainThread */),
-          ConvertToBaseCallback(WTF::Bind(
-              &Permissions::BatchTaskComplete, WrapPersistent(this),
-              WrapPersistent(resolver),
-              WTF::Passed(std::move(internal_permissions_copy)),
-              WTF::Passed(std::move(caller_index_to_internal_index)))));
+          WTF::Bind(&Permissions::BatchTaskComplete, WrapPersistent(this),
+                    WrapPersistent(resolver),
+                    WTF::Passed(std::move(internal_permissions_copy)),
+                    WTF::Passed(std::move(caller_index_to_internal_index))));
   return promise;
 }
 
@@ -294,8 +291,8 @@
     ExecutionContext* execution_context) {
   if (!service_) {
     ConnectToPermissionService(execution_context, mojo::MakeRequest(&service_));
-    service_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-        &Permissions::ServiceConnectionError, WrapWeakPersistent(this))));
+    service_.set_connection_error_handler(WTF::Bind(
+        &Permissions::ServiceConnectionError, WrapWeakPersistent(this)));
   }
   return *service_;
 }
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityStateTest.cpp b/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityStateTest.cpp
index 802ae4d..167db460 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityStateTest.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityStateTest.cpp
@@ -171,7 +171,7 @@
 TEST_F(PresentationAvailabilityStateTest,
        RequestAvailabilityOneUrlNoAvailabilityChange) {
   auto* mock_callback =
-      new testing::StrictMock<MockPresentationAvailabilityCallbacks>();
+      new ::testing::StrictMock<MockPresentationAvailabilityCallbacks>();
 
   EXPECT_CALL(mock_presentation_service_, ListenForScreenAvailability(url1_))
       .Times(1);
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
index d3b01b8..c2fbbc74 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
@@ -531,8 +531,8 @@
 void PresentationConnection::SendMessageToTargetConnection(
     mojom::blink::PresentationConnectionMessagePtr message) {
   if (target_connection_) {
-    target_connection_->OnMessage(
-        std::move(message), ConvertToBaseCallback(WTF::Function<void(bool)>()));
+    target_connection_->OnMessage(std::move(message),
+                                  base::OnceCallback<void(bool)>());
   }
 }
 
diff --git a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.cpp b/third_party/WebKit/Source/modules/quota/StorageErrorCallback.cpp
index 978a2be..e14ea99e 100644
--- a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.cpp
+++ b/third_party/WebKit/Source/modules/quota/StorageErrorCallback.cpp
@@ -34,7 +34,7 @@
 
 namespace blink {
 
-WTF::Closure StorageErrorCallback::CreateSameThreadTask(
+base::OnceClosure StorageErrorCallback::CreateSameThreadTask(
     StorageErrorCallback* callback,
     ExceptionCode ec) {
   return WTF::Bind(&StorageErrorCallback::Run, WrapPersistent(callback), ec);
diff --git a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.h b/third_party/WebKit/Source/modules/quota/StorageErrorCallback.h
index f5ed1d0..ee778cb0 100644
--- a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.h
+++ b/third_party/WebKit/Source/modules/quota/StorageErrorCallback.h
@@ -47,8 +47,9 @@
   virtual void Trace(blink::Visitor* visitor) {}
   virtual void handleEvent(DOMError*) = 0;
 
-  MODULES_EXPORT static WTF::Closure CreateSameThreadTask(StorageErrorCallback*,
-                                                          ExceptionCode);
+  MODULES_EXPORT static base::OnceClosure CreateSameThreadTask(
+      StorageErrorCallback*,
+      ExceptionCode);
 
  private:
   static void Run(StorageErrorCallback*, ExceptionCode);
diff --git a/third_party/WebKit/Source/modules/quota/StorageManager.cpp b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
index b247a21..885a28c9 100644
--- a/third_party/WebKit/Source/modules/quota/StorageManager.cpp
+++ b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
@@ -84,9 +84,8 @@
           CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE),
           ExecutionContext::From(script_state)->GetSecurityOrigin(),
           Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
-          ConvertToBaseCallback(
-              WTF::Bind(&StorageManager::PermissionRequestComplete,
-                        WrapPersistent(this), WrapPersistent(resolver))));
+          WTF::Bind(&StorageManager::PermissionRequestComplete,
+                    WrapPersistent(this), WrapPersistent(resolver)));
 
   return promise;
 }
@@ -108,9 +107,8 @@
       .HasPermission(
           CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE),
           ExecutionContext::From(script_state)->GetSecurityOrigin(),
-          ConvertToBaseCallback(
-              WTF::Bind(&StorageManager::PermissionRequestComplete,
-                        WrapPersistent(this), WrapPersistent(resolver))));
+          WTF::Bind(&StorageManager::PermissionRequestComplete,
+                    WrapPersistent(this), WrapPersistent(resolver)));
   return promise;
 }
 
@@ -138,9 +136,9 @@
   if (!permission_service_) {
     ConnectToPermissionService(execution_context,
                                mojo::MakeRequest(&permission_service_));
-    permission_service_.set_connection_error_handler(ConvertToBaseCallback(
+    permission_service_.set_connection_error_handler(
         WTF::Bind(&StorageManager::PermissionServiceConnectionError,
-                  WrapWeakPersistent(this))));
+                  WrapWeakPersistent(this)));
   }
   return *permission_service_;
 }
diff --git a/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.cpp b/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.cpp
index 495a2109..db17112 100644
--- a/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.cpp
+++ b/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.cpp
@@ -14,7 +14,7 @@
     : bindings_cb_(callback) {}
 
 AvailabilityCallbackWrapper::AvailabilityCallbackWrapper(
-    WTF::RepeatingClosure callback)
+    base::RepeatingClosure callback)
     : internal_cb_(std::move(callback)) {}
 
 void AvailabilityCallbackWrapper::Run(RemotePlayback* remote_playback,
diff --git a/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.h b/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.h
index 2f4744a..850d34f 100644
--- a/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.h
+++ b/third_party/WebKit/Source/modules/remoteplayback/AvailabilityCallbackWrapper.h
@@ -7,18 +7,18 @@
 
 #include <memory>
 
+#include "base/callback.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/bindings/TraceWrapperMember.h"
 #include "platform/heap/GarbageCollected.h"
 #include "platform/wtf/Compiler.h"
-#include "platform/wtf/Functional.h"
 
 namespace blink {
 
 class RemotePlayback;
 class V8RemotePlaybackAvailabilityCallback;
 
-// Wraps either a WTF::Closure or RemotePlaybackAvailabilityCallback object
+// Wraps either a base::OnceClosure or RemotePlaybackAvailabilityCallback object
 // to be kept in the RemotePlayback's |availability_callbacks_| map.
 class AvailabilityCallbackWrapper final
     : public GarbageCollectedFinalized<AvailabilityCallbackWrapper>,
@@ -27,7 +27,7 @@
 
  public:
   explicit AvailabilityCallbackWrapper(V8RemotePlaybackAvailabilityCallback*);
-  explicit AvailabilityCallbackWrapper(WTF::RepeatingClosure);
+  explicit AvailabilityCallbackWrapper(base::RepeatingClosure);
   ~AvailabilityCallbackWrapper() = default;
 
   void Run(RemotePlayback*, bool new_availability);
@@ -38,7 +38,7 @@
  private:
   // Only one of these callbacks must be set.
   TraceWrapperMember<V8RemotePlaybackAvailabilityCallback> bindings_cb_;
-  WTF::RepeatingClosure internal_cb_;
+  base::RepeatingClosure internal_cb_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
index c86716b..21a3aa4 100644
--- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
+++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
@@ -48,7 +48,7 @@
 }
 
 void RunRemotePlaybackTask(ExecutionContext* context,
-                           WTF::Closure task,
+                           base::OnceClosure task,
                            std::unique_ptr<int> task_id) {
   probe::AsyncTask async_task(context, task_id.get());
   std::move(task).Run();
@@ -240,11 +240,11 @@
           availability_urls_,
           std::make_unique<RemotePlaybackConnectionCallbacks>(this));
     } else {
-      // TODO(yuryu): Wrapping PromptCancelled with WTF::Closure as
+      // TODO(yuryu): Wrapping PromptCancelled with base::OnceClosure as
       // InspectorInstrumentation requires a globally unique pointer to track
       // tasks. We can remove the wrapper if InspectorInstrumentation returns a
       // task id.
-      WTF::Closure task =
+      base::OnceClosure task =
           WTF::Bind(&RemotePlayback::PromptCancelled, WrapPersistent(this));
       std::unique_ptr<int> task_id = std::make_unique<int>(0);
       probe::AsyncTaskScheduled(GetExecutionContext(), "promptCancelled",
@@ -279,11 +279,11 @@
   } while (!availability_callbacks_.insert(id, callback).is_new_entry);
 
   // Report the current availability via the callback.
-  // TODO(yuryu): Wrapping notifyInitialAvailability with WTF::Closure as
+  // TODO(yuryu): Wrapping notifyInitialAvailability with base::OnceClosure as
   // InspectorInstrumentation requires a globally unique pointer to track tasks.
   // We can remove the wrapper if InspectorInstrumentation returns a task id.
-  WTF::Closure task = WTF::Bind(&RemotePlayback::NotifyInitialAvailability,
-                                WrapPersistent(this), id);
+  base::OnceClosure task = WTF::Bind(&RemotePlayback::NotifyInitialAvailability,
+                                     WrapPersistent(this), id);
   std::unique_ptr<int> task_id = std::make_unique<int>(0);
   probe::AsyncTaskScheduled(GetExecutionContext(), "watchAvailabilityCallback",
                             task_id.get());
diff --git a/third_party/WebKit/Source/modules/sensor/SensorProviderProxy.cpp b/third_party/WebKit/Source/modules/sensor/SensorProviderProxy.cpp
index 96993f39..15c4051 100644
--- a/third_party/WebKit/Source/modules/sensor/SensorProviderProxy.cpp
+++ b/third_party/WebKit/Source/modules/sensor/SensorProviderProxy.cpp
@@ -21,9 +21,9 @@
 
   GetSupplementable()->GetInterfaceProvider().GetInterface(
       mojo::MakeRequest(&sensor_provider_));
-  sensor_provider_.set_connection_error_handler(ConvertToBaseCallback(
+  sensor_provider_.set_connection_error_handler(
       WTF::Bind(&SensorProviderProxy::OnSensorProviderConnectionError,
-                WrapWeakPersistent(this))));
+                WrapWeakPersistent(this)));
 }
 
 const char* SensorProviderProxy::SupplementName() {
diff --git a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
index 504a5e3..edd418e 100644
--- a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
+++ b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
@@ -64,17 +64,16 @@
   }
 
   state_ = kInitializing;
-  auto callback = ConvertToBaseCallback(
-      WTF::Bind(&SensorProxy::OnSensorCreated, WrapWeakPersistent(this)));
+  auto callback =
+      WTF::Bind(&SensorProxy::OnSensorCreated, WrapWeakPersistent(this));
   provider_->GetSensorProvider()->GetSensor(type_, std::move(callback));
 }
 
 void SensorProxy::AddConfiguration(SensorConfigurationPtr configuration,
-                                   Function<void(bool)> callback) {
+                                   base::OnceCallback<void(bool)> callback) {
   DCHECK(IsInitialized());
   AddActiveFrequency(configuration->frequency);
-  sensor_->AddConfiguration(std::move(configuration),
-                            ConvertToBaseCallback(std::move(callback)));
+  sensor_->AddConfiguration(std::move(configuration), std::move(callback));
 }
 
 void SensorProxy::RemoveConfiguration(SensorConfigurationPtr configuration) {
@@ -209,8 +208,7 @@
 
   auto error_callback =
       WTF::Bind(&SensorProxy::HandleSensorError, WrapWeakPersistent(this));
-  sensor_.set_connection_error_handler(
-      ConvertToBaseCallback(std::move(error_callback)));
+  sensor_.set_connection_error_handler(std::move(error_callback));
 
   state_ = kInitialized;
 
diff --git a/third_party/WebKit/Source/modules/sensor/SensorProxy.h b/third_party/WebKit/Source/modules/sensor/SensorProxy.h
index 60938b1..2f7b42c 100644
--- a/third_party/WebKit/Source/modules/sensor/SensorProxy.h
+++ b/third_party/WebKit/Source/modules/sensor/SensorProxy.h
@@ -60,7 +60,7 @@
   bool IsInitialized() const { return state_ == kInitialized; }
 
   void AddConfiguration(device::mojom::blink::SensorConfigurationPtr,
-                        Function<void(bool)>);
+                        base::OnceCallback<void(bool)>);
 
   void RemoveConfiguration(device::mojom::blink::SensorConfigurationPtr);
 
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.cpp
index de8dd59b..75bd0112 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.cpp
@@ -64,4 +64,9 @@
   return g_empty_string;
 }
 
+bool ServiceWorkerScriptCachedMetadataHandler::IsServedFromCacheStorage()
+    const {
+  return false;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.h
index a7985a4..05ceb08 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.h
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerScriptCachedMetadataHandler.h
@@ -35,6 +35,7 @@
   scoped_refptr<CachedMetadata> GetCachedMetadata(
       uint32_t data_type_id) const override;
   String Encoding() const override;
+  bool IsServedFromCacheStorage() const override;
 
  private:
   ServiceWorkerScriptCachedMetadataHandler(WorkerGlobalScope*,
diff --git a/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.h b/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.h
index b272b4d..9a1e849 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.h
+++ b/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.h
@@ -5,11 +5,11 @@
 #ifndef WaitUntilObserver_h
 #define WaitUntilObserver_h
 
+#include "base/callback.h"
 #include "modules/ModulesExport.h"
 #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h"
 #include "platform/Timer.h"
 #include "platform/wtf/Forward.h"
-#include "platform/wtf/Functional.h"
 
 namespace blink {
 
@@ -23,7 +23,7 @@
     : public GarbageCollectedFinalized<WaitUntilObserver> {
  public:
   using PromiseSettledCallback =
-      WTF::RepeatingFunction<void(const ScriptValue&)>;
+      base::RepeatingCallback<void(const ScriptValue&)>;
 
   enum EventType {
     kAbortPayment,
diff --git a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp
index 0dfd46a..072e94c1 100644
--- a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp
+++ b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp
@@ -25,9 +25,9 @@
     interface_provider->GetInterface(std::move(request));
   }
 
-  barcode_service_.set_connection_error_handler(ConvertToBaseCallback(
+  barcode_service_.set_connection_error_handler(
       WTF::Bind(&BarcodeDetector::OnBarcodeServiceConnectionError,
-                WrapWeakPersistent(this))));
+                WrapWeakPersistent(this)));
 }
 
 ScriptPromise BarcodeDetector::DoDetect(ScriptPromiseResolver* resolver,
@@ -40,9 +40,9 @@
   }
   barcode_service_requests_.insert(resolver);
   barcode_service_->Detect(
-      std::move(bitmap), ConvertToBaseCallback(WTF::Bind(
-                             &BarcodeDetector::OnDetectBarcodes,
-                             WrapPersistent(this), WrapPersistent(resolver))));
+      std::move(bitmap),
+      WTF::Bind(&BarcodeDetector::OnDetectBarcodes, WrapPersistent(this),
+                WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp
index 077097e61..8bd3e71 100644
--- a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp
+++ b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp
@@ -40,8 +40,8 @@
   provider->CreateFaceDetection(mojo::MakeRequest(&face_service_),
                                 std::move(face_detector_options));
 
-  face_service_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-      &FaceDetector::OnFaceServiceConnectionError, WrapWeakPersistent(this))));
+  face_service_.set_connection_error_handler(WTF::Bind(
+      &FaceDetector::OnFaceServiceConnectionError, WrapWeakPersistent(this)));
 }
 
 ScriptPromise FaceDetector::DoDetect(ScriptPromiseResolver* resolver,
@@ -53,10 +53,10 @@
     return promise;
   }
   face_service_requests_.insert(resolver);
-  face_service_->Detect(std::move(bitmap),
-                        ConvertToBaseCallback(WTF::Bind(
-                            &FaceDetector::OnDetectFaces, WrapPersistent(this),
-                            WrapPersistent(resolver))));
+  face_service_->Detect(
+      std::move(bitmap),
+      WTF::Bind(&FaceDetector::OnDetectFaces, WrapPersistent(this),
+                WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp
index 47d9be0..5457605 100644
--- a/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp
+++ b/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp
@@ -25,8 +25,8 @@
     interface_provider->GetInterface(std::move(request));
   }
 
-  text_service_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-      &TextDetector::OnTextServiceConnectionError, WrapWeakPersistent(this))));
+  text_service_.set_connection_error_handler(WTF::Bind(
+      &TextDetector::OnTextServiceConnectionError, WrapWeakPersistent(this)));
 }
 
 ScriptPromise TextDetector::DoDetect(ScriptPromiseResolver* resolver,
@@ -38,10 +38,10 @@
     return promise;
   }
   text_service_requests_.insert(resolver);
-  text_service_->Detect(std::move(bitmap),
-                        ConvertToBaseCallback(WTF::Bind(
-                            &TextDetector::OnDetectText, WrapPersistent(this),
-                            WrapPersistent(resolver))));
+  text_service_->Detect(
+      std::move(bitmap),
+      WTF::Bind(&TextDetector::OnDetectText, WrapPersistent(this),
+                WrapPersistent(resolver)));
   return promise;
 }
 
diff --git a/third_party/WebKit/Source/modules/vibration/VibrationController.cpp b/third_party/WebKit/Source/modules/vibration/VibrationController.cpp
index 1ffe247..13ac11a 100644
--- a/third_party/WebKit/Source/modules/vibration/VibrationController.cpp
+++ b/third_party/WebKit/Source/modules/vibration/VibrationController.cpp
@@ -130,8 +130,7 @@
     is_calling_vibrate_ = true;
     vibration_manager_->Vibrate(
         pattern_[0],
-        ConvertToBaseCallback(
-            WTF::Bind(&VibrationController::DidVibrate, WrapPersistent(this))));
+        WTF::Bind(&VibrationController::DidVibrate, WrapPersistent(this)));
   }
 }
 
@@ -162,8 +161,8 @@
 
   if (is_running_ && !is_calling_cancel_ && vibration_manager_) {
     is_calling_cancel_ = true;
-    vibration_manager_->Cancel(ConvertToBaseCallback(
-        WTF::Bind(&VibrationController::DidCancel, WrapPersistent(this))));
+    vibration_manager_->Cancel(
+        WTF::Bind(&VibrationController::DidCancel, WrapPersistent(this)));
   }
 
   is_running_ = false;
diff --git a/third_party/WebKit/Source/modules/vr/VRController.cpp b/third_party/WebKit/Source/modules/vr/VRController.cpp
index 21a9884..e158cc5b 100644
--- a/third_party/WebKit/Source/modules/vr/VRController.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRController.cpp
@@ -22,14 +22,14 @@
       binding_(this) {
   navigator_vr->GetDocument()->GetFrame()->GetInterfaceProvider().GetInterface(
       mojo::MakeRequest(&service_));
-  service_.set_connection_error_handler(ConvertToBaseCallback(
-      WTF::Bind(&VRController::Dispose, WrapWeakPersistent(this))));
+  service_.set_connection_error_handler(
+      WTF::Bind(&VRController::Dispose, WrapWeakPersistent(this)));
 
   device::mojom::blink::VRServiceClientPtr client;
   binding_.Bind(mojo::MakeRequest(&client));
-  service_->SetClient(std::move(client), ConvertToBaseCallback(WTF::Bind(
-                                             &VRController::OnDisplaysSynced,
-                                             WrapPersistent(this))));
+  service_->SetClient(
+      std::move(client),
+      WTF::Bind(&VRController::OnDisplaysSynced, WrapPersistent(this)));
 }
 
 VRController::~VRController() {}
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
index 18530631..4a1ed3d 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -95,8 +95,6 @@
     : PausableObject(navigator_vr->GetDocument()),
       navigator_vr_(navigator_vr),
       capabilities_(new VRDisplayCapabilities()),
-      eye_parameters_left_(new VREyeParameters()),
-      eye_parameters_right_(new VREyeParameters()),
       magic_window_provider_(std::move(magic_window_provider)),
       display_(std::move(display)),
       submit_frame_client_binding_(this),
@@ -127,15 +125,24 @@
   capabilities_->SetCanPresent(display->capabilities->canPresent);
   capabilities_->SetMaxLayers(display->capabilities->canPresent ? 1 : 0);
 
-  // Ignore non presenting delegate
-  bool is_valid = display->leftEye->renderWidth > 0;
+  // Clear eye parameters to prevent them from getting stale.
+  eye_parameters_left_.Clear();
+  eye_parameters_right_.Clear();
+
+  bool is_valid = false;
+  if (capabilities_->canPresent()) {
+    DCHECK_GT(display->leftEye->renderWidth, 0u);
+    is_valid = true;
+
+    eye_parameters_left_ = new VREyeParameters(display->leftEye);
+    eye_parameters_right_ = new VREyeParameters(display->rightEye);
+  }
+
   bool need_on_present_change = false;
   if (is_presenting_ && is_valid && !is_valid_device_for_presenting_) {
     need_on_present_change = true;
   }
   is_valid_device_for_presenting_ = is_valid;
-  eye_parameters_left_->Update(display->leftEye);
-  eye_parameters_right_->Update(display->rightEye);
 
   if (!display->stageParameters.is_null()) {
     if (!stage_parameters_)
@@ -176,6 +183,9 @@
 }
 
 VREyeParameters* VRDisplay::getEyeParameters(const String& which_eye) {
+  if (!capabilities_->canPresent())
+    return nullptr;
+
   switch (StringToVREye(which_eye)) {
     case kVREyeLeft:
       return eye_parameters_left_;
@@ -207,8 +217,8 @@
     return;
 
   if (!is_presenting_) {
-    magic_window_provider_->GetPose(ConvertToBaseCallback(
-        WTF::Bind(&VRDisplay::OnMagicWindowPose, WrapWeakPersistent(this))));
+    magic_window_provider_->GetPose(
+        WTF::Bind(&VRDisplay::OnMagicWindowPose, WrapWeakPersistent(this)));
     pending_vsync_ = true;
     pending_vsync_id_ =
         doc->RequestAnimationFrame(new VRDisplayFrameRequestCallback(this));
@@ -238,8 +248,8 @@
   // all, there won't be future frames.
 
   pending_vsync_ = true;
-  vr_presentation_provider_->GetVSync(ConvertToBaseCallback(
-      WTF::Bind(&VRDisplay::OnPresentingVSync, WrapWeakPersistent(this))));
+  vr_presentation_provider_->GetVSync(
+      WTF::Bind(&VRDisplay::OnPresentingVSync, WrapWeakPersistent(this)));
 
   DVLOG(2) << __FUNCTION__ << " done: pending_vsync_=" << pending_vsync_;
 }
@@ -446,12 +456,10 @@
     display_->RequestPresent(
         std::move(submit_frame_client),
         mojo::MakeRequest(&vr_presentation_provider_),
-        ConvertToBaseCallback(
-            WTF::Bind(&VRDisplay::OnPresentComplete, WrapPersistent(this))));
+        WTF::Bind(&VRDisplay::OnPresentComplete, WrapPersistent(this)));
     vr_presentation_provider_.set_connection_error_handler(
-        ConvertToBaseCallback(
-            WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError,
-                      WrapWeakPersistent(this))));
+        WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError,
+                  WrapWeakPersistent(this)));
     pending_present_request_ = true;
   } else {
     UpdateLayerBounds();
diff --git a/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp b/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp
index 3cb14260..a5c21e4 100644
--- a/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp
+++ b/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp
@@ -6,15 +6,12 @@
 
 namespace blink {
 
-VREyeParameters::VREyeParameters() {
+VREyeParameters::VREyeParameters(
+    const device::mojom::blink::VREyeParametersPtr& eye_parameters) {
+  // TODO(offenwanger): Convert this into initializers.
   offset_ = DOMFloat32Array::Create(3);
   field_of_view_ = new VRFieldOfView();
-  render_width_ = 0;
-  render_height_ = 0;
-}
 
-void VREyeParameters::Update(
-    const device::mojom::blink::VREyeParametersPtr& eye_parameters) {
   offset_->Data()[0] = eye_parameters->offset[0];
   offset_->Data()[1] = eye_parameters->offset[1];
   offset_->Data()[2] = eye_parameters->offset[2];
diff --git a/third_party/WebKit/Source/modules/vr/VREyeParameters.h b/third_party/WebKit/Source/modules/vr/VREyeParameters.h
index b63cd9f8..1eb901c 100644
--- a/third_party/WebKit/Source/modules/vr/VREyeParameters.h
+++ b/third_party/WebKit/Source/modules/vr/VREyeParameters.h
@@ -19,15 +19,13 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  VREyeParameters();
+  explicit VREyeParameters(const device::mojom::blink::VREyeParametersPtr&);
 
   DOMFloat32Array* offset() const { return offset_; }
   VRFieldOfView* FieldOfView() const { return field_of_view_; }
   unsigned long renderWidth() const { return render_width_; }
   unsigned long renderHeight() const { return render_height_; }
 
-  void Update(const device::mojom::blink::VREyeParametersPtr&);
-
   virtual void Trace(blink::Visitor*);
 
  private:
diff --git a/third_party/WebKit/Source/modules/vr/VRFrameData.cpp b/third_party/WebKit/Source/modules/vr/VRFrameData.cpp
index 083dbdc..217cde8 100644
--- a/third_party/WebKit/Source/modules/vr/VRFrameData.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRFrameData.cpp
@@ -180,23 +180,36 @@
                          VREyeParameters* right_eye,
                          float depth_near,
                          float depth_far) {
+  VRFieldOfView* fov_left;
+  VRFieldOfView* fov_right;
+  if (left_eye && right_eye) {
+    fov_left = left_eye->FieldOfView();
+    fov_right = right_eye->FieldOfView();
+  } else {
+    DCHECK(!left_eye && !right_eye);
+    // TODO(offenwanger): Look into making the projection matrixes null instead
+    // of hard coding values. May break some apps.
+    fov_left = fov_right = new VRFieldOfView(45, 45, 45, 45);
+  }
+
   // Build the projection matrices
-  ProjectionFromFieldOfView(left_projection_matrix_, left_eye->FieldOfView(),
-                            depth_near, depth_far);
-  ProjectionFromFieldOfView(right_projection_matrix_, right_eye->FieldOfView(),
-                            depth_near, depth_far);
+  ProjectionFromFieldOfView(left_projection_matrix_, fov_left, depth_near,
+                            depth_far);
+  ProjectionFromFieldOfView(right_projection_matrix_, fov_right, depth_near,
+                            depth_far);
 
   // Build the view matrices
   MatrixfromRotationTranslation(left_view_matrix_, pose->orientation,
                                 pose->position);
-  MatrixTranslate(left_view_matrix_, left_eye->offset());
-  if (!MatrixInvert(left_view_matrix_))
-    return false;
-
   MatrixfromRotationTranslation(right_view_matrix_, pose->orientation,
                                 pose->position);
-  MatrixTranslate(right_view_matrix_, right_eye->offset());
-  if (!MatrixInvert(right_view_matrix_))
+
+  if (left_eye && right_eye) {
+    MatrixTranslate(left_view_matrix_, left_eye->offset());
+    MatrixTranslate(right_view_matrix_, right_eye->offset());
+  }
+
+  if (!MatrixInvert(left_view_matrix_) || !MatrixInvert(right_view_matrix_))
     return false;
 
   // Set the pose
diff --git a/third_party/WebKit/Source/modules/vr/latest/VR.cpp b/third_party/WebKit/Source/modules/vr/latest/VR.cpp
index eaf0888..bd1bcf5 100644
--- a/third_party/WebKit/Source/modules/vr/latest/VR.cpp
+++ b/third_party/WebKit/Source/modules/vr/latest/VR.cpp
@@ -37,7 +37,7 @@
       binding_(this) {
   frame.GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_));
   service_.set_connection_error_handler(
-      ConvertToBaseCallback(WTF::Bind(&VR::Dispose, WrapWeakPersistent(this))));
+      WTF::Bind(&VR::Dispose, WrapWeakPersistent(this)));
 
   device::mojom::blink::VRServiceClientPtr client;
   binding_.Bind(mojo::MakeRequest(&client));
@@ -45,8 +45,7 @@
   // Setting the client kicks off a request for the details of any connected
   // VRDevices.
   service_->SetClient(std::move(client),
-                      ConvertToBaseCallback(WTF::Bind(&VR::OnDevicesSynced,
-                                                      WrapPersistent(this))));
+                      WTF::Bind(&VR::OnDevicesSynced, WrapPersistent(this)));
 }
 
 ExecutionContext* VR::GetExecutionContext() const {
diff --git a/third_party/WebKit/Source/modules/vr/latest/VRFrameProvider.cpp b/third_party/WebKit/Source/modules/vr/latest/VRFrameProvider.cpp
index 0ef8f23..c7ae964 100644
--- a/third_party/WebKit/Source/modules/vr/latest/VRFrameProvider.cpp
+++ b/third_party/WebKit/Source/modules/vr/latest/VRFrameProvider.cpp
@@ -173,8 +173,8 @@
 
   pending_exclusive_vsync_ = true;
 
-  device_->vrMagicWindowProviderPtr()->GetPose(ConvertToBaseCallback(WTF::Bind(
-      &VRFrameProvider::OnNonExclusivePose, WrapWeakPersistent(this))));
+  device_->vrMagicWindowProviderPtr()->GetPose(WTF::Bind(
+      &VRFrameProvider::OnNonExclusivePose, WrapWeakPersistent(this)));
   doc->RequestAnimationFrame(new VRFrameProviderRequestCallback(this));
 }
 
@@ -192,8 +192,8 @@
 
   pending_non_exclusive_vsync_ = true;
 
-  device_->vrMagicWindowProviderPtr()->GetPose(ConvertToBaseCallback(WTF::Bind(
-      &VRFrameProvider::OnNonExclusivePose, WrapWeakPersistent(this))));
+  device_->vrMagicWindowProviderPtr()->GetPose(WTF::Bind(
+      &VRFrameProvider::OnNonExclusivePose, WrapWeakPersistent(this)));
   doc->RequestAnimationFrame(new VRFrameProviderRequestCallback(this));
 }
 
diff --git a/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp b/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp
index 48553b4..becdbf0b 100644
--- a/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp
@@ -73,7 +73,7 @@
       audio_data->Data(), audio_data->ByteLength(), false, sample_rate);
 
   // Decoding is finished, but we need to do the callbacks on the main thread.
-  // A reference to |*bus| is retained by WTF::Function and will be removed
+  // A reference to |*bus| is retained by base::OnceCallback and will be removed
   // after notifyComplete() is done.
   //
   // We also want to avoid notifying the main thread if AudioContext does not
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp
index b7026c54..4e5e058 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp
@@ -69,8 +69,7 @@
     Document* document = page_->GetFrame().GetDocument();
     thread->Start(
         std::make_unique<GlobalScopeCreationParams>(
-            document->Url(), document->UserAgent(), "" /* source_code */,
-            nullptr /* cached_meta_data */,
+            document->Url(), document->UserAgent(),
             nullptr /* content_security_policy_parsed_headers */,
             document->GetReferrerPolicy(), document->GetSecurityOrigin(),
             nullptr /* worker_clients */, document->AddressSpace(),
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletThreadTest.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletThreadTest.cpp
index 007a660..a8907e8 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletThreadTest.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletThreadTest.cpp
@@ -53,8 +53,7 @@
     Document* document = page_->GetFrame().GetDocument();
     thread->Start(
         std::make_unique<GlobalScopeCreationParams>(
-            document->Url(), document->UserAgent(), "" /* source_code */,
-            nullptr /* cached_meta_data */,
+            document->Url(), document->UserAgent(),
             nullptr /* content_security_policy_parsed_headers */,
             document->GetReferrerPolicy(), document->GetSecurityOrigin(),
             nullptr /* worker_clients */, document->AddressSpace(),
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseTracker.h b/third_party/WebKit/Source/modules/webdatabase/DatabaseTracker.h
index 522cd6b..8961837 100644
--- a/third_party/WebKit/Source/modules/webdatabase/DatabaseTracker.h
+++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseTracker.h
@@ -31,11 +31,11 @@
 
 #include <memory>
 
+#include "base/callback.h"
 #include "base/macros.h"
 #include "modules/ModulesExport.h"
 #include "modules/webdatabase/DatabaseError.h"
 #include "platform/heap/Handle.h"
-#include "platform/wtf/Functional.h"
 #include "platform/wtf/HashMap.h"
 #include "platform/wtf/HashSet.h"
 #include "platform/wtf/ThreadingPrimitives.h"
@@ -79,7 +79,7 @@
 
   void CloseDatabasesImmediately(const SecurityOrigin*, const String& name);
 
-  using DatabaseCallback = WTF::RepeatingFunction<void(Database*)>;
+  using DatabaseCallback = base::RepeatingCallback<void(Database*)>;
   void ForEachOpenDatabaseInPage(Page*, DatabaseCallback);
 
   void PrepareToOpenDatabase(Database*);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.cpp b/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.cpp
index d5132299..52294cc 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.cpp
@@ -107,7 +107,7 @@
   auto callback = WTF::Bind(&WebGLGetBufferSubDataAsyncCallback::Resolve,
                             WrapPersistent(callback_object));
   context->GetDrawingBuffer()->ContextProvider()->SignalQuery(
-      query_id, ConvertToBaseCallback(std::move(callback)));
+      query_id, std::move(callback));
 
   return promise;
 }
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index d5915d7..1170edc 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -1282,8 +1282,8 @@
 
   extensions_util_.reset();
 
-  WTF::RepeatingClosure null_closure;
-  WTF::RepeatingFunction<void(const char*, int32_t)> null_function;
+  base::RepeatingClosure null_closure;
+  base::RepeatingCallback<void(const char*, int32_t)> null_function;
   GetDrawingBuffer()->ContextProvider()->SetLostContextCallback(
       std::move(null_closure));
   GetDrawingBuffer()->ContextProvider()->SetErrorMessageCallback(
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp b/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp
index 669d826..58e9df7 100644
--- a/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp
+++ b/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp
@@ -46,8 +46,8 @@
       CreateMidiPermissionDescriptor(options_.hasSysex() && options_.sysex()),
       GetExecutionContext()->GetSecurityOrigin(),
       Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
-      ConvertToBaseCallback(WTF::Bind(
-          &MIDIAccessInitializer::OnPermissionsUpdated, WrapPersistent(this))));
+      WTF::Bind(&MIDIAccessInitializer::OnPermissionsUpdated,
+                WrapPersistent(this)));
 
   return promise;
 }
diff --git a/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp b/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp
index 8f67085..7a02d5fa 100644
--- a/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp
+++ b/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp
@@ -140,8 +140,8 @@
     }
 
     frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_));
-    service_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-        &NavigatorShare::OnConnectionError, WrapWeakPersistent(this))));
+    service_.set_connection_error_handler(WTF::Bind(
+        &NavigatorShare::OnConnectionError, WrapWeakPersistent(this)));
     DCHECK(service_);
   }
 
@@ -150,11 +150,10 @@
   clients_.insert(client);
   ScriptPromise promise = resolver->Promise();
 
-  service_->Share(share_data.hasTitle() ? share_data.title() : g_empty_string,
-                  share_data.hasText() ? share_data.text() : g_empty_string,
-                  full_url,
-                  ConvertToBaseCallback(WTF::Bind(&ShareClientImpl::Callback,
-                                                  WrapPersistent(client))));
+  service_->Share(
+      share_data.hasTitle() ? share_data.title() : g_empty_string,
+      share_data.hasText() ? share_data.text() : g_empty_string, full_url,
+      WTF::Bind(&ShareClientImpl::Callback, WrapPersistent(client)));
 
   return promise;
 }
diff --git a/third_party/WebKit/Source/modules/websockets/WebSocketHandleImpl.cpp b/third_party/WebKit/Source/modules/websockets/WebSocketHandleImpl.cpp
index ff9befb..4832a715 100644
--- a/third_party/WebKit/Source/modules/websockets/WebSocketHandleImpl.cpp
+++ b/third_party/WebKit/Source/modules/websockets/WebSocketHandleImpl.cpp
@@ -40,9 +40,8 @@
 
   DCHECK(!websocket_);
   websocket_ = std::move(websocket);
-  websocket_.set_connection_error_with_reason_handler(
-      ConvertToBaseCallback(WTF::Bind(&WebSocketHandleImpl::OnConnectionError,
-                                      WTF::Unretained(this))));
+  websocket_.set_connection_error_with_reason_handler(WTF::Bind(
+      &WebSocketHandleImpl::OnConnectionError, WTF::Unretained(this)));
 }
 
 void WebSocketHandleImpl::Connect(const KURL& url,
diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp
index 0d3ff48..5a467cd 100644
--- a/third_party/WebKit/Source/modules/webusb/USB.cpp
+++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
@@ -97,9 +97,8 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   device_manager_requests_.insert(resolver);
   device_manager_->GetDevices(
-      nullptr,
-      ConvertToBaseCallback(WTF::Bind(&USB::OnGetDevices, WrapPersistent(this),
-                                      WrapPersistent(resolver))));
+      nullptr, WTF::Bind(&USB::OnGetDevices, WrapPersistent(this),
+                         WrapPersistent(resolver)));
   return resolver->Promise();
 }
 
@@ -125,9 +124,8 @@
   if (!chooser_service_) {
     GetFrame()->GetInterfaceProvider().GetInterface(
         mojo::MakeRequest(&chooser_service_));
-    chooser_service_.set_connection_error_handler(
-        ConvertToBaseCallback(WTF::Bind(&USB::OnChooserServiceConnectionError,
-                                        WrapWeakPersistent(this))));
+    chooser_service_.set_connection_error_handler(WTF::Bind(
+        &USB::OnChooserServiceConnectionError, WrapWeakPersistent(this)));
   }
 
   if (!Frame::ConsumeTransientUserActivation(frame)) {
@@ -148,9 +146,8 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   chooser_service_requests_.insert(resolver);
   chooser_service_->GetPermission(
-      std::move(filters), ConvertToBaseCallback(WTF::Bind(
-                              &USB::OnGetPermission, WrapPersistent(this),
-                              WrapPersistent(resolver))));
+      std::move(filters), WTF::Bind(&USB::OnGetPermission, WrapPersistent(this),
+                                    WrapPersistent(resolver)));
   return resolver->Promise();
 }
 
@@ -272,8 +269,8 @@
   DCHECK(GetFrame());
   GetFrame()->GetInterfaceProvider().GetInterface(
       mojo::MakeRequest(&device_manager_));
-  device_manager_.set_connection_error_handler(ConvertToBaseCallback(WTF::Bind(
-      &USB::OnDeviceManagerConnectionError, WrapWeakPersistent(this))));
+  device_manager_.set_connection_error_handler(WTF::Bind(
+      &USB::OnDeviceManagerConnectionError, WrapWeakPersistent(this)));
 
   DCHECK(!client_binding_.is_bound());
 
diff --git a/third_party/WebKit/Source/modules/webusb/USBDevice.cpp b/third_party/WebKit/Source/modules/webusb/USBDevice.cpp
index c56087a..db5be323 100644
--- a/third_party/WebKit/Source/modules/webusb/USBDevice.cpp
+++ b/third_party/WebKit/Source/modules/webusb/USBDevice.cpp
@@ -112,8 +112,8 @@
       device_state_change_in_progress_(false),
       configuration_index_(-1) {
   if (device_) {
-    device_.set_connection_error_handler(ConvertToBaseCallback(
-        WTF::Bind(&USBDevice::OnConnectionError, WrapWeakPersistent(this))));
+    device_.set_connection_error_handler(
+        WTF::Bind(&USBDevice::OnConnectionError, WrapWeakPersistent(this)));
   }
   int configuration_index = FindConfigurationIndex(Info().active_configuration);
   if (configuration_index != -1)
@@ -160,9 +160,8 @@
     } else {
       device_state_change_in_progress_ = true;
       device_requests_.insert(resolver);
-      device_->Open(ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncOpen,
-                                                    WrapPersistent(this),
-                                                    WrapPersistent(resolver))));
+      device_->Open(WTF::Bind(&USBDevice::AsyncOpen, WrapPersistent(this),
+                              WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -177,9 +176,8 @@
     } else {
       device_state_change_in_progress_ = true;
       device_requests_.insert(resolver);
-      device_->Close(ConvertToBaseCallback(
-          WTF::Bind(&USBDevice::AsyncClose, WrapPersistent(this),
-                    WrapPersistent(resolver))));
+      device_->Close(WTF::Bind(&USBDevice::AsyncClose, WrapPersistent(this),
+                               WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -206,9 +204,9 @@
         device_requests_.insert(resolver);
         device_->SetConfiguration(
             configuration_value,
-            ConvertToBaseCallback(WTF::Bind(
-                &USBDevice::AsyncSelectConfiguration, WrapPersistent(this),
-                configuration_index, WrapPersistent(resolver))));
+            WTF::Bind(&USBDevice::AsyncSelectConfiguration,
+                      WrapPersistent(this), configuration_index,
+                      WrapPersistent(resolver)));
       }
     }
   }
@@ -234,9 +232,8 @@
       device_requests_.insert(resolver);
       device_->ClaimInterface(
           interface_number,
-          ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncClaimInterface,
-                                          WrapPersistent(this), interface_index,
-                                          WrapPersistent(resolver))));
+          WTF::Bind(&USBDevice::AsyncClaimInterface, WrapPersistent(this),
+                    interface_index, WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -266,9 +263,8 @@
       device_requests_.insert(resolver);
       device_->ReleaseInterface(
           interface_number,
-          ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncReleaseInterface,
-                                          WrapPersistent(this), interface_index,
-                                          WrapPersistent(resolver))));
+          WTF::Bind(&USBDevice::AsyncReleaseInterface, WrapPersistent(this),
+                    interface_index, WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -298,9 +294,9 @@
       device_requests_.insert(resolver);
       device_->SetInterfaceAlternateSetting(
           interface_number, alternate_setting,
-          ConvertToBaseCallback(WTF::Bind(
-              &USBDevice::AsyncSelectAlternateInterface, WrapPersistent(this),
-              interface_number, alternate_setting, WrapPersistent(resolver))));
+          WTF::Bind(&USBDevice::AsyncSelectAlternateInterface,
+                    WrapPersistent(this), interface_number, alternate_setting,
+                    WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -318,9 +314,8 @@
       device_requests_.insert(resolver);
       device_->ControlTransferIn(
           std::move(parameters), length, 0,
-          ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncControlTransferIn,
-                                          WrapPersistent(this),
-                                          WrapPersistent(resolver))));
+          WTF::Bind(&USBDevice::AsyncControlTransferIn, WrapPersistent(this),
+                    WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -337,9 +332,8 @@
       device_requests_.insert(resolver);
       device_->ControlTransferOut(
           std::move(parameters), Vector<uint8_t>(), 0,
-          ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncControlTransferOut,
-                                          WrapPersistent(this), 0,
-                                          WrapPersistent(resolver))));
+          WTF::Bind(&USBDevice::AsyncControlTransferOut, WrapPersistent(this),
+                    0, WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -359,9 +353,8 @@
       device_requests_.insert(resolver);
       device_->ControlTransferOut(
           std::move(parameters), buffer, 0,
-          ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncControlTransferOut,
-                                          WrapPersistent(this), transfer_length,
-                                          WrapPersistent(resolver))));
+          WTF::Bind(&USBDevice::AsyncControlTransferOut, WrapPersistent(this),
+                    transfer_length, WrapPersistent(resolver)));
     }
   }
   return promise;
@@ -374,10 +367,9 @@
   ScriptPromise promise = resolver->Promise();
   if (EnsureEndpointAvailable(direction == "in", endpoint_number, resolver)) {
     device_requests_.insert(resolver);
-    device_->ClearHalt(endpoint_number,
-                       ConvertToBaseCallback(WTF::Bind(
-                           &USBDevice::AsyncClearHalt, WrapPersistent(this),
-                           WrapPersistent(resolver))));
+    device_->ClearHalt(endpoint_number, WTF::Bind(&USBDevice::AsyncClearHalt,
+                                                  WrapPersistent(this),
+                                                  WrapPersistent(resolver)));
   }
   return promise;
 }
@@ -391,9 +383,8 @@
     device_requests_.insert(resolver);
     device_->GenericTransferIn(
         endpoint_number, length, 0,
-        ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncTransferIn,
-                                        WrapPersistent(this),
-                                        WrapPersistent(resolver))));
+        WTF::Bind(&USBDevice::AsyncTransferIn, WrapPersistent(this),
+                  WrapPersistent(resolver)));
   }
   return promise;
 }
@@ -409,9 +400,8 @@
     device_requests_.insert(resolver);
     device_->GenericTransferOut(
         endpoint_number, buffer, 0,
-        ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncTransferOut,
-                                        WrapPersistent(this), transfer_length,
-                                        WrapPersistent(resolver))));
+        WTF::Bind(&USBDevice::AsyncTransferOut, WrapPersistent(this),
+                  transfer_length, WrapPersistent(resolver)));
   }
   return promise;
 }
@@ -426,9 +416,8 @@
     device_requests_.insert(resolver);
     device_->IsochronousTransferIn(
         endpoint_number, packet_lengths, 0,
-        ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncIsochronousTransferIn,
-                                        WrapPersistent(this),
-                                        WrapPersistent(resolver))));
+        WTF::Bind(&USBDevice::AsyncIsochronousTransferIn, WrapPersistent(this),
+                  WrapPersistent(resolver)));
   }
   return promise;
 }
@@ -444,9 +433,8 @@
     device_requests_.insert(resolver);
     device_->IsochronousTransferOut(
         endpoint_number, ConvertBufferSource(data), packet_lengths, 0,
-        ConvertToBaseCallback(WTF::Bind(&USBDevice::AsyncIsochronousTransferOut,
-                                        WrapPersistent(this),
-                                        WrapPersistent(resolver))));
+        WTF::Bind(&USBDevice::AsyncIsochronousTransferOut, WrapPersistent(this),
+                  WrapPersistent(resolver)));
   }
   return promise;
 }
@@ -459,9 +447,8 @@
       resolver->Reject(DOMException::Create(kInvalidStateError, kOpenRequired));
     } else {
       device_requests_.insert(resolver);
-      device_->Reset(ConvertToBaseCallback(
-          WTF::Bind(&USBDevice::AsyncReset, WrapPersistent(this),
-                    WrapPersistent(resolver))));
+      device_->Reset(WTF::Bind(&USBDevice::AsyncReset, WrapPersistent(this),
+                               WrapPersistent(resolver)));
     }
   }
   return promise;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index 45a46ba4..25fd13f 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -337,7 +337,6 @@
     "WebMouseEvent.cpp",
     "WebMouseWheelEvent.cpp",
     "WebPointerEvent.cpp",
-    "WebScheduler.cpp",
     "WebTaskRunner.cpp",
     "WebTaskRunner.h",
     "WebTextInputInfo.cpp",
@@ -584,7 +583,6 @@
     "exported/WebImageGenerator.cpp",
     "exported/WebInputEvent.cpp",
     "exported/WebMediaConstraints.cpp",
-    "exported/WebMediaDeviceInfo.cpp",
     "exported/WebMediaPlayerClient.cpp",
     "exported/WebMediaPlayerEncryptedMediaClient.cpp",
     "exported/WebMediaPlayerSource.cpp",
diff --git a/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp b/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp
index 79198c2..bcfaa7e 100644
--- a/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp
+++ b/third_party/WebKit/Source/platform/ContentSettingCallbacks.cpp
@@ -36,14 +36,14 @@
 namespace blink {
 
 std::unique_ptr<ContentSettingCallbacks> ContentSettingCallbacks::Create(
-    WTF::Closure allowed,
-    WTF::Closure denied) {
+    base::OnceClosure allowed,
+    base::OnceClosure denied) {
   return WTF::WrapUnique(
       new ContentSettingCallbacks(std::move(allowed), std::move(denied)));
 }
 
-ContentSettingCallbacks::ContentSettingCallbacks(WTF::Closure allowed,
-                                                 WTF::Closure denied)
+ContentSettingCallbacks::ContentSettingCallbacks(base::OnceClosure allowed,
+                                                 base::OnceClosure denied)
     : allowed_(std::move(allowed)), denied_(std::move(denied)) {}
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/ContentSettingCallbacks.h b/third_party/WebKit/Source/platform/ContentSettingCallbacks.h
index 86d168f5..561a207 100644
--- a/third_party/WebKit/Source/platform/ContentSettingCallbacks.h
+++ b/third_party/WebKit/Source/platform/ContentSettingCallbacks.h
@@ -18,18 +18,19 @@
   WTF_MAKE_NONCOPYABLE(ContentSettingCallbacks);
 
  public:
-  static std::unique_ptr<ContentSettingCallbacks> Create(WTF::Closure allowed,
-                                                         WTF::Closure denied);
+  static std::unique_ptr<ContentSettingCallbacks> Create(
+      base::OnceClosure allowed,
+      base::OnceClosure denied);
   virtual ~ContentSettingCallbacks() {}
 
   void OnAllowed() { std::move(allowed_).Run(); }
   void OnDenied() { std::move(denied_).Run(); }
 
  private:
-  ContentSettingCallbacks(WTF::Closure allowed, WTF::Closure denied);
+  ContentSettingCallbacks(base::OnceClosure allowed, base::OnceClosure denied);
 
-  WTF::Closure allowed_;
-  WTF::Closure denied_;
+  base::OnceClosure allowed_;
+  base::OnceClosure denied_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/WebPointerEvent.cpp b/third_party/WebKit/Source/platform/WebPointerEvent.cpp
index a32fab9..8531f54 100644
--- a/third_party/WebKit/Source/platform/WebPointerEvent.cpp
+++ b/third_party/WebKit/Source/platform/WebPointerEvent.cpp
@@ -34,9 +34,9 @@
                                  const WebTouchPoint& touch_point)
     : WebInputEvent(sizeof(WebPointerEvent)),
       WebPointerProperties(touch_point),
-      // TODO(crbug.com/731725): This mapping needs a times by 2.
-      width(touch_point.radius_x),
-      height(touch_point.radius_y) {
+      scroll_capable(true),
+      width(touch_point.radius_x * 2.f),
+      height(touch_point.radius_y * 2.f) {
   // WebInutEvent attributes
   SetFrameScale(touch_event.FrameScale());
   SetFrameTranslate(touch_event.FrameTranslate());
@@ -56,6 +56,7 @@
                                  const WebMouseEvent& mouse_event)
     : WebInputEvent(sizeof(WebPointerEvent)),
       WebPointerProperties(mouse_event),
+      scroll_capable(false),
       width(1),
       height(1) {
   DCHECK_GE(type, WebInputEvent::kPointerTypeFirst);
@@ -67,6 +68,14 @@
   SetModifiers(mouse_event.GetModifiers());
 }
 
+WebPointerEvent::WebPointerEvent(WebPointerProperties::PointerType type,
+                                 double time_stamp_seconds)
+    : WebPointerEvent() {
+  pointer_type = type;
+  SetTimeStampSeconds(time_stamp_seconds);
+  SetType(WebInputEvent::Type::kPointerCausedUaAction);
+}
+
 WebPointerEvent WebPointerEvent::WebPointerEventInRootFrame() const {
   WebPointerEvent transformed_event = *this;
   transformed_event.width /= frame_scale_;
diff --git a/third_party/WebKit/Source/platform/WebScheduler.cpp b/third_party/WebKit/Source/platform/WebScheduler.cpp
deleted file mode 100644
index 53e3057..0000000
--- a/third_party/WebKit/Source/platform/WebScheduler.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "platform/scheduler/child/web_scheduler.h"
-
-#include "platform/WebFrameScheduler.h"
-#include "platform/wtf/Assertions.h"
-#include "platform/wtf/Noncopyable.h"
-#include "public/platform/WebTraceLocation.h"
-
-namespace blink {
-
-namespace {
-
-class IdleTaskRunner : public WebThread::IdleTask {
-  USING_FAST_MALLOC(IdleTaskRunner);
-  WTF_MAKE_NONCOPYABLE(IdleTaskRunner);
-
- public:
-  explicit IdleTaskRunner(WebScheduler::IdleTask task)
-      : task_(std::move(task)) {}
-
-  ~IdleTaskRunner() override {}
-
-  // WebThread::IdleTask implementation.
-  void Run(double deadline_seconds) override {
-    std::move(task_).Run(deadline_seconds);
-  }
-
- private:
-  WebScheduler::IdleTask task_;
-};
-
-}  // namespace
-
-void WebScheduler::PostIdleTask(const WebTraceLocation& location,
-                                IdleTask idle_task) {
-  PostIdleTask(location, new IdleTaskRunner(std::move(idle_task)));
-}
-
-void WebScheduler::PostNonNestableIdleTask(const WebTraceLocation& location,
-                                           IdleTask idle_task) {
-  PostNonNestableIdleTask(location, new IdleTaskRunner(std::move(idle_task)));
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.cpp b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
index 5f71c87..621aacd 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.cpp
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
@@ -39,7 +39,7 @@
 
 class TaskHandle::Runner : public WTF::ThreadSafeRefCounted<Runner> {
  public:
-  explicit Runner(WTF::Closure task)
+  explicit Runner(base::OnceClosure task)
       : task_(std::move(task)), weak_ptr_factory_(this) {}
 
   base::WeakPtr<Runner> AsWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }
@@ -47,7 +47,7 @@
   bool IsActive() const { return task_ && !task_.IsCancelled(); }
 
   void Cancel() {
-    WTF::Closure task = std::move(task_);
+    base::OnceClosure task = std::move(task_);
     weak_ptr_factory_.InvalidateWeakPtrs();
   }
 
@@ -68,15 +68,15 @@
   // There is a circular reference in the example above as:
   //   foo -> m_handle -> m_runner -> m_task -> Persistent<Foo> in WTF::bind.
   // The TaskHandle parameter on run() is needed to break the circle by clearing
-  // |m_task| when the wrapped WTF::Closure is deleted.
+  // |m_task| when the wrapped base::OnceClosure is deleted.
   void Run(const TaskHandle&) {
-    WTF::Closure task = std::move(task_);
+    base::OnceClosure task = std::move(task_);
     weak_ptr_factory_.InvalidateWeakPtrs();
     std::move(task).Run();
   }
 
  private:
-  WTF::Closure task_;
+  base::OnceClosure task_;
   base::WeakPtrFactory<Runner> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(Runner);
@@ -131,14 +131,12 @@
 }
 
 void WebTaskRunner::PostTask(const WebTraceLocation& location,
-                             WTF::Closure task) {
-  DCHECK(RunsTasksInCurrentSequence());
-  PostDelayedTask(location, ConvertToBaseCallback(std::move(task)),
-                  base::TimeDelta());
+                             base::OnceClosure task) {
+  PostDelayedTask(location, std::move(task), base::TimeDelta());
 }
 
 TaskHandle WebTaskRunner::PostCancellableTask(const WebTraceLocation& location,
-                                              WTF::Closure task) {
+                                              base::OnceClosure task) {
   DCHECK(RunsTasksInCurrentSequence());
   scoped_refptr<TaskHandle::Runner> runner =
       base::AdoptRef(new TaskHandle::Runner(std::move(task)));
@@ -149,7 +147,7 @@
 
 TaskHandle WebTaskRunner::PostDelayedCancellableTask(
     const WebTraceLocation& location,
-    WTF::Closure task,
+    base::OnceClosure task,
     TimeDelta delay) {
   DCHECK(RunsTasksInCurrentSequence());
   scoped_refptr<TaskHandle::Runner> runner =
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.h b/third_party/WebKit/Source/platform/WebTaskRunner.h
index 9883ddf..8c4959a 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.h
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.h
@@ -77,15 +77,15 @@
                        TimeDelta delay);
 
   // For same-thread posting. Must be called from the associated WebThread.
-  void PostTask(const WebTraceLocation&, WTF::Closure);
+  void PostTask(const WebTraceLocation&, base::OnceClosure);
 
   // For same-thread cancellable task posting. Returns a TaskHandle object for
   // cancellation.
   WARN_UNUSED_RESULT TaskHandle PostCancellableTask(const WebTraceLocation&,
-                                                    WTF::Closure);
+                                                    base::OnceClosure);
   WARN_UNUSED_RESULT TaskHandle
   PostDelayedCancellableTask(const WebTraceLocation&,
-                             WTF::Closure,
+                             base::OnceClosure,
                              TimeDelta delay);
 
  protected:
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
index a16912e..67a78e91 100644
--- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
+++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
@@ -34,12 +34,12 @@
   static std::unique_ptr<WebThreadSupportingGC> CreateForThread(WebThread*);
   ~WebThreadSupportingGC();
 
-  void PostTask(const WebTraceLocation& location, WTF::Closure task) {
+  void PostTask(const WebTraceLocation& location, base::OnceClosure task) {
     thread_->GetWebTaskRunner()->PostTask(location, std::move(task));
   }
 
   void PostDelayedTask(const WebTraceLocation& location,
-                       WTF::Closure task,
+                       base::OnceClosure task,
                        TimeDelta delay) {
     thread_->GetWebTaskRunner()->PostDelayedTask(location, std::move(task),
                                                  delay);
diff --git a/third_party/WebKit/Source/platform/bindings/Microtask.cpp b/third_party/WebKit/Source/platform/bindings/Microtask.cpp
index fc7cc8b..d4221965 100644
--- a/third_party/WebKit/Source/platform/bindings/Microtask.cpp
+++ b/third_party/WebKit/Source/platform/bindings/Microtask.cpp
@@ -42,16 +42,16 @@
 }
 
 static void MicrotaskFunctionCallback(void* data) {
-  std::unique_ptr<WTF::Closure> task =
-      WTF::WrapUnique(static_cast<WTF::Closure*>(data));
+  std::unique_ptr<base::OnceClosure> task =
+      WTF::WrapUnique(static_cast<base::OnceClosure*>(data));
   std::move(*task).Run();
 }
 
-void Microtask::EnqueueMicrotask(WTF::Closure callback) {
+void Microtask::EnqueueMicrotask(base::OnceClosure callback) {
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
   isolate->EnqueueMicrotask(
       &MicrotaskFunctionCallback,
-      static_cast<void*>(new WTF::Closure(std::move(callback))));
+      static_cast<void*>(new base::OnceClosure(std::move(callback))));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/bindings/Microtask.h b/third_party/WebKit/Source/platform/bindings/Microtask.h
index e8e823eb..4ebde30f 100644
--- a/third_party/WebKit/Source/platform/bindings/Microtask.h
+++ b/third_party/WebKit/Source/platform/bindings/Microtask.h
@@ -70,7 +70,7 @@
   // TODO(jochen): Make all microtasks pass in the ScriptState they want to be
   // executed in. Until then, all microtasks have to keep track of their
   // ScriptState themselves.
-  static void EnqueueMicrotask(WTF::Closure);
+  static void EnqueueMicrotask(base::OnceClosure);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
index 31d64cf..d3344cf 100644
--- a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
+++ b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
@@ -62,14 +62,10 @@
     WebTaskRunner* task_runner,
     V8ContextSnapshotMode v8_context_snapshot_mode)
     : v8_context_snapshot_mode_(v8_context_snapshot_mode),
-      isolate_holder_(
-          task_runner,
-          gin::IsolateHolder::kSingleThread,
-          IsMainThread() ? gin::IsolateHolder::kDisallowAtomicsWait
-                         : gin::IsolateHolder::kAllowAtomicsWait,
-          v8_context_snapshot_mode_ == V8ContextSnapshotMode::kUseSnapshot
-              ? &startup_data_
-              : nullptr),
+      isolate_holder_(task_runner,
+                      gin::IsolateHolder::kSingleThread,
+                      IsMainThread() ? gin::IsolateHolder::kDisallowAtomicsWait
+                                     : gin::IsolateHolder::kAllowAtomicsWait),
       interface_template_map_for_v8_context_snapshot_(GetIsolate()),
       string_cache_(WTF::WrapUnique(new StringCache(GetIsolate()))),
       private_property_(V8PrivateProperty::Create()),
@@ -78,13 +74,6 @@
       is_handling_recursion_level_error_(false),
       is_reporting_exception_(false),
       runtime_call_stats_(base::DefaultTickClock::GetInstance()) {
-  // If it fails to load the snapshot file, falls back to kDontUseSnapshot mode.
-  // TODO(peria): Remove this fallback routine.
-  if (v8_context_snapshot_mode_ == V8ContextSnapshotMode::kUseSnapshot &&
-      !startup_data_.data) {
-    v8_context_snapshot_mode_ = V8ContextSnapshotMode::kDontUseSnapshot;
-  }
-
   // FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone.
   GetIsolate()->Enter();
   GetIsolate()->AddBeforeCallEnteredCallback(&BeforeCallEnteredCallback);
@@ -329,12 +318,12 @@
       templ);
 }
 
-void V8PerIsolateData::AddEndOfScopeTask(WTF::Closure task) {
+void V8PerIsolateData::AddEndOfScopeTask(base::OnceClosure task) {
   end_of_scope_tasks_.push_back(std::move(task));
 }
 
 void V8PerIsolateData::RunEndOfScopeTasks() {
-  Vector<WTF::Closure> tasks;
+  Vector<base::OnceClosure> tasks;
   tasks.swap(end_of_scope_tasks_);
   for (auto& task : tasks)
     std::move(task).Run();
diff --git a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h
index bc1d64b..b897089 100644
--- a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h
+++ b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h
@@ -185,7 +185,7 @@
   // to C++ from script, after executing a script task (e.g. callback,
   // event) or microtasks (e.g. promise). This is explicitly needed for
   // Indexed DB transactions per spec, but should in general be avoided.
-  void AddEndOfScopeTask(WTF::Closure);
+  void AddEndOfScopeTask(base::OnceClosure);
   void RunEndOfScopeTasks();
   void ClearEndOfScopeTasks();
 
@@ -300,7 +300,7 @@
   bool is_handling_recursion_level_error_;
   bool is_reporting_exception_;
 
-  Vector<WTF::Closure> end_of_scope_tasks_;
+  Vector<base::OnceClosure> end_of_scope_tasks_;
   std::unique_ptr<Data> thread_debugger_;
 
   Persistent<ActiveScriptWrappableSet> active_script_wrappables_;
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp
index f40f17b..0c90f9a2 100644
--- a/third_party/WebKit/Source/platform/exported/Platform.cpp
+++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -249,7 +249,9 @@
 }
 
 std::unique_ptr<WebRTCPeerConnectionHandler>
-Platform::CreateRTCPeerConnectionHandler(WebRTCPeerConnectionHandlerClient*) {
+Platform::CreateRTCPeerConnectionHandler(
+    WebRTCPeerConnectionHandlerClient*,
+    scoped_refptr<base::SingleThreadTaskRunner>) {
   return nullptr;
 }
 
diff --git a/third_party/WebKit/Source/platform/exported/WebMediaDeviceInfo.cpp b/third_party/WebKit/Source/platform/exported/WebMediaDeviceInfo.cpp
deleted file mode 100644
index 12e32d902..0000000
--- a/third_party/WebKit/Source/platform/exported/WebMediaDeviceInfo.cpp
+++ /dev/null
@@ -1,112 +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. ``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
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "public/platform/WebMediaDeviceInfo.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "platform/wtf/RefCounted.h"
-#include "public/platform/WebString.h"
-
-namespace blink {
-
-class WebMediaDeviceInfoPrivate final
-    : public RefCounted<WebMediaDeviceInfoPrivate> {
- public:
-  static scoped_refptr<WebMediaDeviceInfoPrivate> Create(
-      const WebString& device_id,
-      WebMediaDeviceInfo::MediaDeviceKind,
-      const WebString& label,
-      const WebString& group_id);
-
-  const WebString& DeviceId() const { return device_id_; }
-  WebMediaDeviceInfo::MediaDeviceKind Kind() const { return kind_; }
-  const WebString& Label() const { return label_; }
-  const WebString& GroupId() const { return group_id_; }
-
- private:
-  WebMediaDeviceInfoPrivate(const WebString& device_id,
-                            WebMediaDeviceInfo::MediaDeviceKind,
-                            const WebString& label,
-                            const WebString& group_id);
-
-  WebString device_id_;
-  WebMediaDeviceInfo::MediaDeviceKind kind_;
-  WebString label_;
-  WebString group_id_;
-};
-
-scoped_refptr<WebMediaDeviceInfoPrivate> WebMediaDeviceInfoPrivate::Create(
-    const WebString& device_id,
-    WebMediaDeviceInfo::MediaDeviceKind kind,
-    const WebString& label,
-    const WebString& group_id) {
-  return base::AdoptRef(
-      new WebMediaDeviceInfoPrivate(device_id, kind, label, group_id));
-}
-
-WebMediaDeviceInfoPrivate::WebMediaDeviceInfoPrivate(
-    const WebString& device_id,
-    WebMediaDeviceInfo::MediaDeviceKind kind,
-    const WebString& label,
-    const WebString& group_id)
-    : device_id_(device_id), kind_(kind), label_(label), group_id_(group_id) {}
-
-void WebMediaDeviceInfo::Assign(const WebMediaDeviceInfo& other) {
-  private_ = other.private_;
-}
-
-void WebMediaDeviceInfo::Reset() {
-  private_.Reset();
-}
-
-void WebMediaDeviceInfo::Initialize(const WebString& device_id,
-                                    WebMediaDeviceInfo::MediaDeviceKind kind,
-                                    const WebString& label,
-                                    const WebString& group_id) {
-  private_ =
-      WebMediaDeviceInfoPrivate::Create(device_id, kind, label, group_id);
-}
-
-WebString WebMediaDeviceInfo::DeviceId() const {
-  DCHECK(!private_.IsNull());
-  return private_->DeviceId();
-}
-
-WebMediaDeviceInfo::MediaDeviceKind WebMediaDeviceInfo::Kind() const {
-  DCHECK(!private_.IsNull());
-  return private_->Kind();
-}
-
-WebString WebMediaDeviceInfo::Label() const {
-  DCHECK(!private_.IsNull());
-  return private_->Label();
-}
-
-WebString WebMediaDeviceInfo::GroupId() const {
-  DCHECK(!private_.IsNull());
-  return private_->GroupId();
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
index 97766db..0590d4d 100644
--- a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
@@ -169,7 +169,6 @@
 }
 
 void WebRuntimeFeatures::EnableLoadingWithMojo(bool enable) {
-  RuntimeEnabledFeatures::SetLoadingWithMojoEnabled(enable);
 }
 
 void WebRuntimeFeatures::EnableMediaCapture(bool enable) {
@@ -209,7 +208,6 @@
 }
 
 void WebRuntimeFeatures::EnableNotificationsWithMojo(bool enable) {
-  RuntimeEnabledFeatures::SetLoadingWithMojoEnabled(enable);
 }
 
 void WebRuntimeFeatures::EnableNavigatorContentUtils(bool enable) {
diff --git a/third_party/WebKit/Source/platform/fonts/FontPlatformData.cpp b/third_party/WebKit/Source/platform/fonts/FontPlatformData.cpp
index 2eda705..d86c56a3 100644
--- a/third_party/WebKit/Source/platform/fonts/FontPlatformData.cpp
+++ b/third_party/WebKit/Source/platform/fonts/FontPlatformData.cpp
@@ -29,6 +29,7 @@
 #include "platform/text/Character.h"
 #include "platform/wtf/ByteSwap.h"
 #include "platform/wtf/HashMap.h"
+#include "platform/wtf/text/CharacterNames.h"
 #include "platform/wtf/text/StringHash.h"
 #include "platform/wtf/text/WTFString.h"
 
@@ -254,54 +255,13 @@
   return harf_buzz_face_.get();
 }
 
-static inline bool TableHasSpace(hb_face_t* face,
-                                 hb_set_t* glyphs,
-                                 hb_tag_t tag,
-                                 hb_codepoint_t space) {
-  unsigned count = hb_ot_layout_table_get_lookup_count(face, tag);
-  for (unsigned i = 0; i < count; i++) {
-    hb_ot_layout_lookup_collect_glyphs(face, tag, i, glyphs, glyphs, glyphs,
-                                       nullptr);
-    if (hb_set_has(glyphs, space))
-      return true;
-  }
-  return false;
-}
-
 bool FontPlatformData::HasSpaceInLigaturesOrKerning(
     TypesettingFeatures features) const {
   HarfBuzzFace* hb_face = GetHarfBuzzFace();
   if (!hb_face)
     return false;
 
-  hb_font_t* font =
-      hb_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
-  DCHECK(font);
-  hb_face_t* face = hb_font_get_face(font);
-  DCHECK(face);
-
-  hb_codepoint_t space;
-  // If the space glyph isn't present in the font then each space character
-  // will be rendering using a fallback font, which grantees that it cannot
-  // affect the shape of the preceding word.
-  if (!hb_font_get_glyph(font, kSpaceCharacter, 0, &space))
-    return false;
-
-  if (!hb_ot_layout_has_substitution(face) &&
-      !hb_ot_layout_has_positioning(face)) {
-    return false;
-  }
-
-  bool found_space_in_table = false;
-  hb_set_t* glyphs = hb_set_create();
-  if (features & kKerning)
-    found_space_in_table = TableHasSpace(face, glyphs, HB_OT_TAG_GPOS, space);
-  if (!found_space_in_table && (features & kLigatures))
-    found_space_in_table = TableHasSpace(face, glyphs, HB_OT_TAG_GSUB, space);
-
-  hb_set_destroy(glyphs);
-
-  return found_space_in_table;
+  return hb_face->HasSpaceInLigaturesOrKerning(features);
 }
 
 unsigned FontPlatformData::GetHash() const {
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
index 0eaaa38c..1b2c654 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
@@ -72,6 +72,15 @@
     hb_face_destroy(face);
 }
 
+struct HbSetDeleter {
+  void operator()(hb_set_t* set) {
+    if (set)
+      hb_set_destroy(set);
+  }
+};
+
+using HbSetUniquePtr = std::unique_ptr<hb_set_t, HbSetDeleter>;
+
 static scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t*);
 
 HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
@@ -210,6 +219,71 @@
   return true;
 }
 
+static inline bool TableHasSpace(hb_face_t* face,
+                                 hb_set_t* glyphs,
+                                 hb_tag_t tag,
+                                 hb_codepoint_t space) {
+  unsigned count = hb_ot_layout_table_get_lookup_count(face, tag);
+  for (unsigned i = 0; i < count; i++) {
+    hb_ot_layout_lookup_collect_glyphs(face, tag, i, glyphs, glyphs, glyphs,
+                                       nullptr);
+    if (hb_set_has(glyphs, space))
+      return true;
+  }
+  return false;
+}
+
+static bool GetSpaceGlyph(hb_font_t* font, hb_codepoint_t& space) {
+  return hb_font_get_nominal_glyph(font, kSpaceCharacter, &space);
+}
+
+bool HarfBuzzFace::HasSpaceInLigaturesOrKerning(TypesettingFeatures features) {
+  const hb_codepoint_t kInvalidCodepoint = static_cast<hb_codepoint_t>(-1);
+  hb_codepoint_t space = kInvalidCodepoint;
+
+  HbSetUniquePtr glyphs(hb_set_create());
+
+  // Check whether computing is needed and compute for gpos/gsub.
+  if (features & kKerning &&
+      harf_buzz_font_data_->space_in_gpos_ ==
+          HarfBuzzFontData::SpaceGlyphInOpenTypeTables::Unknown) {
+    if (space == kInvalidCodepoint && !GetSpaceGlyph(unscaled_font_, space))
+      return false;
+    // Compute for gpos.
+    hb_face_t* face = hb_font_get_face(unscaled_font_);
+    DCHECK(face);
+    harf_buzz_font_data_->space_in_gpos_ =
+        hb_ot_layout_has_positioning(face) &&
+                TableHasSpace(face, glyphs.get(), HB_OT_TAG_GPOS, space)
+            ? HarfBuzzFontData::SpaceGlyphInOpenTypeTables::Present
+            : HarfBuzzFontData::SpaceGlyphInOpenTypeTables::NotPresent;
+  }
+
+  hb_set_clear(glyphs.get());
+
+  if (features & kLigatures &&
+      harf_buzz_font_data_->space_in_gsub_ ==
+          HarfBuzzFontData::SpaceGlyphInOpenTypeTables::Unknown) {
+    if (space == kInvalidCodepoint && !GetSpaceGlyph(unscaled_font_, space))
+      return false;
+    // Compute for gpos.
+    hb_face_t* face = hb_font_get_face(unscaled_font_);
+    DCHECK(face);
+    harf_buzz_font_data_->space_in_gsub_ =
+        hb_ot_layout_has_substitution(face) &&
+                TableHasSpace(face, glyphs.get(), HB_OT_TAG_GSUB, space)
+            ? HarfBuzzFontData::SpaceGlyphInOpenTypeTables::Present
+            : HarfBuzzFontData::SpaceGlyphInOpenTypeTables::NotPresent;
+  }
+
+  return (features & kKerning &&
+          harf_buzz_font_data_->space_in_gpos_ ==
+              HarfBuzzFontData::SpaceGlyphInOpenTypeTables::Present) ||
+         (features & kLigatures &&
+          harf_buzz_font_data_->space_in_gsub_ ==
+              HarfBuzzFontData::SpaceGlyphInOpenTypeTables::Present);
+}
+
 static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs() {
   hb_font_funcs_t* funcs = FontGlobalContext::GetHarfBuzzFontFuncs();
 
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.h b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.h
index b0a1cf41..2c70e4dd 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.h
@@ -32,6 +32,7 @@
 #define HarfBuzzFace_h
 
 #include "base/memory/scoped_refptr.h"
+#include "platform/fonts/TypesettingFeatures.h"
 #include "platform/fonts/UnicodeRangeSet.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/HashMap.h"
@@ -64,6 +65,8 @@
   hb_font_t* GetScaledFont(scoped_refptr<UnicodeRangeSet>,
                            VerticalLayoutCallbacks) const;
 
+  bool HasSpaceInLigaturesOrKerning(TypesettingFeatures);
+
  private:
   HarfBuzzFace(FontPlatformData*, uint64_t);
 
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFontCache.h b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFontCache.h
index 3a66c0c..e8584cd 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFontCache.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFontCache.h
@@ -39,7 +39,12 @@
   WTF_MAKE_NONCOPYABLE(HarfBuzzFontData);
 
  public:
-  HarfBuzzFontData() : paint_(), vertical_data_(nullptr), range_set_(nullptr) {}
+  HarfBuzzFontData()
+      : paint_(),
+        space_in_gpos_(SpaceGlyphInOpenTypeTables::Unknown),
+        space_in_gsub_(SpaceGlyphInOpenTypeTables::Unknown),
+        vertical_data_(nullptr),
+        range_set_(nullptr) {}
 
   // The vertical origin and vertical advance functions in HarfBuzzFace require
   // the ascent and height metrics as fallback in case no specific vertical
@@ -95,6 +100,11 @@
   float ascent_fallback_;
   float height_fallback_;
 
+  enum class SpaceGlyphInOpenTypeTables { Unknown, Present, NotPresent };
+
+  SpaceGlyphInOpenTypeTables space_in_gpos_;
+  SpaceGlyphInOpenTypeTables space_in_gsub_;
+
   scoped_refptr<OpenTypeVerticalData> vertical_data_;
   scoped_refptr<UnicodeRangeSet> range_set_;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp b/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp
index 8997c15..4081260a 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp
@@ -122,8 +122,7 @@
   scoped_refptr<CanvasResource> this_ref(this);
   auto func = WTF::Bind(&ReleaseFrameResources, provider_,
                         WTF::Passed(std::move(this_ref)));
-  *out_callback = viz::SingleReleaseCallback::Create(
-      ConvertToBaseCallback(std::move(func)));
+  *out_callback = viz::SingleReleaseCallback::Create(std::move(func));
 }
 
 GrContext* CanvasResource::GetGrContext() const {
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp b/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp
index 96cdb55..1f7d14cd 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp
@@ -7,6 +7,7 @@
 #include "platform/graphics/gpu/SharedGpuContext.h"
 #include "platform/graphics/test/FakeGLES2Interface.h"
 #include "platform/graphics/test/FakeWebGraphicsContext3DProvider.h"
+#include "platform/wtf/Functional.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkSurface.h"
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
index 574596a..77571d3 100644
--- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
+++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
@@ -45,7 +45,7 @@
   if (frame_sink_id_.is_valid()) {
     // Only frameless canvas pass an invalid frame sink id; we don't create
     // mojo channel for this special case.
-    current_local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    current_local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
     DCHECK(!sink_.is_bound());
     mojom::blink::OffscreenCanvasProviderPtr provider;
     Platform::Current()->GetInterfaceProvider()->GetInterface(
@@ -337,7 +337,7 @@
   }
 
   if (change_size_for_next_commit_) {
-    current_local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    current_local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
     change_size_for_next_commit_ = false;
   }
 
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h
index 0912c60..6f3f6c9 100644
--- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h
+++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h
@@ -7,7 +7,7 @@
 
 #include <memory>
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "platform/graphics/OffscreenCanvasFrameDispatcher.h"
 #include "platform/graphics/OffscreenCanvasResourceProvider.h"
@@ -69,7 +69,7 @@
   friend class OffscreenCanvasFrameDispatcherImplTest;
 
   // Surface-related
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
   const viz::FrameSinkId frame_sink_id_;
   viz::LocalSurfaceId current_local_surface_id_;
 
diff --git a/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.cpp b/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.cpp
index c63f1b3e..6016c329 100644
--- a/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.cpp
+++ b/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.cpp
@@ -9,7 +9,7 @@
 #include "cc/resources/resource_provider.h"
 #include "cc/resources/video_resource_updater.h"
 #include "cc/scheduler/video_frame_controller.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "media/base/video_frame.h"
 #include "public/platform/InterfaceProvider.h"
 #include "public/platform/Platform.h"
@@ -24,7 +24,7 @@
       resource_provider_(std::move(resource_provider)),
       is_rendering_(false),
       weak_ptr_factory_(this) {
-  current_local_surface_id_ = local_surface_id_allocator_.GenerateId();
+  current_local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
   DETACH_FROM_THREAD(media_thread_checker_);
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.h b/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.h
index 5ad6d14..0376f20 100644
--- a/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.h
+++ b/third_party/WebKit/Source/platform/graphics/VideoFrameSubmitter.h
@@ -7,7 +7,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "platform/PlatformExport.h"
 #include "platform/graphics/VideoFrameResourceProvider.h"
@@ -73,7 +73,7 @@
   cc::VideoFrameProvider* provider_ = nullptr;
   viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
   mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
   viz::LocalSurfaceId current_local_surface_id_;
   std::unique_ptr<VideoFrameResourceProvider> resource_provider_;
 
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
index 43411a4..1bf701c 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
@@ -301,7 +301,8 @@
   cc::EffectNode& mask_isolation = *GetEffectTree().Node(current_effect_id_);
   // Assignment of mask_isolation.stable_id was delayed until now.
   // See PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded().
-  DCHECK_EQ(cc::EffectNode::INVALID_STABLE_ID, mask_isolation.stable_id);
+  DCHECK_EQ(static_cast<uint64_t>(cc::EffectNode::INVALID_STABLE_ID),
+            mask_isolation.stable_id);
   mask_isolation.stable_id = mask_isolation_id.ToInternalValue();
 
   cc::EffectNode& mask_effect = *GetEffectTree().Node(
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp b/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp
index 0095177a4..aa3b9db 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp
@@ -41,6 +41,9 @@
 sk_sp<PaintFilter> FETile::CreateImageFilter() {
   sk_sp<PaintFilter> input(
       PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace()));
+  if (!input)
+    return nullptr;
+
   FloatRect src_rect;
   if (InputEffect(0)->GetFilterEffectType() == kFilterEffectTypeSourceInput)
     src_rect = GetFilter()->FilterRegion();
diff --git a/third_party/WebKit/Source/platform/graphics/filters/PaintFilterBuilder.cpp b/third_party/WebKit/Source/platform/graphics/filters/PaintFilterBuilder.cpp
index 4bc5724..f59a410e 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/PaintFilterBuilder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/PaintFilterBuilder.cpp
@@ -84,6 +84,7 @@
       requires_pm_color_validation
           ? effect->CreateImageFilter()
           : effect->CreateImageFilterWithoutValidation();
+
   sk_sp<PaintFilter> filter = TransformInterpolationSpace(
       orig_filter, effect->OperatingInterpolationSpace(), interpolation_space);
   effect->SetImageFilter(interpolation_space, requires_pm_color_validation,
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
index d4f7487..8167474 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -339,8 +339,7 @@
   auto func = WTF::Bind(&DrawingBuffer::MailboxReleasedSoftware,
                         scoped_refptr<DrawingBuffer>(this),
                         WTF::Passed(std::move(bitmap)), size_);
-  *out_release_callback = viz::SingleReleaseCallback::Create(
-      ConvertToBaseCallback(std::move(func)));
+  *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func));
 
   if (preserve_drawing_buffer_ == kDiscard) {
     SetBufferClearNeeded(true);
@@ -425,8 +424,7 @@
     auto func =
         WTF::Bind(&DrawingBuffer::MailboxReleasedGpu,
                   scoped_refptr<DrawingBuffer>(this), color_buffer_for_mailbox);
-    *out_release_callback = viz::SingleReleaseCallback::Create(
-        ConvertToBaseCallback(std::move(func)));
+    *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func));
   }
 
   // Point |m_frontColorBuffer| to the buffer that we are now presenting.
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp
index fbef4715..21604d2a 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp
@@ -114,8 +114,7 @@
     auto func =
         WTF::Bind(&ImageLayerBridge::ResourceReleasedGpu,
                   WrapWeakPersistent(this), std::move(image_for_compositor));
-    *out_release_callback = viz::SingleReleaseCallback::Create(
-        ConvertToBaseCallback(std::move(func)));
+    *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func));
   } else {
     std::unique_ptr<viz::SharedBitmap> bitmap =
         CreateOrRecycleBitmap(image_for_compositor->Size());
@@ -144,8 +143,7 @@
     auto func = WTF::Bind(&ImageLayerBridge::ResourceReleasedSoftware,
                           WrapWeakPersistent(this), base::Passed(&bitmap),
                           image_for_compositor->Size());
-    *out_release_callback = viz::SingleReleaseCallback::Create(
-        ConvertToBaseCallback(std::move(func)));
+    *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func));
   }
 
   // TODO(junov): Figure out how to get the color space info.
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h
index 2891eab..fa5d16d2 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h
@@ -5,14 +5,13 @@
 #ifndef SharedGpuContext_h
 #define SharedGpuContext_h
 
+#include <memory>
+#include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "platform/PlatformExport.h"
 #include "platform/graphics/WebGraphicsContext3DProviderWrapper.h"
-#include "platform/wtf/Functional.h"
 #include "platform/wtf/ThreadSpecific.h"
 
-#include <memory>
-
 namespace blink {
 
 class WebGraphicsContext3DProvider;
@@ -37,7 +36,7 @@
   static bool IsValidWithoutRestoring();
 
   using ContextProviderFactory =
-      WTF::RepeatingFunction<std::unique_ptr<WebGraphicsContext3DProvider>(
+      base::RepeatingCallback<std::unique_ptr<WebGraphicsContext3DProvider>(
           bool* is_gpu_compositing_disabled)>;
   static void SetContextProviderFactoryForTesting(ContextProviderFactory);
   // Resets the global instance including the |context_provider_factory_| and
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index d772ab8..2ac6bdab 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -5072,11 +5072,11 @@
 }
 
 TEST(HeapTest, Bind) {
-  WTF::Closure closure =
+  base::OnceClosure closure =
       WTF::Bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::Trace),
                 WrapPersistent(Bar::Create()), nullptr);
   // OffHeapInt* should not make Persistent.
-  WTF::Closure closure2 =
+  base::OnceClosure closure2 =
       WTF::Bind(&OffHeapInt::VoidFunction, OffHeapInt::Create(1));
   PreciselyCollectGarbage();
   // The closure should have a persistent handle to the Bar.
@@ -5084,7 +5084,7 @@
 
   UseMixin::trace_count_ = 0;
   Mixin* mixin = UseMixin::Create();
-  WTF::Closure mixin_closure =
+  base::OnceClosure mixin_closure =
       WTF::Bind(static_cast<void (Mixin::*)(Visitor*)>(&Mixin::Trace),
                 WrapPersistent(mixin), nullptr);
   PreciselyCollectGarbage();
diff --git a/third_party/WebKit/Source/platform/heap/PersistentTest.cpp b/third_party/WebKit/Source/platform/heap/PersistentTest.cpp
index ae905981..7386700 100644
--- a/third_party/WebKit/Source/platform/heap/PersistentTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/PersistentTest.cpp
@@ -8,6 +8,7 @@
 #include "platform/CrossThreadFunctional.h"
 #include "platform/heap/Handle.h"
 #include "platform/heap/HeapTestUtilities.h"
+#include "platform/wtf/Functional.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
@@ -23,7 +24,7 @@
 TEST(PersistentTest, BindCancellation) {
   Receiver* receiver = new Receiver;
   int counter = 0;
-  WTF::RepeatingClosure function =
+  base::RepeatingClosure function =
       WTF::BindRepeating(&Receiver::Increment, WrapWeakPersistent(receiver),
                          WTF::Unretained(&counter));
 
diff --git a/third_party/WebKit/Source/platform/loader/fetch/CachedMetadataHandler.h b/third_party/WebKit/Source/platform/loader/fetch/CachedMetadataHandler.h
index 203f4470..f1162c4 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/CachedMetadataHandler.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/CachedMetadataHandler.h
@@ -39,6 +39,8 @@
   // Returns the encoding to which the cache is specific.
   virtual String Encoding() const = 0;
 
+  virtual bool IsServedFromCacheStorage() const = 0;
+
  protected:
   CachedMetadataHandler() {}
 };
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
index 3c1e4e97..ecddf0d 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
@@ -124,6 +124,10 @@
   void ClearCachedMetadata(CacheType) override;
   scoped_refptr<CachedMetadata> GetCachedMetadata(uint32_t) const override;
   String Encoding() const override;
+  bool IsServedFromCacheStorage() const override {
+    return !GetResponse().CacheStorageCacheName().IsNull();
+  }
+
   // Sets the serialized metadata retrieved from the platform's cache.
   void SetSerializedCachedMetadata(const char*, size_t);
 
@@ -222,7 +226,6 @@
  private:
   explicit ServiceWorkerResponseCachedMetadataHandler(Resource*,
                                                       const SecurityOrigin*);
-  String cache_storage_cache_name_;
   scoped_refptr<const SecurityOrigin> security_origin_;
 };
 
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp
index fab34e76..1c0a1884 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceRequest.cpp
@@ -77,9 +77,7 @@
       is_external_request_(false),
       cors_preflight_policy_(
           network::mojom::CORSPreflightPolicy::kConsiderPreflight),
-      loading_ipc_type_(RuntimeEnabledFeatures::LoadingWithMojoEnabled()
-                            ? WebURLRequest::LoadingIPCType::kMojo
-                            : WebURLRequest::LoadingIPCType::kChromeIPC),
+      loading_ipc_type_(WebURLRequest::LoadingIPCType::kMojo),
       is_same_document_navigation_(false),
       input_perf_metric_report_policy_(
           InputToLoadPerfMetricReportPolicy::kNoReport),
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
index f895a60..6859246 100644
--- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5
+++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -541,6 +541,11 @@
     },
     {
       name: "LoadingWithMojo",
+      status: "stable",
+    },
+    {
+      name: "LocksAPI",
+      status: "experimental",
     },
     {
       name: "LongTaskObserver",
diff --git a/third_party/WebKit/Source/platform/scheduler/BUILD.gn b/third_party/WebKit/Source/platform/scheduler/BUILD.gn
index 588e8a0..745ac70 100644
--- a/third_party/WebKit/Source/platform/scheduler/BUILD.gn
+++ b/third_party/WebKit/Source/platform/scheduler/BUILD.gn
@@ -144,8 +144,6 @@
 
   sources = [
     "base/test_task_time_observer.h",
-    "base/test_time_source.cc",
-    "base/test_time_source.h",
     "test/create_task_queue_manager_for_test.cc",
     "test/create_task_queue_manager_for_test.h",
     "test/fake_renderer_scheduler.cc",
diff --git a/third_party/WebKit/Source/platform/scheduler/DEPS b/third_party/WebKit/Source/platform/scheduler/DEPS
index 4b2a56b..7dbb33a 100644
--- a/third_party/WebKit/Source/platform/scheduler/DEPS
+++ b/third_party/WebKit/Source/platform/scheduler/DEPS
@@ -25,7 +25,6 @@
   "+base/strings/string_number_conversions.h",
   "+base/synchronization/atomic_flag.h",
   "+base/synchronization/lock.h",
-  "+base/test_time_source.h",
   "+base/threading/platform_thread.h",
   "+base/threading/thread.h",
   "+base/threading/thread_checker.h",
diff --git a/third_party/WebKit/Source/platform/scheduler/base/DEPS b/third_party/WebKit/Source/platform/scheduler/base/DEPS
index 2fab039..53701134 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/DEPS
+++ b/third_party/WebKit/Source/platform/scheduler/base/DEPS
@@ -1,5 +1,5 @@
 specific_include_rules = {
-  "(test_time_source|.*test)\.cc": [
+  ".*test\.cc": [
     "+components/viz/test",
   ],
 }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
index a13c288..a1ca23c 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager.cc
@@ -85,7 +85,7 @@
   return std::unique_ptr<TaskQueueManager>(
       new TaskQueueManager(internal::ThreadControllerImpl::Create(
           base::MessageLoop::current(),
-          std::make_unique<base::DefaultTickClock>())));
+          base::DefaultTickClock::GetInstance())));
 }
 
 TaskQueueManager::AnyThread::AnyThread()
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.cc
index 6dbbcfd..b6be124b 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.cc
@@ -16,15 +16,15 @@
 scoped_refptr<TaskQueueManagerDelegateForTest>
 TaskQueueManagerDelegateForTest::Create(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    std::unique_ptr<base::TickClock> time_source) {
+    base::TickClock* time_source) {
   return base::WrapRefCounted(
-      new TaskQueueManagerDelegateForTest(task_runner, std::move(time_source)));
+      new TaskQueueManagerDelegateForTest(task_runner, time_source));
 }
 
 TaskQueueManagerDelegateForTest::TaskQueueManagerDelegateForTest(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    std::unique_ptr<base::TickClock> time_source)
-    : task_runner_(task_runner), time_source_(std::move(time_source)) {}
+    base::TickClock* time_source)
+    : task_runner_(task_runner), time_source_(time_source) {}
 
 TaskQueueManagerDelegateForTest::~TaskQueueManagerDelegateForTest() {}
 
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.h
index d518b1fc..f66ee0d2 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_delegate_for_test.h
@@ -21,7 +21,7 @@
  public:
   static scoped_refptr<TaskQueueManagerDelegateForTest> Create(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      std::unique_ptr<base::TickClock> time_source);
+      base::TickClock* time_source);
 
   // SingleThreadTaskRunner:
   bool PostDelayedTask(const base::Location& from_here,
@@ -44,11 +44,11 @@
   ~TaskQueueManagerDelegateForTest() override;
   TaskQueueManagerDelegateForTest(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      std::unique_ptr<base::TickClock> time_source);
+      base::TickClock* time_source);
 
  private:
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  std::unique_ptr<base::TickClock> time_source_;
+  base::TickClock* time_source_;
 
   DISALLOW_COPY_AND_ASSIGN(TaskQueueManagerDelegateForTest);
 };
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc
index 3011455f..2f228b7 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc
@@ -86,7 +86,7 @@
     message_loop_.reset(new base::MessageLoop());
     manager_ = CreateTaskQueueManagerForTest(
         message_loop_.get(), message_loop_->task_runner(),
-        std::make_unique<base::DefaultTickClock>());
+        base::DefaultTickClock::GetInstance());
     manager_->AddTaskTimeObserver(&test_task_time_observer_);
 
     virtual_time_domain_.reset(new PerfTestTimeDomain());
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
index 7d0503ee..dde0fa2 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
@@ -25,7 +25,6 @@
 #include "platform/scheduler/base/task_queue_selector.h"
 #include "platform/scheduler/base/test_count_uses_time_source.h"
 #include "platform/scheduler/base/test_task_time_observer.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/base/thread_controller_impl.h"
 #include "platform/scheduler/base/virtual_time_domain.h"
 #include "platform/scheduler/base/work_queue.h"
@@ -64,10 +63,10 @@
   ThreadControllerForTest(
       base::MessageLoop* message_loop,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      std::unique_ptr<base::TickClock> time_source)
+      base::TickClock* time_source)
       : ThreadControllerImpl(message_loop,
                              std::move(task_runner),
-                             std::move(time_source)) {}
+                             time_source) {}
 
   ~ThreadControllerForTest() override {}
 
@@ -105,37 +104,29 @@
         TaskQueue::Spec("test").SetShouldMonitorQuiescence(true));
   }
 
-  void InitializeWithClock(size_t num_queues,
-                           std::unique_ptr<base::TickClock> test_time_source) {
-    test_task_runner_ = base::WrapRefCounted(
-        new cc::OrderedSimpleTaskRunner(now_src_.get(), false));
+  void Initialize(size_t num_queues) {
+    now_src_.Advance(base::TimeDelta::FromMicroseconds(1000));
+
+    test_task_runner_ =
+        base::WrapRefCounted(new cc::OrderedSimpleTaskRunner(&now_src_, false));
 
     manager_ = std::make_unique<TaskQueueManagerForTest>(
         std::make_unique<ThreadControllerForTest>(
-            nullptr, test_task_runner_.get(),
-            std::make_unique<TestTimeSource>(now_src_.get())));
+            nullptr, test_task_runner_.get(), &now_src_));
 
     for (size_t i = 0; i < num_queues; i++)
       runners_.push_back(CreateTaskQueue());
   }
 
-  void Initialize(size_t num_queues) {
-    now_src_.reset(new base::SimpleTestTickClock());
-    now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
-    InitializeWithClock(num_queues,
-                        std::make_unique<TestTimeSource>(now_src_.get()));
-  }
-
   void InitializeWithRealMessageLoop(size_t num_queues) {
-    now_src_.reset(new base::SimpleTestTickClock());
     message_loop_.reset(new base::MessageLoop());
     original_message_loop_task_runner_ = message_loop_->task_runner();
     // A null clock triggers some assertions.
-    now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
+    now_src_.Advance(base::TimeDelta::FromMicroseconds(1000));
     manager_ = std::make_unique<TaskQueueManagerForTest>(
         std::make_unique<ThreadControllerForTest>(
             message_loop_.get(), base::ThreadTaskRunnerHandle::Get(),
-            std::make_unique<TestTimeSource>(now_src_.get())));
+            &now_src_));
 
     for (size_t i = 0; i < num_queues; i++)
       runners_.push_back(CreateTaskQueue());
@@ -186,7 +177,7 @@
       if (manager_->selector_.EnabledWorkQueuesEmpty()) {
         base::TimeTicks run_time;
         if (manager_->real_time_domain()->NextScheduledRunTime(&run_time)) {
-          now_src_->SetNowTicks(run_time);
+          now_src_.SetNowTicks(run_time);
           per_run_time_callback.Run();
         } else {
           break;
@@ -197,12 +188,12 @@
     }
   }
 
-  base::TimeTicks Now() const { return now_src_->NowTicks(); }
+  base::TimeTicks Now() { return now_src_.NowTicks(); }
 
   std::unique_ptr<base::MessageLoop> message_loop_;
   scoped_refptr<base::SingleThreadTaskRunner>
       original_message_loop_task_runner_;
-  std::unique_ptr<base::SimpleTestTickClock> now_src_;
+  base::SimpleTestTickClock now_src_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_;
   std::unique_ptr<TaskQueueManagerForTest> manager_;
   std::vector<scoped_refptr<TestTaskQueue>> runners_;
@@ -230,13 +221,12 @@
   message_loop_.reset(new base::MessageLoop());
   // This memory is managed by the TaskQueueManager, but we need to hold a
   // pointer to this object to read out how many times Now was called.
-  TestCountUsesTimeSource* test_count_uses_time_source =
-      new TestCountUsesTimeSource();
+  TestCountUsesTimeSource test_count_uses_time_source;
 
   manager_ = std::make_unique<TaskQueueManagerForTest>(
       std::make_unique<ThreadControllerForTest>(
           nullptr, base::ThreadTaskRunnerHandle::Get(),
-          base::WrapUnique(test_count_uses_time_source)));
+          &test_count_uses_time_source));
   manager_->SetWorkBatchSize(6);
   manager_->AddTaskTimeObserver(&test_task_time_observer_);
 
@@ -254,20 +244,19 @@
   // Now is called each time a task is queued, when first task is started
   // running, and when a task is completed.
   // With 6 tasks that means that 6 + 1 + 6 = 13 calls are expected.
-  EXPECT_EQ(13, test_count_uses_time_source->now_calls_count());
+  EXPECT_EQ(13, test_count_uses_time_source.now_calls_count());
 }
 
 TEST_F(TaskQueueManagerTest, NowNotCalledForNestedTasks) {
   message_loop_.reset(new base::MessageLoop());
   // This memory is managed by the TaskQueueManager, but we need to hold a
   // pointer to this object to read out how many times Now was called.
-  TestCountUsesTimeSource* test_count_uses_time_source =
-      new TestCountUsesTimeSource();
+  TestCountUsesTimeSource test_count_uses_time_source;
 
   manager_ = std::make_unique<TaskQueueManagerForTest>(
-      std::make_unique<ThreadControllerForTest>(
-          message_loop_.get(), message_loop_->task_runner(),
-          base::WrapUnique(test_count_uses_time_source)));
+      std::make_unique<ThreadControllerForTest>(message_loop_.get(),
+                                                message_loop_->task_runner(),
+                                                &test_count_uses_time_source));
   manager_->AddTaskTimeObserver(&test_task_time_observer_);
 
   runners_.push_back(CreateTaskQueue());
@@ -288,7 +277,7 @@
   // task. We shouldn't call it for any of the nested tasks.
   // Also Now is called when a task is scheduled (8 times).
   // That brings expected call count for Now() to 2 + 8 = 10
-  EXPECT_EQ(10, test_count_uses_time_source->now_calls_count());
+  EXPECT_EQ(10, test_count_uses_time_source.now_calls_count());
 }
 
 void NullTask() {}
@@ -407,11 +396,11 @@
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
                                delay);
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
-  now_src_->Advance(delay);
+  now_src_.Advance(delay);
   EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately());
 
   // Move the task into the |delayed_work_queue|.
-  WakeUpReadyDelayedQueues(LazyNow(now_src_.get()));
+  WakeUpReadyDelayedQueues(LazyNow(&now_src_));
   EXPECT_FALSE(runners_[0]->GetTaskQueueImpl()->delayed_work_queue()->Empty());
   EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately());
 
@@ -703,7 +692,7 @@
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
                                delay3);
 
-  now_src_->Advance(base::TimeDelta::FromMilliseconds(15));
+  now_src_.Advance(base::TimeDelta::FromMilliseconds(15));
   test_task_runner_->RunUntilIdle();
   EXPECT_TRUE(run_order.empty());
 
@@ -831,13 +820,13 @@
 
   std::vector<base::TimeTicks> run_times;
   runners_[0]->PostDelayedTask(
-      FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()),
+      FROM_HERE, base::Bind(&RecordTimeTask, &run_times, &now_src_),
       base::TimeDelta::FromMilliseconds(100));
   runners_[0]->PostDelayedTask(
-      FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()),
+      FROM_HERE, base::Bind(&RecordTimeTask, &run_times, &now_src_),
       base::TimeDelta::FromMilliseconds(200));
   runners_[0]->PostDelayedTask(
-      FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()),
+      FROM_HERE, base::Bind(&RecordTimeTask, &run_times, &now_src_),
       base::TimeDelta::FromMilliseconds(300));
 
   runners_[0]->InsertFenceAt(Now() + base::TimeDelta::FromMilliseconds(250));
@@ -868,8 +857,8 @@
   runners_[0]->InsertFenceAt(Now() + base::TimeDelta::FromMilliseconds(250));
 
   for (int i = 0; i < 5; ++i) {
-    runners_[0]->PostTask(
-        FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()));
+    runners_[0]->PostTask(FROM_HERE,
+                          base::Bind(&RecordTimeTask, &run_times, &now_src_));
     test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(100));
     if (i < 2) {
       EXPECT_FALSE(runners_[0]->HasActiveFence());
@@ -902,8 +891,8 @@
   runners_[0]->InsertFenceAt(Now() + base::TimeDelta::FromMilliseconds(250));
 
   for (int i = 0; i < 3; ++i) {
-    runners_[0]->PostTask(
-        FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()));
+    runners_[0]->PostTask(FROM_HERE,
+                          base::Bind(&RecordTimeTask, &run_times, &now_src_));
     EXPECT_FALSE(runners_[0]->HasActiveFence());
     test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(100));
   }
@@ -912,8 +901,8 @@
   runners_[0]->RemoveFence();
 
   for (int i = 0; i < 2; ++i) {
-    runners_[0]->PostTask(
-        FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()));
+    runners_[0]->PostTask(FROM_HERE,
+                          base::Bind(&RecordTimeTask, &run_times, &now_src_));
     test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(100));
     EXPECT_FALSE(runners_[0]->HasActiveFence());
   }
@@ -1163,7 +1152,7 @@
 
 TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime) {
   Initialize(2u);
-  now_src_->Advance(base::TimeDelta::FromMicroseconds(10000));
+  now_src_.Advance(base::TimeDelta::FromMicroseconds(10000));
 
   // With no delayed tasks.
   base::TimeTicks run_time;
@@ -1177,30 +1166,30 @@
   base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50);
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
   EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-  EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
+  EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time);
 
   // With another delayed task in the same queue with a longer delay.
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
                                base::TimeDelta::FromMilliseconds(100));
   EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-  EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
+  EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time);
 
   // With another delayed task in the same queue with a shorter delay.
   expected_delay = base::TimeDelta::FromMilliseconds(20);
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
   EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-  EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
+  EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time);
 
   // With another delayed task in a different queue with a shorter delay.
   expected_delay = base::TimeDelta::FromMilliseconds(10);
   runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
   EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-  EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
+  EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time);
 
   // Test it updates as time progresses
-  now_src_->Advance(expected_delay);
+  now_src_.Advance(expected_delay);
   EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-  EXPECT_EQ(now_src_->NowTicks(), run_time);
+  EXPECT_EQ(now_src_.NowTicks(), run_time);
 }
 
 TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime_MultipleQueues) {
@@ -1216,7 +1205,7 @@
 
   base::TimeTicks run_time;
   EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
-  EXPECT_EQ(now_src_->NowTicks() + delay2, run_time);
+  EXPECT_EQ(now_src_.NowTicks() + delay2, run_time);
 }
 
 TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) {
@@ -1281,13 +1270,13 @@
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
 
   // Move time forwards until just before the delayed task should run.
-  now_src_->Advance(base::TimeDelta::FromMilliseconds(10));
-  WakeUpReadyDelayedQueues(LazyNow(now_src_.get()));
+  now_src_.Advance(base::TimeDelta::FromMilliseconds(10));
+  WakeUpReadyDelayedQueues(LazyNow(&now_src_));
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
 
   // Force the delayed task onto the work queue.
-  now_src_->Advance(base::TimeDelta::FromMilliseconds(2));
-  WakeUpReadyDelayedQueues(LazyNow(now_src_.get()));
+  now_src_.Advance(base::TimeDelta::FromMilliseconds(2));
+  WakeUpReadyDelayedQueues(LazyNow(&now_src_));
   EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately());
 
   test_task_runner_->RunUntilIdle();
@@ -1308,15 +1297,15 @@
   base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
   for (int i = 10; i < 19; i++) {
     runners_[0]->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&ExpensiveTestTask, i, now_src_.get(), &run_order), delay);
+        FROM_HERE, base::Bind(&ExpensiveTestTask, i, &now_src_, &run_order),
+        delay);
   }
 
   test_task_runner_->RunForPeriod(delay);
 
   for (int i = 0; i < 9; i++) {
-    runners_[0]->PostTask(FROM_HERE, base::Bind(&ExpensiveTestTask, i,
-                                                now_src_.get(), &run_order));
+    runners_[0]->PostTask(
+        FROM_HERE, base::Bind(&ExpensiveTestTask, i, &now_src_, &run_order));
   }
 
   test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
@@ -1340,7 +1329,7 @@
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
                                delay);
 
-  now_src_->Advance(delay * 2);
+  now_src_.Advance(delay * 2);
   test_task_runner_->RunUntilIdle();
 
   EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
@@ -1357,7 +1346,7 @@
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
                                delay);
 
-  now_src_->Advance(delay * 2);
+  now_src_.Advance(delay * 2);
   test_task_runner_->RunUntilIdle();
 
   EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
@@ -1374,7 +1363,7 @@
   runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
                                delay2);
 
-  now_src_->Advance(delay1 * 2);
+  now_src_.Advance(delay1 * 2);
   test_task_runner_->RunUntilIdle();
 
   EXPECT_THAT(run_order, ElementsAre(2, 1));
@@ -1929,7 +1918,7 @@
       std::make_unique<RealTimeDomain>();
   manager_->RegisterTimeDomain(mock_time_domain.get());
 
-  now_src_->Advance(delay10s);
+  now_src_.Advance(delay10s);
 
   EXPECT_CALL(observer, OnQueueNextWakeUpChanged(_, _));
   runners_[0]->SetTimeDomain(mock_time_domain.get());
@@ -1966,8 +1955,8 @@
               OnQueueNextWakeUpChanged(runners_[0].get(), start_time + delay1))
       .Times(1);
 
-  CancelableTask task1(now_src_.get());
-  CancelableTask task2(now_src_.get());
+  CancelableTask task1(&now_src_);
+  CancelableTask task2(&now_src_);
   std::vector<base::TimeTicks> run_times;
   runners_[0]->PostDelayedTask(
       FROM_HERE,
@@ -2091,9 +2080,8 @@
   Initialize(1u);
 
   QuadraticTask quadratic_delayed_task(
-      runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
-  LinearTask linear_immediate_task(runners_[0], base::TimeDelta(),
-                                   now_src_.get());
+      runners_[0], base::TimeDelta::FromMilliseconds(10), &now_src_);
+  LinearTask linear_immediate_task(runners_[0], base::TimeDelta(), &now_src_);
   base::Callback<bool()> should_exit =
       base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
   quadratic_delayed_task.SetShouldExit(should_exit);
@@ -2116,9 +2104,9 @@
   Initialize(1u);
 
   QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
-                                         now_src_.get());
+                                         &now_src_);
   LinearTask linear_delayed_task(
-      runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
+      runners_[0], base::TimeDelta::FromMilliseconds(10), &now_src_);
   base::Callback<bool()> should_exit =
       base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task);
 
@@ -2145,9 +2133,8 @@
   Initialize(2u);
 
   QuadraticTask quadratic_delayed_task(
-      runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
-  LinearTask linear_immediate_task(runners_[1], base::TimeDelta(),
-                                   now_src_.get());
+      runners_[0], base::TimeDelta::FromMilliseconds(10), &now_src_);
+  LinearTask linear_immediate_task(runners_[1], base::TimeDelta(), &now_src_);
   base::Callback<bool()> should_exit =
       base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
   quadratic_delayed_task.SetShouldExit(should_exit);
@@ -2171,9 +2158,9 @@
   Initialize(2u);
 
   QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
-                                         now_src_.get());
+                                         &now_src_);
   LinearTask linear_delayed_task(
-      runners_[1], base::TimeDelta::FromMilliseconds(10), now_src_.get());
+      runners_[1], base::TimeDelta::FromMilliseconds(10), &now_src_);
   base::Callback<bool()> should_exit =
       base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task);
 
@@ -2352,10 +2339,10 @@
 
   base::TimeTicks start_time = manager_->NowTicks();
 
-  CancelableTask task1(now_src_.get());
-  CancelableTask task2(now_src_.get());
-  CancelableTask task3(now_src_.get());
-  CancelableTask task4(now_src_.get());
+  CancelableTask task1(&now_src_);
+  CancelableTask task2(&now_src_);
+  CancelableTask task3(&now_src_);
+  CancelableTask task4(&now_src_);
   base::TimeDelta delay1(base::TimeDelta::FromSeconds(5));
   base::TimeDelta delay2(base::TimeDelta::FromSeconds(10));
   base::TimeDelta delay3(base::TimeDelta::FromSeconds(15));
@@ -2388,7 +2375,7 @@
          base::SimpleTestTickClock* clock) {
         wake_up_times->insert(clock->NowTicks());
       },
-      &wake_up_times, now_src_.get()));
+      &wake_up_times, &now_src_));
 
   EXPECT_THAT(wake_up_times,
               ElementsAre(start_time + delay1, start_time + delay4));
@@ -2400,10 +2387,10 @@
 
   base::TimeTicks start_time = manager_->NowTicks();
 
-  CancelableTask task1(now_src_.get());
-  CancelableTask task2(now_src_.get());
-  CancelableTask task3(now_src_.get());
-  CancelableTask task4(now_src_.get());
+  CancelableTask task1(&now_src_);
+  CancelableTask task2(&now_src_);
+  CancelableTask task3(&now_src_);
+  CancelableTask task4(&now_src_);
   base::TimeDelta delay1(base::TimeDelta::FromSeconds(5));
   base::TimeDelta delay2(base::TimeDelta::FromSeconds(10));
   base::TimeDelta delay3(base::TimeDelta::FromSeconds(15));
@@ -2436,7 +2423,7 @@
          base::SimpleTestTickClock* clock) {
         wake_up_times->insert(clock->NowTicks());
       },
-      &wake_up_times, now_src_.get()));
+      &wake_up_times, &now_src_));
 
   EXPECT_THAT(wake_up_times,
               ElementsAre(start_time + delay1, start_time + delay4));
@@ -2448,10 +2435,10 @@
 
   base::TimeTicks start_time = manager_->NowTicks();
 
-  CancelableTask task1(now_src_.get());
-  CancelableTask task2(now_src_.get());
-  CancelableTask task3(now_src_.get());
-  CancelableTask task4(now_src_.get());
+  CancelableTask task1(&now_src_);
+  CancelableTask task2(&now_src_);
+  CancelableTask task3(&now_src_);
+  CancelableTask task4(&now_src_);
   base::TimeDelta delay1(base::TimeDelta::FromSeconds(5));
   base::TimeDelta delay2(base::TimeDelta::FromSeconds(10));
   base::TimeDelta delay3(base::TimeDelta::FromSeconds(15));
@@ -2492,7 +2479,7 @@
          base::SimpleTestTickClock* clock) {
         wake_up_times->insert(clock->NowTicks());
       },
-      &wake_up_times, now_src_.get()));
+      &wake_up_times, &now_src_));
 
   EXPECT_THAT(wake_up_times,
               ElementsAre(start_time + delay1, start_time + delay3,
@@ -2580,10 +2567,10 @@
 TEST_F(TaskQueueManagerTest, SweepCanceledDelayedTasks) {
   Initialize(1u);
 
-  CancelableTask task1(now_src_.get());
-  CancelableTask task2(now_src_.get());
-  CancelableTask task3(now_src_.get());
-  CancelableTask task4(now_src_.get());
+  CancelableTask task1(&now_src_);
+  CancelableTask task2(&now_src_);
+  CancelableTask task3(&now_src_);
+  CancelableTask task4(&now_src_);
   base::TimeDelta delay1(base::TimeDelta::FromSeconds(5));
   base::TimeDelta delay2(base::TimeDelta::FromSeconds(10));
   base::TimeDelta delay3(base::TimeDelta::FromSeconds(15));
@@ -2624,7 +2611,7 @@
 TEST_F(TaskQueueManagerTest, ComputeDelayTillNextTask) {
   Initialize(2u);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   EXPECT_FALSE(static_cast<bool>(ComputeDelayTillNextTask(&lazy_now)));
 
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
@@ -2658,7 +2645,7 @@
   voter->SetQueueEnabled(false);
   runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   EXPECT_FALSE(ComputeDelayTillNextTask(&lazy_now));
 }
 
@@ -2668,7 +2655,7 @@
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
   runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   EXPECT_FALSE(ComputeDelayTillNextTask(&lazy_now));
 }
 
@@ -2679,7 +2666,7 @@
   runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   EXPECT_EQ(base::TimeDelta(), ComputeDelayTillNextTask(&lazy_now)->Delay());
 }
 
@@ -2689,16 +2676,16 @@
   runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
                                base::TimeDelta::FromSeconds(1));
 
-  now_src_->Advance(base::TimeDelta::FromSeconds(10));
+  now_src_.Advance(base::TimeDelta::FromSeconds(10));
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   EXPECT_EQ(base::TimeDelta(), ComputeDelayTillNextTask(&lazy_now)->Delay());
 }
 
 TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_NoMoreWork) {
   Initialize(1u);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   PostDoWorkContinuation(base::Optional<NextTaskDelay>(), &lazy_now);
 
   EXPECT_EQ(0u, test_task_runner_->NumPendingTasks());
@@ -2709,7 +2696,7 @@
 TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_ImmediateWork) {
   Initialize(1u);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   PostDoWorkContinuation(NextTaskDelay(), &lazy_now);
 
   EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
@@ -2721,7 +2708,7 @@
 TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_DelayedWorkInThePast) {
   Initialize(1u);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   // Note this isn't supposed to happen in practice.
   PostDoWorkContinuation(
       NextTaskDelay(base::TimeDelta::FromSeconds(-1),
@@ -2738,7 +2725,7 @@
 TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_DelayedWork) {
   Initialize(1u);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   PostDoWorkContinuation(NextTaskDelay(base::TimeDelta::FromSeconds(1),
                                        runners_[0]->GetTimeDomain()),
                          &lazy_now);
@@ -2760,7 +2747,7 @@
   EXPECT_EQ(base::TimeDelta(), test_task_runner_->DelayToNextTaskTime());
   EXPECT_EQ(1, immediate_do_work_posted_count());
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   PostDoWorkContinuation(NextTaskDelay(base::TimeDelta::FromSeconds(1),
                                        runners_[0]->GetTimeDomain()),
                          &lazy_now);
@@ -2775,7 +2762,7 @@
 TEST_F(TaskQueueManagerTest, PostDoWorkContinuation_DelayedWorkTimeChanges) {
   Initialize(1u);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   PostDoWorkContinuation(NextTaskDelay(base::TimeDelta::FromSeconds(1),
                                        runners_[0]->GetTimeDomain()),
                          &lazy_now);
@@ -2807,13 +2794,13 @@
        PostDoWorkContinuation_ImmediateWorkButDelayedDoWorkPending) {
   Initialize(1u);
 
-  LazyNow lazy_now(now_src_.get());
+  LazyNow lazy_now(&now_src_);
   PostDoWorkContinuation(NextTaskDelay(base::TimeDelta::FromSeconds(1),
                                        runners_[0]->GetTimeDomain()),
                          &lazy_now);
 
-  now_src_->Advance(base::TimeDelta::FromSeconds(1));
-  lazy_now = LazyNow(now_src_.get());
+  now_src_.Advance(base::TimeDelta::FromSeconds(1));
+  lazy_now = LazyNow(&now_src_);
   PostDoWorkContinuation(NextTaskDelay(), &lazy_now);
 
   // Because the delayed DoWork was pending we don't expect an immediate DoWork
@@ -2840,10 +2827,9 @@
 TEST_F(TaskQueueManagerTest, DelayedTaskRunsInNestedMessageLoop) {
   InitializeWithRealMessageLoop(1u);
   base::RunLoop run_loop;
-  runners_[0]->PostTask(
-      FROM_HERE,
-      base::Bind(&MessageLoopTaskWithDelayedQuit, message_loop_.get(),
-                 now_src_.get(), base::RetainedRef(runners_[0])));
+  runners_[0]->PostTask(FROM_HERE, base::Bind(&MessageLoopTaskWithDelayedQuit,
+                                              message_loop_.get(), &now_src_,
+                                              base::RetainedRef(runners_[0])));
   run_loop.RunUntilIdle();
 }
 
@@ -2873,7 +2859,7 @@
                  run_loop.QuitClosure(), base::RetainedRef(runners_[0])),
       base::TimeDelta::FromMilliseconds(100));
 
-  now_src_->Advance(base::TimeDelta::FromMilliseconds(200));
+  now_src_.Advance(base::TimeDelta::FromMilliseconds(200));
   run_loop.Run();
 }
 
@@ -3146,9 +3132,9 @@
   EXPECT_EQ(0u, manager_->QueuesToDeleteCount());
 
   for (int i = 1; i <= 5; ++i) {
-    main_tq->PostDelayedTask(
-        FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()),
-        base::TimeDelta::FromMilliseconds(i * 100));
+    main_tq->PostDelayedTask(FROM_HERE,
+                             base::Bind(&RecordTimeTask, &run_times, &now_src_),
+                             base::TimeDelta::FromMilliseconds(i * 100));
   }
   test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(250));
 
@@ -3202,7 +3188,7 @@
 
   for (int i = 1; i <= 5; ++i) {
     main_tqs[0]->PostDelayedTask(
-        FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()),
+        FROM_HERE, base::Bind(&RecordTimeTask, &run_times, &now_src_),
         base::TimeDelta::FromMilliseconds(i * 100));
   }
   test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(250));
@@ -3240,9 +3226,9 @@
   EXPECT_EQ(0u, manager_->QueuesToDeleteCount());
 
   for (int i = 1; i <= 5; ++i) {
-    main_tq->PostDelayedTask(
-        FROM_HERE, base::Bind(&RecordTimeTask, &run_times, now_src_.get()),
-        base::TimeDelta::FromMilliseconds(i * 100));
+    main_tq->PostDelayedTask(FROM_HERE,
+                             base::Bind(&RecordTimeTask, &run_times, &now_src_),
+                             base::TimeDelta::FromMilliseconds(i * 100));
   }
   test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(250));
 
diff --git a/third_party/WebKit/Source/platform/scheduler/base/test_time_source.cc b/third_party/WebKit/Source/platform/scheduler/base/test_time_source.cc
deleted file mode 100644
index ea193a4..0000000
--- a/third_party/WebKit/Source/platform/scheduler/base/test_time_source.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "platform/scheduler/base/test_time_source.h"
-
-namespace blink {
-namespace scheduler {
-
-TestTimeSource::TestTimeSource(base::SimpleTestTickClock* time_source)
-    : time_source_(time_source) {
-  DCHECK(time_source_);
-}
-
-TestTimeSource::~TestTimeSource() {}
-
-base::TimeTicks TestTimeSource::NowTicks() {
-  return time_source_->NowTicks();
-}
-
-}  // namespace scheduler
-}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/base/test_time_source.h b/third_party/WebKit/Source/platform/scheduler/base/test_time_source.h
deleted file mode 100644
index 4e3c2ae..0000000
--- a/third_party/WebKit/Source/platform/scheduler/base/test_time_source.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
-#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
-
-#include "base/macros.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/time/tick_clock.h"
-
-namespace blink {
-namespace scheduler {
-
-class TestTimeSource : public base::TickClock {
- public:
-  explicit TestTimeSource(base::SimpleTestTickClock* time_source);
-  ~TestTimeSource() override;
-
-  base::TimeTicks NowTicks() override;
-
- private:
-  // Not owned.
-  base::SimpleTestTickClock* time_source_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestTimeSource);
-};
-
-}  // namespace scheduler
-}  // namespace blink
-
-#endif  // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TEST_TIME_SOURCE_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc
index 2a4542a..4270502 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc
@@ -18,12 +18,12 @@
 ThreadControllerImpl::ThreadControllerImpl(
     base::MessageLoop* message_loop,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    std::unique_ptr<base::TickClock> time_source)
+    base::TickClock* time_source)
     : message_loop_(message_loop),
       task_runner_(task_runner),
       message_loop_task_runner_(message_loop ? message_loop->task_runner()
                                              : nullptr),
-      time_source_(std::move(time_source)),
+      time_source_(time_source),
       weak_factory_(this) {
   immediate_do_work_closure_ = base::BindRepeating(
       &ThreadControllerImpl::DoWork, weak_factory_.GetWeakPtr(),
@@ -37,9 +37,9 @@
 
 std::unique_ptr<ThreadControllerImpl> ThreadControllerImpl::Create(
     base::MessageLoop* message_loop,
-    std::unique_ptr<base::TickClock> time_source) {
+    base::TickClock* time_source) {
   return base::WrapUnique(new ThreadControllerImpl(
-      message_loop, message_loop->task_runner(), std::move(time_source)));
+      message_loop, message_loop->task_runner(), time_source));
 }
 
 void ThreadControllerImpl::SetSequence(Sequence* sequence) {
@@ -78,7 +78,7 @@
 }
 
 base::TickClock* ThreadControllerImpl::GetClock() {
-  return time_source_.get();
+  return time_source_;
 }
 
 void ThreadControllerImpl::SetDefaultTaskRunner(
diff --git a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h
index 31dd466..8e0f8ee9 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h
@@ -32,7 +32,7 @@
 
   static std::unique_ptr<ThreadControllerImpl> Create(
       base::MessageLoop* message_loop,
-      std::unique_ptr<base::TickClock> time_source);
+      base::TickClock* time_source);
 
   // ThreadController:
   void ScheduleWork() override;
@@ -53,7 +53,7 @@
  protected:
   ThreadControllerImpl(base::MessageLoop* message_loop,
                        scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-                       std::unique_ptr<base::TickClock> time_source);
+                       base::TickClock* time_source);
 
   // TODO(altimin): Make these const. Blocked on removing
   // lazy initialisation support.
@@ -66,7 +66,7 @@
   SEQUENCE_CHECKER(sequence_checker_);
 
   scoped_refptr<base::SingleThreadTaskRunner> message_loop_task_runner_;
-  std::unique_ptr<base::TickClock> time_source_;
+  base::TickClock* time_source_;
   base::RepeatingClosure immediate_do_work_closure_;
   base::RepeatingClosure delayed_do_work_closure_;
   base::CancelableClosure cancelable_delayed_do_work_closure_;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc
index 2d67736..b35203d 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain_unittest.cc
@@ -11,7 +11,6 @@
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/scheduler/base/task_queue_impl.h"
 #include "platform/scheduler/base/task_queue_manager.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/base/work_queue.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
diff --git a/third_party/WebKit/Source/platform/scheduler/child/DEPS b/third_party/WebKit/Source/platform/scheduler/child/DEPS
index 62f1124b..20ff8ba 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/DEPS
+++ b/third_party/WebKit/Source/platform/scheduler/child/DEPS
@@ -4,7 +4,7 @@
 ]
 
 specific_include_rules = {
-  "(test_time_source|.*test)\.cc": [
+  ".*test\.cc": [
     "+components/viz/test",
   ],
 }
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc
index 2edc688..6209b36 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc
@@ -9,7 +9,6 @@
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/scheduler/base/lazy_now.h"
 #include "platform/scheduler/base/task_queue.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/child/idle_helper.h"
 #include "platform/scheduler/child/scheduler_helper.h"
 #include "platform/scheduler/renderer/main_thread_scheduler_helper.h"
@@ -32,12 +31,11 @@
                                            public IdleHelper::Delegate {
  public:
   IdleCanceledDelayedTaskSweeperTest()
-      : clock_(new base::SimpleTestTickClock()),
-        mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_.get(), true)),
+      : mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)),
         scheduler_helper_(new MainThreadSchedulerHelper(
             CreateTaskQueueManagerWithUnownedClockForTest(nullptr,
                                                           mock_task_runner_,
-                                                          clock_.get()),
+                                                          &clock_),
             nullptr)),
         idle_helper_(
             new IdleHelper(scheduler_helper_.get(),
@@ -51,7 +49,7 @@
             new IdleCanceledDelayedTaskSweeper(scheduler_helper_.get(),
                                                idle_helper_->IdleTaskRunner())),
         default_task_queue_(scheduler_helper_->DefaultMainThreadTaskQueue()) {
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   ~IdleCanceledDelayedTaskSweeperTest() override {}
@@ -75,7 +73,7 @@
   void OnPendingTasksChanged(bool has_tasks) {}
 
  protected:
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
 
   std::unique_ptr<MainThreadSchedulerHelper> scheduler_helper_;
@@ -124,7 +122,7 @@
   // Give the IdleCanceledDelayedTaskSweeper a chance to run but don't let
   // the first non canceled delayed task run.  This is important because the
   // canceled tasks would get removed by TaskQueueImpl::WakeUpForDelayedWork.
-  clock_->Advance(base::TimeDelta::FromSeconds(40));
+  clock_.Advance(base::TimeDelta::FromSeconds(40));
   idle_helper_->EnableLongIdlePeriod();
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(40));
 
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc
index 0fabb81..5b639caa 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc
@@ -17,7 +17,6 @@
 #include "platform/scheduler/base/real_time_domain.h"
 #include "platform/scheduler/base/task_queue.h"
 #include "platform/scheduler/base/task_queue_manager.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/child/scheduler_helper.h"
 #include "platform/scheduler/child/worker_scheduler_helper.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
@@ -193,17 +192,15 @@
   BaseIdleHelperTest(
       base::MessageLoop* message_loop,
       base::TimeDelta required_quiescence_duration_before_long_idle_period)
-      : clock_(new base::SimpleTestTickClock()),
-        mock_task_runner_(
-            message_loop
-                ? nullptr
-                : new cc::OrderedSimpleTaskRunner(clock_.get(), false)),
+      : mock_task_runner_(
+            message_loop ? nullptr
+                         : new cc::OrderedSimpleTaskRunner(&clock_, false)),
         message_loop_(message_loop),
         scheduler_helper_(new WorkerSchedulerHelper(
             CreateTaskQueueManagerWithUnownedClockForTest(
                 message_loop,
                 message_loop ? message_loop->task_runner() : mock_task_runner_,
-                clock_.get()),
+                &clock_),
             nullptr)),
         idle_helper_(new IdleHelperForTest(
             scheduler_helper_.get(),
@@ -211,7 +208,7 @@
             scheduler_helper_->NewTaskQueue(TaskQueue::Spec("idle_test")))),
         default_task_runner_(scheduler_helper_->DefaultWorkerTaskQueue()),
         idle_task_runner_(idle_helper_->IdleTaskRunner()) {
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   ~BaseIdleHelperTest() override {}
@@ -300,7 +297,7 @@
     return idle_helper_->idle_queue_;
   }
 
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   // Only one of mock_task_runner_ or message_loop_ will be set.
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<base::MessageLoop> message_loop_;
@@ -330,10 +327,10 @@
 TEST_F(IdleHelperTest, TestPostIdleTask) {
   int run_count = 0;
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(2300);
   base::TimeTicks deadline_in_task;
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(100));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
@@ -341,7 +338,7 @@
   EXPECT_EQ(0, run_count);
 
   idle_helper_->StartIdlePeriod(IdleHelper::IdlePeriodState::kInShortIdlePeriod,
-                                clock_->NowTicks(), expected_deadline);
+                                clock_.NowTicks(), expected_deadline);
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
   EXPECT_EQ(expected_deadline, deadline_in_task);
@@ -351,7 +348,7 @@
   int run_count = 0;
   base::TimeTicks deadline_in_task;
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(100));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
@@ -359,8 +356,8 @@
   EXPECT_EQ(0, run_count);
 
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   idle_helper_->EndIdlePeriod();
   RunUntilIdle();
   EXPECT_EQ(0, run_count);
@@ -376,8 +373,8 @@
       base::Bind(&RepostingIdleTestTask, base::RetainedRef(idle_task_runner_),
                  &run_count, &actual_deadline));
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 
@@ -386,8 +383,8 @@
   EXPECT_EQ(1, run_count);
 
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   RunUntilIdle();
   EXPECT_EQ(2, run_count);
 }
@@ -398,22 +395,22 @@
   // Post two UpdateClockToDeadlineIdleTestTask tasks.
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
-      base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_.get(), &run_count));
+      base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count));
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
-      base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_.get(), &run_count));
+      base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count));
 
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   RunUntilIdle();
   // Only the first idle task should execute since it's used up the deadline.
   EXPECT_EQ(1, run_count);
 
   idle_helper_->EndIdlePeriod();
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   RunUntilIdle();
   // Second task should be run on the next idle period.
   EXPECT_EQ(2, run_count);
@@ -453,8 +450,8 @@
   ExpectIdlePeriodStartsButNeverEnds();
 
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
 }
 
 TEST_F(IdleHelperTestWithIdlePeriodObserver, TestEnterAndExitIdlePeriod) {
@@ -469,8 +466,8 @@
   ExpectIdlePeriodStartsAndEnds(Exactly(1));
 
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   idle_helper_->EndIdlePeriod();
 }
 
@@ -486,14 +483,15 @@
     base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get());
     for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) {
       if (pair.second) {
-        idle_task_runner_->PostIdleTask(FROM_HERE, pair.first);
+        idle_task_runner_->PostIdleTask(FROM_HERE, std::move(pair.first));
       } else {
-        idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first);
+        idle_task_runner_->PostNonNestableIdleTask(FROM_HERE,
+                                                   std::move(pair.first));
       }
     }
     idle_helper_->StartIdlePeriod(
-        IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-        clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+        IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+        clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
     base::RunLoop().RunUntilIdle();
   }
 
@@ -533,8 +531,8 @@
                  base::Unretained(&tasks_to_post_from_nested_loop)));
 
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   RunUntilIdle();
   // Note we expect task 3 to run last because it's non-nestable.
   EXPECT_THAT(order, ::testing::ElementsAre(std::string("1"), std::string("2"),
@@ -544,7 +542,7 @@
 
 TEST_F(IdleHelperTestWithIdlePeriodObserver, TestLongIdlePeriod) {
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + maximum_idle_period_duration();
+      clock_.NowTicks() + maximum_idle_period_duration();
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
@@ -567,7 +565,7 @@
 
 TEST_F(IdleHelperTest, TestLongIdlePeriodWithPendingDelayedTask) {
   base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
-  base::TimeTicks expected_deadline = clock_->NowTicks() + pending_task_delay;
+  base::TimeTicks expected_deadline = clock_.NowTicks() + pending_task_delay;
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
@@ -591,7 +589,7 @@
                                         pending_task_delay);
 
   // Advance clock until after delayed task was meant to be run.
-  clock_->Advance(base::TimeDelta::FromMilliseconds(20));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(20));
 
   // Post an idle task and then EnableLongIdlePeriod. Since there is a late
   // pending delayed task this shouldn't actually start an idle period.
@@ -602,7 +600,7 @@
   EXPECT_EQ(0, run_count);
 
   // After the delayed task has been run we should trigger an idle period.
-  clock_->Advance(maximum_idle_period_duration());
+  clock_.Advance(maximum_idle_period_duration());
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 }
@@ -618,13 +616,12 @@
   ExpectIdlePeriodStartsAndEnds(AtLeast(2));
 
   g_max_idle_task_reposts = 3;
-  base::TimeTicks clock_before(clock_->NowTicks());
+  base::TimeTicks clock_before(clock_.NowTicks());
   base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::Bind(&RepostingUpdateClockIdleTestTask,
-                 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
-                 idle_task_runtime, &actual_deadlines));
+      FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
+                            base::RetainedRef(idle_task_runner_), &run_count,
+                            &clock_, idle_task_runtime, &actual_deadlines));
 
   // Check each idle task runs in their own idle period.
   idle_helper_->EnableLongIdlePeriod();
@@ -638,10 +635,9 @@
 
   g_max_idle_task_reposts = 5;
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::Bind(&RepostingUpdateClockIdleTestTask,
-                 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
-                 idle_task_runtime, &actual_deadlines));
+      FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
+                            base::RetainedRef(idle_task_runner_), &run_count,
+                            &clock_, idle_task_runtime, &actual_deadlines));
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
       base::Bind(&EndIdlePeriodIdleTask, base::Unretained(idle_helper_.get())));
@@ -655,7 +651,7 @@
        TestLongIdlePeriodWhenNotCanEnterLongIdlePeriod) {
   base::TimeDelta delay = base::TimeDelta::FromMilliseconds(1000);
   base::TimeDelta half_delay = base::TimeDelta::FromMilliseconds(500);
-  base::TimeTicks delay_over = clock_->NowTicks() + delay;
+  base::TimeTicks delay_over = clock_.NowTicks() + delay;
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
@@ -681,12 +677,12 @@
   RunUntilIdle();
   EXPECT_EQ(0, run_count);
 
-  clock_->Advance(half_delay);
+  clock_.Advance(half_delay);
   RunUntilIdle();
   EXPECT_EQ(0, run_count);
 
   // Delay is finished, idle task should run.
-  clock_->Advance(half_delay);
+  clock_.Advance(half_delay);
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 }
@@ -698,17 +694,16 @@
   std::vector<base::TimeTicks> actual_deadlines;
   int run_count = 0;
 
-  base::TimeTicks clock_before(clock_->NowTicks());
+  base::TimeTicks clock_before(clock_.NowTicks());
   base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
 
   // The second idle period should happen immediately after the first the
   // they have max deadlines.
   g_max_idle_task_reposts = 2;
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::Bind(&RepostingUpdateClockIdleTestTask,
-                 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
-                 idle_task_runtime, &actual_deadlines));
+      FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
+                            base::RetainedRef(idle_task_runner_), &run_count,
+                            &clock_, idle_task_runtime, &actual_deadlines));
 
   idle_helper_->EnableLongIdlePeriod();
   RunUntilIdle();
@@ -725,7 +720,7 @@
 
   base::TimeDelta pending_task_delay(base::TimeDelta::FromMilliseconds(20));
   base::TimeDelta idle_task_duration(base::TimeDelta::FromMilliseconds(10));
-  base::TimeTicks expected_deadline(clock_->NowTicks() + pending_task_delay +
+  base::TimeTicks expected_deadline(clock_.NowTicks() + pending_task_delay +
                                     maximum_idle_period_duration() +
                                     retry_enable_long_idle_period_delay());
 
@@ -741,18 +736,18 @@
   idle_helper_->EnableLongIdlePeriod();
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
-  clock_->Advance(idle_task_duration);
+  clock_.Advance(idle_task_duration);
 
   // Next idle period shouldn't happen until the pending task has been run.
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 
   // Once the pending task is run the new idle period should start.
-  clock_->Advance(pending_task_delay - idle_task_duration);
+  clock_.Advance(pending_task_delay - idle_task_duration);
 
   // Since the idle period tried to start before the pending task ran we have to
   // wait for the idle helper to retry starting the long idle period.
-  clock_->Advance(retry_enable_long_idle_period_delay());
+  clock_.Advance(retry_enable_long_idle_period_delay());
   RunUntilIdle();
 
   EXPECT_EQ(2, run_count);
@@ -774,13 +769,12 @@
 
   // Posting a task should transition us to the an active state.
   g_max_idle_task_reposts = 2;
-  base::TimeTicks clock_before(clock_->NowTicks());
+  base::TimeTicks clock_before(clock_.NowTicks());
   base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::Bind(&RepostingUpdateClockIdleTestTask,
-                 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
-                 idle_task_runtime, &actual_deadlines));
+      FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
+                            base::RetainedRef(idle_task_runner_), &run_count,
+                            &clock_, idle_task_runtime, &actual_deadlines));
   RunUntilIdle();
   EXPECT_EQ(2, run_count);
   EXPECT_THAT(actual_deadlines,
@@ -834,8 +828,8 @@
       base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, idle_helper_.get(),
                  &can_exceed_idle_deadline, &run_count));
   idle_helper_->StartIdlePeriod(
-      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_->NowTicks(),
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(10));
+      IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(),
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10));
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
   EXPECT_FALSE(can_exceed_idle_deadline);
@@ -855,7 +849,7 @@
 
   // Next long idle period will be for the maximum time, so
   // CanExceedIdleDeadlineIfRequired should return true.
-  clock_->Advance(maximum_idle_period_duration());
+  clock_.Advance(maximum_idle_period_duration());
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
       base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, idle_helper_.get(),
@@ -970,8 +964,8 @@
   // In this scenario EnableLongIdlePeriod deems us not to be quiescent 5x in
   // a row.
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(
-                               5 * kQuiescenceDelayMs + kLongIdlePeriodMs);
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(
+                              5 * kQuiescenceDelayMs + kLongIdlePeriodMs);
   base::TimeTicks deadline_in_task;
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
@@ -999,7 +993,7 @@
   int run_count = 0;
   base::TimeTicks deadline_in_task;
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() +
+      clock_.NowTicks() +
       base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs + kLongIdlePeriodMs);
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
@@ -1019,17 +1013,17 @@
 
   base::TimeDelta half_a_ms(base::TimeDelta::FromMicroseconds(50));
   base::TimeTicks less_than_min_deadline(
-      clock_->NowTicks() + minimum_idle_period_duration() - half_a_ms);
+      clock_.NowTicks() + minimum_idle_period_duration() - half_a_ms);
   base::TimeTicks more_than_min_deadline(
-      clock_->NowTicks() + minimum_idle_period_duration() + half_a_ms);
+      clock_.NowTicks() + minimum_idle_period_duration() + half_a_ms);
 
   idle_helper_->StartIdlePeriod(IdleHelper::IdlePeriodState::kInShortIdlePeriod,
-                                clock_->NowTicks(), less_than_min_deadline);
+                                clock_.NowTicks(), less_than_min_deadline);
   RunUntilIdle();
   EXPECT_EQ(0, run_count);
 
   idle_helper_->StartIdlePeriod(IdleHelper::IdlePeriodState::kInShortIdlePeriod,
-                                clock_->NowTicks(), more_than_min_deadline);
+                                clock_.NowTicks(), more_than_min_deadline);
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 }
@@ -1054,7 +1048,7 @@
   EXPECT_EQ(0, run_count);
 
   idle_helper_->EndIdlePeriod();
-  clock_->Advance(maximum_idle_period_duration());
+  clock_.Advance(maximum_idle_period_duration());
   RunUntilIdle();
   EXPECT_EQ(0, run_count);
 
@@ -1081,7 +1075,7 @@
 
   // Delayed call to IdleHelper::EnableLongIdlePeriod enables idle tasks.
   idle_helper_->EnableLongIdlePeriod();
-  clock_->Advance(maximum_idle_period_duration() * 2.0);
+  clock_.Advance(maximum_idle_period_duration() * 2.0);
   mock_task_runner_->RunPendingTasks();
   EXPECT_TRUE(shutdown_task_run);
   EXPECT_EQ(0, run_count);
@@ -1096,7 +1090,7 @@
 TEST_F(IdleHelperTest, TestPostDelayedIdleTask) {
   int run_count = 0;
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(2300);
   base::TimeTicks deadline_in_task;
 
   // Posting a delayed idle task should not post anything on the underlying
@@ -1106,18 +1100,18 @@
       base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
   EXPECT_EQ(0u, idle_queue()->GetNumberOfPendingTasks());
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(100));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
 
   // It shouldn't run until the delay is over even though we went idle.
   idle_helper_->StartIdlePeriod(IdleHelper::IdlePeriodState::kInShortIdlePeriod,
-                                clock_->NowTicks(), expected_deadline);
+                                clock_.NowTicks(), expected_deadline);
   EXPECT_EQ(0u, idle_queue()->GetNumberOfPendingTasks());
   RunUntilIdle();
   EXPECT_EQ(0, run_count);
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(100));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
   idle_helper_->StartIdlePeriod(IdleHelper::IdlePeriodState::kInShortIdlePeriod,
-                                clock_->NowTicks(), expected_deadline);
+                                clock_.NowTicks(), expected_deadline);
   EXPECT_EQ(1u, idle_queue()->GetNumberOfPendingTasks());
   RunUntilIdle();
 
@@ -1130,7 +1124,7 @@
 TEST_F(IdleHelperTest, OnPendingTasksChanged) {
   int run_count = 0;
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(2300);
   base::TimeTicks deadline_in_task;
 
   {
@@ -1141,7 +1135,7 @@
     EXPECT_CALL(*idle_helper_, OnPendingTasksChanged(false)).Times(1);
   }
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(100));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
@@ -1149,7 +1143,7 @@
   EXPECT_EQ(0, run_count);
 
   idle_helper_->StartIdlePeriod(IdleHelper::IdlePeriodState::kInShortIdlePeriod,
-                                clock_->NowTicks(), expected_deadline);
+                                clock_.NowTicks(), expected_deadline);
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
   EXPECT_EQ(expected_deadline, deadline_in_task);
@@ -1160,7 +1154,7 @@
 TEST_F(IdleHelperTest, OnPendingTasksChanged_TwoTasksAtTheSameTime) {
   int run_count = 0;
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(2300);
   base::TimeTicks deadline_in_task;
 
   {
@@ -1172,7 +1166,7 @@
     EXPECT_CALL(*idle_helper_, OnPendingTasksChanged(false)).Times(1);
   }
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(100));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
   idle_task_runner_->PostIdleTask(
@@ -1182,7 +1176,7 @@
   EXPECT_EQ(0, run_count);
 
   idle_helper_->StartIdlePeriod(IdleHelper::IdlePeriodState::kInShortIdlePeriod,
-                                clock_->NowTicks(), expected_deadline);
+                                clock_.NowTicks(), expected_deadline);
   RunUntilIdle();
   EXPECT_EQ(2, run_count);
   EXPECT_EQ(expected_deadline, deadline_in_task);
diff --git a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc
index a015bccb..496d972 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc
@@ -13,7 +13,6 @@
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/scheduler/base/lazy_now.h"
 #include "platform/scheduler/base/task_queue.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/child/worker_scheduler_helper.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -52,15 +51,14 @@
 class SchedulerHelperTest : public ::testing::Test {
  public:
   SchedulerHelperTest()
-      : clock_(new base::SimpleTestTickClock()),
-        mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_.get(), false)),
+      : mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, false)),
         scheduler_helper_(new WorkerSchedulerHelper(
             CreateTaskQueueManagerWithUnownedClockForTest(nullptr,
                                                           mock_task_runner_,
-                                                          clock_.get()),
+                                                          &clock_),
             nullptr)),
         default_task_runner_(scheduler_helper_->DefaultWorkerTaskQueue()) {
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   ~SchedulerHelperTest() override {}
@@ -85,7 +83,7 @@
   }
 
  protected:
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
 
   std::unique_ptr<WorkerSchedulerHelper> scheduler_helper_;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/single_thread_idle_task_runner.cc b/third_party/WebKit/Source/platform/scheduler/child/single_thread_idle_task_runner.cc
index 9a63a56..f9b56ac 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/single_thread_idle_task_runner.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/single_thread_idle_task_runner.cc
@@ -35,31 +35,33 @@
 }
 
 void SingleThreadIdleTaskRunner::PostIdleTask(const base::Location& from_here,
-                                              const IdleTask& idle_task) {
+                                              IdleTask idle_task) {
   delegate_->OnIdleTaskPosted();
   idle_priority_task_runner_->PostTask(
-      from_here, base::Bind(&SingleThreadIdleTaskRunner::RunTask,
-                            weak_scheduler_ptr_, idle_task));
+      from_here, base::BindOnce(&SingleThreadIdleTaskRunner::RunTask,
+                                weak_scheduler_ptr_, std::move(idle_task)));
 }
 
 void SingleThreadIdleTaskRunner::PostDelayedIdleTask(
     const base::Location& from_here,
     const base::TimeDelta delay,
-    const IdleTask& idle_task) {
+    IdleTask idle_task) {
   base::TimeTicks first_run_time = delegate_->NowTicks() + delay;
   delayed_idle_tasks_.insert(std::make_pair(
       first_run_time,
-      std::make_pair(from_here, base::Bind(&SingleThreadIdleTaskRunner::RunTask,
-                                           weak_scheduler_ptr_, idle_task))));
+      std::make_pair(
+          from_here,
+          base::BindOnce(&SingleThreadIdleTaskRunner::RunTask,
+                         weak_scheduler_ptr_, std::move(idle_task)))));
 }
 
 void SingleThreadIdleTaskRunner::PostNonNestableIdleTask(
     const base::Location& from_here,
-    const IdleTask& idle_task) {
+    IdleTask idle_task) {
   delegate_->OnIdleTaskPosted();
   idle_priority_task_runner_->PostNonNestableTask(
-      from_here, base::Bind(&SingleThreadIdleTaskRunner::RunTask,
-                            weak_scheduler_ptr_, idle_task));
+      from_here, base::BindOnce(&SingleThreadIdleTaskRunner::RunTask,
+                                weak_scheduler_ptr_, std::move(idle_task)));
 }
 
 void SingleThreadIdleTaskRunner::EnqueueReadyDelayedIdleTasks() {
@@ -83,7 +85,7 @@
                (deadline - base::TimeTicks::Now()).InMillisecondsF());
   if (blame_context_)
     blame_context_->Enter();
-  idle_task.Run(deadline);
+  std::move(idle_task).Run(deadline);
   if (blame_context_)
     blame_context_->Leave();
   delegate_->DidProcessIdleTask();
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler.h b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler.h
index c5d987b..baf4780 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler.h
+++ b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler.h
@@ -58,7 +58,7 @@
   // tasks which may be reordered relative to other task types and may be
   // starved for an arbitrarily long time if no idle time is available.
   // Takes ownership of |IdleTask|. Can be called from any thread.
-  virtual void PostIdleTask(const WebTraceLocation&, WebThread::IdleTask*) = 0;
+  virtual void PostIdleTask(const WebTraceLocation&, WebThread::IdleTask) = 0;
 
   // Like postIdleTask but guarantees that the posted task will not run
   // nested within an already-running task. Posting an idle task as
@@ -66,7 +66,7 @@
   // make it run later than it normally would, but it won't make it
   // run earlier than it normally would.
   virtual void PostNonNestableIdleTask(const WebTraceLocation&,
-                                       WebThread::IdleTask*) = 0;
+                                       WebThread::IdleTask) = 0;
 
   // Returns a WebTaskRunner for loading tasks. Can be called from any thread.
   virtual WebTaskRunner* LoadingTaskRunner() = 0;
@@ -110,14 +110,6 @@
   virtual scheduler::RendererScheduler* GetRendererSchedulerForTest() {
     return nullptr;
   }
-
-#ifdef INSIDE_BLINK
-  // Helpers for posting bound functions as tasks.
-  typedef Function<void(double deadline_seconds)> IdleTask;
-
-  void PostIdleTask(const WebTraceLocation&, IdleTask);
-  void PostNonNestableIdleTask(const WebTraceLocation&, IdleTask);
-#endif
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc
index fba7a9e..5fc381a 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.cc
@@ -44,27 +44,26 @@
   return child_scheduler_->CanExceedIdleDeadlineIfRequired();
 }
 
-void WebSchedulerImpl::RunIdleTask(
-    std::unique_ptr<blink::WebThread::IdleTask> task,
-    base::TimeTicks deadline) {
-  task->Run((deadline - base::TimeTicks()).InSecondsF());
+void WebSchedulerImpl::RunIdleTask(blink::WebThread::IdleTask task,
+                                   base::TimeTicks deadline) {
+  std::move(task).Run((deadline - base::TimeTicks()).InSecondsF());
 }
 
 void WebSchedulerImpl::PostIdleTask(const blink::WebTraceLocation& location,
-                                    blink::WebThread::IdleTask* task) {
+                                    blink::WebThread::IdleTask task) {
   DCHECK(idle_task_runner_);
   idle_task_runner_->PostIdleTask(
-      location, base::Bind(&WebSchedulerImpl::RunIdleTask,
-                           base::Passed(base::WrapUnique(task))));
+      location,
+      base::BindOnce(&WebSchedulerImpl::RunIdleTask, std::move(task)));
 }
 
 void WebSchedulerImpl::PostNonNestableIdleTask(
     const blink::WebTraceLocation& location,
-    blink::WebThread::IdleTask* task) {
+    blink::WebThread::IdleTask task) {
   DCHECK(idle_task_runner_);
   idle_task_runner_->PostNonNestableIdleTask(
-      location, base::Bind(&WebSchedulerImpl::RunIdleTask,
-                           base::Passed(base::WrapUnique(task))));
+      location,
+      base::BindOnce(&WebSchedulerImpl::RunIdleTask, std::move(task)));
 }
 
 blink::WebTaskRunner* WebSchedulerImpl::LoadingTaskRunner() {
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h
index 0a0d22c..ab30cdb 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/child/web_scheduler_impl.h
@@ -36,9 +36,9 @@
   bool ShouldYieldForHighPriorityWork() override;
   bool CanExceedIdleDeadlineIfRequired() override;
   void PostIdleTask(const WebTraceLocation& location,
-                    WebThread::IdleTask* task) override;
+                    WebThread::IdleTask task) override;
   void PostNonNestableIdleTask(const WebTraceLocation& location,
-                               WebThread::IdleTask* task) override;
+                               WebThread::IdleTask task) override;
   WebTaskRunner* LoadingTaskRunner() override;
   WebTaskRunner* TimerTaskRunner() override;
   WebTaskRunner* V8TaskRunner() override;
@@ -54,8 +54,7 @@
       scheduler::RendererScheduler::NavigatingFrameType type) override {}
 
  private:
-  static void RunIdleTask(std::unique_ptr<WebThread::IdleTask> task,
-                          base::TimeTicks deadline);
+  static void RunIdleTask(WebThread::IdleTask task, base::TimeTicks deadline);
 
   ChildScheduler* child_scheduler_;  // NOT OWNED
   scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc
index 1d19ca8..1acd091b 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc
@@ -87,17 +87,16 @@
 }
 
 // static
-void WebThreadBase::RunWebThreadIdleTask(
-    std::unique_ptr<blink::WebThread::IdleTask> idle_task,
-    base::TimeTicks deadline) {
-  idle_task->Run((deadline - base::TimeTicks()).InSecondsF());
+void WebThreadBase::RunWebThreadIdleTask(blink::WebThread::IdleTask idle_task,
+                                         base::TimeTicks deadline) {
+  std::move(idle_task).Run((deadline - base::TimeTicks()).InSecondsF());
 }
 
 void WebThreadBase::PostIdleTask(const blink::WebTraceLocation& location,
-                                 IdleTask* idle_task) {
+                                 IdleTask idle_task) {
   GetIdleTaskRunner()->PostIdleTask(
-      location, base::Bind(&WebThreadBase::RunWebThreadIdleTask,
-                           base::Passed(base::WrapUnique(idle_task))));
+      location, base::BindOnce(&WebThreadBase::RunWebThreadIdleTask,
+                               std::move(idle_task)));
 }
 
 bool WebThreadBase::IsCurrentThread() const {
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
index 3e6ccd19..01e114e 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -28,10 +28,8 @@
   MOCK_METHOD0(Run, void());
 };
 
-class MockIdleTask : public blink::WebThread::IdleTask {
+class MockIdleTask {
  public:
-  ~MockIdleTask() override {}
-
   MOCK_METHOD1(Run, void(double deadline));
 };
 
@@ -140,17 +138,19 @@
 }
 
 TEST_F(WebThreadImplForWorkerSchedulerTest, TestIdleTask) {
-  std::unique_ptr<MockIdleTask> task(new MockIdleTask());
+  MockIdleTask task;
   base::WaitableEvent completion(
       base::WaitableEvent::ResetPolicy::AUTOMATIC,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
 
-  EXPECT_CALL(*task, Run(_));
-  ON_CALL(*task, Run(_)).WillByDefault(Invoke([&completion](double) {
+  EXPECT_CALL(task, Run(_));
+  ON_CALL(task, Run(_)).WillByDefault(Invoke([&completion](double) {
     completion.Signal();
   }));
 
-  thread_->PostIdleTask(BLINK_FROM_HERE, task.release());
+  thread_->PostIdleTask(
+      BLINK_FROM_HERE,
+      base::BindOnce(&MockIdleTask::Run, WTF::Unretained(&task)));
   // We need to post a wake-up task or idle work will never happen.
   thread_->GetWebTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE, CrossThreadBind([] {}), TimeDelta::FromMilliseconds(50));
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc
index 1b7c585..62ff5e4 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/test/simple_test_tick_clock.h"
 #include "base/test/test_simple_task_runner.h"
 #include "platform/WebTaskRunner.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/child/worker_scheduler_impl.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -31,13 +30,12 @@
 class WorkerGlobalScopeSchedulerTest : public ::testing::Test {
  public:
   WorkerGlobalScopeSchedulerTest()
-      : clock_(new base::SimpleTestTickClock()),
-        mock_task_runner_(new base::TestSimpleTaskRunner()),
+      : mock_task_runner_(new base::TestSimpleTaskRunner()),
         scheduler_(new WorkerSchedulerImpl(
             CreateTaskQueueManagerWithUnownedClockForTest(nullptr,
                                                           mock_task_runner_,
-                                                          clock_.get()))) {
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+                                                          &clock_))) {
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   ~WorkerGlobalScopeSchedulerTest() override {}
@@ -60,7 +58,7 @@
   }
 
  protected:
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<base::TestSimpleTaskRunner> mock_task_runner_;
 
   std::unique_ptr<WorkerSchedulerImpl> scheduler_;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc
index faaf717a..3742b45 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "components/viz/test/ordered_simple_task_runner.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -91,15 +90,14 @@
 class WorkerSchedulerImplTest : public ::testing::Test {
  public:
   WorkerSchedulerImplTest()
-      : clock_(new base::SimpleTestTickClock()),
-        mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_.get(), true)),
+      : mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)),
         scheduler_(new WorkerSchedulerImplForTest(
             CreateTaskQueueManagerWithUnownedClockForTest(nullptr,
                                                           mock_task_runner_,
-                                                          clock_.get()),
-            clock_.get())),
+                                                          &clock_),
+            &clock_)),
         timeline_(nullptr) {
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   ~WorkerSchedulerImplTest() override {}
@@ -125,12 +123,12 @@
   void RunUntilIdle() {
     if (timeline_) {
       timeline_->push_back(base::StringPrintf(
-          "RunUntilIdle begin @ %d", TimeTicksToIntMs(clock_->NowTicks())));
+          "RunUntilIdle begin @ %d", TimeTicksToIntMs(clock_.NowTicks())));
     }
     mock_task_runner_->RunUntilIdle();
     if (timeline_) {
       timeline_->push_back(base::StringPrintf(
-          "RunUntilIdle end @ %d", TimeTicksToIntMs(clock_->NowTicks())));
+          "RunUntilIdle end @ %d", TimeTicksToIntMs(clock_.NowTicks())));
     }
   }
 
@@ -167,7 +165,7 @@
   }
 
  protected:
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   // Only one of mock_task_runner_ or message_loop_ will be set.
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
 
@@ -239,7 +237,7 @@
   // Post a delayed task timed to occur mid way during the long idle period.
   default_task_runner_->PostTask(
       FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
-                            base::Unretained(clock_.get())));
+                            base::Unretained(&clock_)));
   RunUntilIdle();
 
   timeline.push_back("Post idle task");
@@ -267,8 +265,9 @@
   timeline.push_back("Post delayed and idle tasks");
   // Post a delayed task timed to occur mid way during the long idle period.
   default_task_runner_->PostDelayedTask(
-      FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
-                            base::Unretained(clock_.get())),
+      FROM_HERE,
+      base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
+                 base::Unretained(&clock_)),
       base::TimeDelta::FromMilliseconds(20));
   idle_task_runner_->PostIdleTask(FROM_HERE,
                                   base::Bind(&TimelineIdleTestTask, &timeline));
@@ -293,8 +292,9 @@
   timeline.push_back("Post delayed and idle tasks");
   // Post a delayed task timed to occur well after the long idle period.
   default_task_runner_->PostDelayedTask(
-      FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
-                            base::Unretained(clock_.get())),
+      FROM_HERE,
+      base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
+                 base::Unretained(&clock_)),
       base::TimeDelta::FromMilliseconds(500));
   idle_task_runner_->PostIdleTask(FROM_HERE,
                                   base::Bind(&TimelineIdleTestTask, &timeline));
@@ -348,7 +348,7 @@
   // idle period.
   base::TimeTicks idle_period_deadline =
       scheduler_->CurrentIdleTaskDeadlineForTesting();
-  clock_->Advance(maximum_idle_period_duration());
+  clock_.Advance(maximum_idle_period_duration());
   RunUntilIdle();
 
   base::TimeTicks new_idle_period_deadline =
@@ -359,9 +359,10 @@
   // 300ms pause will occur before the next long idle period is initiated and
   // the idle task run.
   default_task_runner_->PostDelayedTask(
-      FROM_HERE, base::Bind(&PostIdleTask, base::Unretained(&timeline),
-                            base::Unretained(clock_.get()),
-                            base::Unretained(idle_task_runner_.get())),
+      FROM_HERE,
+      base::Bind(&PostIdleTask, base::Unretained(&timeline),
+                 base::Unretained(&clock_),
+                 base::Unretained(idle_task_runner_.get())),
       base::TimeDelta::FromMilliseconds(30));
 
   timeline.push_back("PostFirstIdleTask");
@@ -374,7 +375,7 @@
   timeline.push_back("Post RecordTimelineTask");
   default_task_runner_->PostTask(
       FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline),
-                            base::Unretained(clock_.get())));
+                            base::Unretained(&clock_)));
   RunUntilIdle();
 
   std::string expected_timeline[] = {"RunUntilIdle begin @ 55",
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc
index ddc3c911..bc8d0ef 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc
@@ -9,7 +9,6 @@
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/scheduler/base/task_queue_manager.h"
 #include "platform/scheduler/base/test_task_time_observer.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/child/worker_scheduler_helper.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "platform/scheduler/test/test_task_queue.h"
@@ -27,21 +26,19 @@
   ~AutoAdvancingVirtualTimeDomainTest() override {}
 
   void SetUp() override {
-    clock_.reset(new base::SimpleTestTickClock());
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
 
-    test_time_source_.reset(new TestTimeSource(clock_.get()));
     mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), false);
+        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false);
 
     scheduler_helper_.reset(
         new WorkerSchedulerHelper(CreateTaskQueueManagerWithUnownedClockForTest(
-                                      nullptr, mock_task_runner_, clock_.get()),
+                                      nullptr, mock_task_runner_, &clock_),
                                   nullptr));
 
     scheduler_helper_->AddTaskTimeObserver(&test_task_time_observer_);
     task_queue_ = scheduler_helper_->DefaultWorkerTaskQueue();
-    initial_time_ = clock_->NowTicks();
+    initial_time_ = clock_.NowTicks();
     auto_advancing_time_domain_.reset(new AutoAdvancingVirtualTimeDomain(
         initial_time_, scheduler_helper_.get()));
     scheduler_helper_->RegisterTimeDomain(auto_advancing_time_domain_.get());
@@ -54,8 +51,7 @@
   }
 
   base::TimeTicks initial_time_;
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
-  std::unique_ptr<TestTimeSource> test_time_source_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<WorkerSchedulerHelper> scheduler_helper_;
   scoped_refptr<TaskQueue> task_queue_;
@@ -87,7 +83,7 @@
   EXPECT_CALL(mock_observer, OnVirtualTimeAdvanced());
   mock_task_runner_->RunUntilIdle();
 
-  EXPECT_EQ(initial_time_, clock_->NowTicks());
+  EXPECT_EQ(initial_time_, clock_.NowTicks());
   EXPECT_EQ(initial_time_ + delay,
             auto_advancing_time_domain_->CreateLazyNow().Now());
   EXPECT_TRUE(task_run);
@@ -109,7 +105,7 @@
   EXPECT_CALL(mock_observer, OnVirtualTimeAdvanced()).Times(0);
   mock_task_runner_->RunUntilIdle();
 
-  EXPECT_EQ(initial_time_, clock_->NowTicks());
+  EXPECT_EQ(initial_time_, clock_.NowTicks());
   EXPECT_EQ(initial_time_, auto_advancing_time_domain_->CreateLazyNow().Now());
   EXPECT_FALSE(task_run);
 
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc
index 0cb11010..dcc5d88 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/test/simple_test_tick_clock.h"
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/scheduler/base/task_queue_impl.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/budget_pool.h"
 #include "platform/scheduler/renderer/cpu_time_budget_pool.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
@@ -31,15 +30,14 @@
   ~BudgetPoolTest() override {}
 
   void SetUp() override {
-    clock_.reset(new base::SimpleTestTickClock());
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
     mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), true);
+        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true);
     scheduler_.reset(
         new RendererSchedulerImpl(CreateTaskQueueManagerWithUnownedClockForTest(
-            nullptr, mock_task_runner_, clock_.get())));
+            nullptr, mock_task_runner_, &clock_)));
     task_queue_throttler_ = scheduler_->task_queue_throttler();
-    start_time_ = clock_->NowTicks();
+    start_time_ = clock_.NowTicks();
   }
 
   void TearDown() override {
@@ -56,7 +54,7 @@
   }
 
  protected:
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<RendererSchedulerImpl> scheduler_;
   TaskQueueThrottler* task_queue_throttler_;  // NOT OWNED
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc
index 5946cc8..520f29ed 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/idle_time_estimator_unittest.cc
@@ -11,7 +11,6 @@
 #include "platform/scheduler/base/task_queue.h"
 #include "platform/scheduler/base/task_queue_manager.h"
 #include "platform/scheduler/base/test_task_time_observer.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "platform/scheduler/test/test_task_queue.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -24,11 +23,11 @@
  public:
   IdleTimeEstimatorForTest(
       const scoped_refptr<TaskQueue>& compositor_task_runner,
-      TestTimeSource* test_time_source,
+      base::TickClock* clock,
       int sample_count,
       double estimation_percentile)
       : IdleTimeEstimator(compositor_task_runner,
-                          test_time_source,
+                          clock,
                           sample_count,
                           estimation_percentile) {}
 };
@@ -41,17 +40,15 @@
   ~IdleTimeEstimatorTest() override {}
 
   void SetUp() override {
-    clock_.reset(new base::SimpleTestTickClock());
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
-    test_time_source_.reset(new TestTimeSource(clock_.get()));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
     mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), false);
+        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false);
     manager_ = CreateTaskQueueManagerWithUnownedClockForTest(
-        nullptr, mock_task_runner_, clock_.get());
+        nullptr, mock_task_runner_, &clock_);
     compositor_task_queue_ =
         manager_->CreateTaskQueue<TestTaskQueue>(TaskQueue::Spec("test_tq"));
-    estimator_.reset(new IdleTimeEstimatorForTest(
-        compositor_task_queue_, test_time_source_.get(), 10, 50));
+    estimator_.reset(
+        new IdleTimeEstimatorForTest(compositor_task_queue_, &clock_, 10, 50));
   }
 
   void SimulateFrameWithOneCompositorTask(int compositor_time) {
@@ -59,11 +56,11 @@
         base::TimeDelta::FromMilliseconds(compositor_time);
     base::PendingTask task(FROM_HERE, base::Closure());
     estimator_->WillProcessTask(task);
-    clock_->Advance(non_idle_time);
+    clock_.Advance(non_idle_time);
     estimator_->DidCommitFrameToCompositor();
     estimator_->DidProcessTask(task);
     if (non_idle_time < frame_length_)
-      clock_->Advance(frame_length_ - non_idle_time);
+      clock_.Advance(frame_length_ - non_idle_time);
   }
 
   void SimulateFrameWithTwoCompositorTasks(int compositor_time1,
@@ -74,20 +71,19 @@
         base::TimeDelta::FromMilliseconds(compositor_time2);
     base::PendingTask task(FROM_HERE, base::Closure());
     estimator_->WillProcessTask(task);
-    clock_->Advance(non_idle_time1);
+    clock_.Advance(non_idle_time1);
     estimator_->DidProcessTask(task);
 
     estimator_->WillProcessTask(task);
-    clock_->Advance(non_idle_time2);
+    clock_.Advance(non_idle_time2);
     estimator_->DidCommitFrameToCompositor();
     estimator_->DidProcessTask(task);
 
     base::TimeDelta idle_time = frame_length_ - non_idle_time1 - non_idle_time2;
-    clock_->Advance(idle_time);
+    clock_.Advance(idle_time);
   }
 
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
-  std::unique_ptr<TestTimeSource> test_time_source_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<TaskQueueManager> manager_;
   scoped_refptr<TaskQueue> compositor_task_queue_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.cc b/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.cc
index 5e07098..189a1b78 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.cc
@@ -242,6 +242,13 @@
     client->OnReportSplitExpectedQueueingTime(it.first,
                                               it.second / steps_per_window_);
   }
+  // TODO(npm): Report fine grained for other splits. See crbug.com/792965.
+  client->OnReportFineGrainedExpectedQueueingTime(
+      "RendererScheduler.ExpectedQueueingTimeByFrameStatus."
+      "MainFrameBackground",
+      delta_by_message[GetReportingMessageFromFrameStatus(
+          FrameStatus::kMainFrameBackground)] /
+          steps_per_window_);
   std::fill(eqt_by_queue_type_.begin(), eqt_by_queue_type_.end(),
             base::TimeDelta());
   std::fill(eqt_by_frame_status_.begin(), eqt_by_frame_status_.end(),
@@ -371,6 +378,10 @@
       const char* split_description,
       base::TimeDelta queueing_time) override {}
 
+  void OnReportFineGrainedExpectedQueueingTime(
+      const char* split_description,
+      base::TimeDelta queueing_time) override {}
+
   base::TimeDelta queueing_time() { return queueing_time_; }
 
   RecordQueueingTimeClient() {}
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.h b/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.h
index b2f25c3..1c5378d7 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator.h
@@ -28,6 +28,9 @@
     virtual void OnReportSplitExpectedQueueingTime(
         const char* split_description,
         base::TimeDelta queueing_time) = 0;
+    virtual void OnReportFineGrainedExpectedQueueingTime(
+        const char* split_description,
+        base::TimeDelta queueing_time) = 0;
     Client() {}
     virtual ~Client() {}
 
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator_unittest.cc
index 35c523b..ac56210 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/queueing_time_estimator_unittest.cc
@@ -5,7 +5,7 @@
 #include "platform/scheduler/renderer/queueing_time_estimator.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
-#include "platform/scheduler/base/test_time_source.h"
+#include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/test/fake_web_frame_scheduler.h"
 #include "platform/testing/HistogramTester.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -31,6 +31,12 @@
     if (is_disjoint_window) {
       UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration",
                           queueing_time);
+      UMA_HISTOGRAM_CUSTOM_COUNTS(
+          "RendererScheduler.ExpectedTaskQueueingDuration2",
+          queueing_time.InMicroseconds(),
+          RendererSchedulerImpl::kMinExpectedQueueingTimeBucket,
+          RendererSchedulerImpl::kMaxExpectedQueueingTimeBucket,
+          RendererSchedulerImpl::kNumberExpectedQueueingTimeBuckets);
     }
   }
   void OnReportSplitExpectedQueueingTime(
@@ -42,6 +48,15 @@
     // Mimic RendererSchedulerImpl::OnReportSplitExpectedQueueingTime.
     base::UmaHistogramTimes(split_description, queueing_time);
   }
+  void OnReportFineGrainedExpectedQueueingTime(const char* split_description,
+                                               base::TimeDelta queueing_time) {
+    // Mimic RendererSchedulerImpl::OnReportFineGrainedExpectedQueueingTime.
+    UMA_HISTOGRAM_CUSTOM_COUNTS(
+        split_description, queueing_time.InMicroseconds(),
+        RendererSchedulerImpl::kMinExpectedQueueingTimeBucket,
+        RendererSchedulerImpl::kMaxExpectedQueueingTimeBucket,
+        RendererSchedulerImpl::kNumberExpectedQueueingTimeBuckets);
+  }
   const std::vector<base::TimeDelta>& expected_queueing_times() {
     return expected_queueing_times_;
   }
@@ -80,6 +95,16 @@
 
 class QueueingTimeEstimatorTest : public ::testing::Test {
  protected:
+  static std::vector<BucketExpectation> GetFineGrained(
+      const std::vector<BucketExpectation>& expected) {
+    std::vector<BucketExpectation> fine_grained(expected.size());
+    for (size_t i = 0; i < expected.size(); ++i) {
+      fine_grained[i].sample = expected[i].sample * 1000;
+      fine_grained[i].count = expected[i].count;
+    }
+    return fine_grained;
+  }
+
   void TestHistogram(const std::string& name,
                      int total,
                      const std::vector<BucketExpectation>& expectations) {
@@ -135,6 +160,9 @@
               ::testing::ElementsAre(base::TimeDelta::FromMilliseconds(300)));
   std::vector<BucketExpectation> expected = {{300, 1}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 1, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 1,
+                fine_grained);
 }
 
 // One 20 second long task, starting 3 seconds into the first window.
@@ -172,6 +200,11 @@
   std::vector<BucketExpectation> expected = {
       {900, 1}, {5500, 1}, {7600, 1}, {10500, 2}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 5, expected);
+  // Split here is different: 4 values go into the highest bucket.
+  std::vector<BucketExpectation> fine_grained = {{900 * 1000, 1},
+                                                 {5500 * 1000, 4}};
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 5,
+                fine_grained);
 }
 
 // The main thread is considered unresponsive during a single long task. In this
@@ -199,6 +232,7 @@
   // Window time was not completed, so no UMA should be recorded.
   histogram_tester.ExpectTotalCount(
       "RendererScheduler.ExpectedTaskQueueingDuration", 0);
+  histogram_tester.ExpectTotalCount("ExpectedTaskQueueingDuration2", 0);
 }
 
 // The main thread is considered unresponsive during a single long task, which
@@ -262,6 +296,8 @@
   // completion, so UMA should not have been reported yet.
   histogram_tester.ExpectTotalCount(
       "RendererScheduler.ExpectedTaskQueueingDuration", 0);
+  histogram_tester.ExpectTotalCount(
+      "RendererScheduler.ExpectedTaskQueueingDuration2", 0);
 }
 
 //                        Estimate
@@ -300,6 +336,7 @@
   EXPECT_EQ(base::TimeDelta::FromMilliseconds(25), estimated_queueing_time);
   std::vector<BucketExpectation> expected = {{0, 1}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 1, expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 1, expected);
 }
 
 // Tasks containing nested run loops may be extremely long without
@@ -335,6 +372,9 @@
                                      base::TimeDelta::FromMilliseconds(100)));
   std::vector<BucketExpectation> expected = {{0, 1}, {100, 1}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 2, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 2,
+                fine_grained);
 }
 
 // If a task is too long, we assume it's invalid. Perhaps the user's machine
@@ -383,6 +423,9 @@
                                      base::TimeDelta::FromMilliseconds(100)));
   std::vector<BucketExpectation> expected = {{100, 2}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 2, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 2,
+                fine_grained);
 }
 
 // If we idle for too long, ignore idling time, even if the renderer is on the
@@ -429,6 +472,9 @@
                                      base::TimeDelta::FromMilliseconds(100)));
   std::vector<BucketExpectation> expected = {{100, 2}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 2, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 2,
+                fine_grained);
 }
 
 // ^ Instantaneous queuing time
@@ -525,6 +571,9 @@
               ::testing::ElementsAreArray(expected_durations));
   std::vector<BucketExpectation> expected = {{0, 1}, {725, 1}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 2, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 2,
+                fine_grained);
 }
 
 // ^ Instantaneous queuing time
@@ -582,6 +631,9 @@
               ::testing::ElementsAreArray(expected_durations));
   std::vector<BucketExpectation> expected = {{325, 1}, {400, 1}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 2, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 2,
+                fine_grained);
 }
 
 // There are multiple windows, but some of the EQTs are not reported due to
@@ -636,6 +688,9 @@
   std::vector<BucketExpectation> expected = {
       {0, 1}, {20, 1}, {125, 1}, {1000, 1}};
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 4, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 4,
+                fine_grained);
 }
 
 // We only ignore steps that contain some part that is backgrounded. Thus a
@@ -923,6 +978,9 @@
   TestHistogram("RendererScheduler.ExpectedQueueingTimeByFrameType.Other", 5,
                 expected);
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 5, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 5,
+                fine_grained);
   TestSplitSumsTotal(expected_sums, 6);
 }
 
@@ -1105,6 +1163,10 @@
   TestHistogram(
       "RendererScheduler.ExpectedQueueingTimeByFrameType.MainFrameBackground",
       5, expected);
+  std::vector<BucketExpectation> fine_grained = GetFineGrained(expected);
+  TestHistogram(
+      "RendererScheduler.ExpectedQueueingTimeByFrameStatus.MainFrameBackground",
+      5, fine_grained);
 
   EXPECT_THAT(client.FrameStatusValues(FrameStatus::kMainFrameVisible),
               ::testing::ElementsAre(base::TimeDelta::FromMilliseconds(0),
@@ -1185,6 +1247,9 @@
   TestHistogram("RendererScheduler.ExpectedQueueingTimeByTaskQueueType.Other",
                 5, expected);
   TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 5, expected);
+  fine_grained = GetFineGrained(expected);
+  TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration2", 5,
+                fine_grained);
   TestSplitSumsTotal(expected_sums, 6);
 }
 
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc
index 943b88c..5d206dfe 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/test/simple_test_tick_clock.h"
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/WebFrameScheduler.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "platform/scheduler/test/fake_web_frame_scheduler.h"
@@ -33,12 +32,11 @@
 
   void SetUp() {
     histogram_tester_.reset(new base::HistogramTester());
-    clock_ = std::make_unique<base::SimpleTestTickClock>();
     mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), true);
+        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true);
     scheduler_ = std::make_unique<RendererSchedulerImpl>(
         CreateTaskQueueManagerWithUnownedClockForTest(
-            nullptr, mock_task_runner_, clock_.get()));
+            nullptr, mock_task_runner_, &clock_));
     metrics_helper_ = &scheduler_->main_thread_only().metrics_helper;
   }
 
@@ -50,8 +48,8 @@
   void RunTask(MainThreadTaskQueue::QueueType queue_type,
                base::TimeTicks start,
                base::TimeDelta duration) {
-    DCHECK_LE(clock_->NowTicks(), start);
-    clock_->SetNowTicks(start + duration);
+    DCHECK_LE(clock_.NowTicks(), start);
+    clock_.SetNowTicks(start + duration);
     scoped_refptr<MainThreadTaskQueueForTest> queue(
         new MainThreadTaskQueueForTest(queue_type));
 
@@ -65,8 +63,8 @@
   void RunTask(WebFrameScheduler* scheduler,
                base::TimeTicks start,
                base::TimeDelta duration) {
-    DCHECK_LE(clock_->NowTicks(), start);
-    clock_->SetNowTicks(start + duration);
+    DCHECK_LE(clock_.NowTicks(), start);
+    clock_.SetNowTicks(start + duration);
     scoped_refptr<MainThreadTaskQueueForTest> queue(
         new MainThreadTaskQueueForTest(QueueType::kDefault));
     queue->SetFrameScheduler(scheduler);
@@ -191,7 +189,7 @@
     return builder.Build();
   }
 
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<RendererSchedulerImpl> scheduler_;
   RendererMetricsHelper* metrics_helper_;  // NOT OWNED
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
index a5ec4de2..acb1232 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -2249,6 +2249,10 @@
 
   UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration",
                       queueing_time);
+  UMA_HISTOGRAM_CUSTOM_COUNTS(
+      "RendererScheduler.ExpectedTaskQueueingDuration2",
+      queueing_time.InMicroseconds(), kMinExpectedQueueingTimeBucket,
+      kMaxExpectedQueueingTimeBucket, kNumberExpectedQueueingTimeBuckets);
   TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
                  "estimated_queueing_time_for_window",
                  queueing_time.InMillisecondsF());
@@ -2265,6 +2269,15 @@
   base::UmaHistogramTimes(split_description, queueing_time);
 }
 
+void RendererSchedulerImpl::OnReportFineGrainedExpectedQueueingTime(
+    const char* split_description,
+    base::TimeDelta queueing_time) {
+  base::UmaHistogramCustomCounts(
+      split_description, queueing_time.InMicroseconds(),
+      kMinExpectedQueueingTimeBucket, kMaxExpectedQueueingTimeBucket,
+      kNumberExpectedQueueingTimeBuckets);
+}
+
 AutoAdvancingVirtualTimeDomain* RendererSchedulerImpl::GetVirtualTimeDomain() {
   return virtual_time_domain_.get();
 }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
index 8da453a..c5b82d8 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.h
@@ -94,6 +94,13 @@
   static const char* RAILModeToString(v8::RAILMode rail_mode);
   static const char* VirtualTimePolicyToString(
       WebViewScheduler::VirtualTimePolicy virtual_time_policy);
+  // The lowest bucket for fine-grained Expected Queueing Time reporting.
+  static const int kMinExpectedQueueingTimeBucket = 1;
+  // The highest bucket for fine-grained Expected Queueing Time reporting, in
+  // microseconds.
+  static const int kMaxExpectedQueueingTimeBucket = 4 * 1000 * 1000;
+  // The number of buckets for fine-grained Expected Queueing Time reporting.
+  static const int kNumberExpectedQueueingTimeBuckets = 50;
 
   explicit RendererSchedulerImpl(
       std::unique_ptr<TaskQueueManager> task_queue_manager);
@@ -158,6 +165,9 @@
   // QueueingTimeEstimator::Client implementation:
   void OnQueueingTimeForWindowEstimated(base::TimeDelta queueing_time,
                                         bool is_disjoint_window) override;
+  void OnReportFineGrainedExpectedQueueingTime(
+      const char* split_description,
+      base::TimeDelta queueing_time) override;
   void OnReportSplitExpectedQueueingTime(
       const char* split_description,
       base::TimeDelta queueing_time) override;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
index 6119a3c..1663d197 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -19,7 +19,6 @@
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/WebTaskRunner.h"
 #include "platform/scheduler/base/real_time_domain.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h"
 #include "platform/scheduler/renderer/budget_pool.h"
 #include "platform/scheduler/renderer/web_frame_scheduler_impl.h"
@@ -261,32 +260,30 @@
   using UseCase = RendererSchedulerImpl::UseCase;
 
   RendererSchedulerImplTest()
-      : clock_(new base::SimpleTestTickClock()),
-        fake_task_(TaskQueue::PostedTask(base::Bind([] {}), FROM_HERE),
+      : fake_task_(TaskQueue::PostedTask(base::Bind([] {}), FROM_HERE),
                    base::TimeTicks()) {
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   RendererSchedulerImplTest(base::MessageLoop* message_loop)
-      : clock_(new base::SimpleTestTickClock()),
-        fake_task_(TaskQueue::PostedTask(base::Bind([] {}), FROM_HERE),
+      : fake_task_(TaskQueue::PostedTask(base::Bind([] {}), FROM_HERE),
                    base::TimeTicks()),
         message_loop_(message_loop) {
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   ~RendererSchedulerImplTest() override {}
 
   void SetUp() override {
     if (!message_loop_) {
-      mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(
-          clock_.get(), false);
+      mock_task_runner_ =
+          base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false);
     }
     Initialize(std::make_unique<RendererSchedulerImplForTest>(
         CreateTaskQueueManagerWithUnownedClockForTest(
             message_loop_.get(),
             message_loop_ ? message_loop_->task_runner() : mock_task_runner_,
-            clock_.get())));
+            &clock_)));
   }
 
   void Initialize(std::unique_ptr<RendererSchedulerImplForTest> scheduler) {
@@ -328,7 +325,7 @@
 
   void DoMainFrame() {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -338,7 +335,7 @@
 
   void DoMainFrameOnCriticalPath() {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -352,7 +349,7 @@
     scheduler_->DidHandleInputEventOnCompositorThread(
         FakeInputEvent(blink::WebInputEvent::kGestureScrollEnd),
         RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-    clock_->Advance(priority_escalation_after_input_duration() * 2);
+    clock_.Advance(priority_escalation_after_input_duration() * 2);
     scheduler_->ForceUpdatePolicy();
   }
 
@@ -366,7 +363,7 @@
     for (int i = 0; i < 10; i++) {
       task_runner->PostTask(FROM_HERE,
                             base::Bind(&base::SimpleTestTickClock::Advance,
-                                       base::Unretained(clock_.get()),
+                                       base::Unretained(&clock_),
                                        base::TimeDelta::FromMilliseconds(500)));
     }
 
@@ -502,7 +499,7 @@
     scheduler_->DidHandleInputEventOnCompositorThread(
         FakeInputEvent(blink::WebInputEvent::kTouchMove),
         RendererScheduler::InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-    clock_->Advance(begin_main_frame_duration);
+    clock_.Advance(begin_main_frame_duration);
     scheduler_->DidHandleInputEventOnMainThread(
         FakeInputEvent(blink::WebInputEvent::kTouchMove),
         WebInputEventResult::kHandledApplication);
@@ -511,7 +508,7 @@
 
   void SimulateMainThreadCompositorTask(
       base::TimeDelta begin_main_frame_duration) {
-    clock_->Advance(begin_main_frame_duration);
+    clock_.Advance(begin_main_frame_duration);
     scheduler_->DidCommitFrameToCompositor();
     simulate_compositor_task_ran_ = true;
   }
@@ -521,7 +518,7 @@
   }
 
   void SimulateTimerTask(base::TimeDelta duration) {
-    clock_->Advance(duration);
+    clock_.Advance(duration);
     simulate_timer_task_ran_ = true;
   }
 
@@ -569,10 +566,10 @@
   }
 
   void AdvanceTimeWithTask(double duration) {
-    base::TimeTicks start = clock_->NowTicks();
+    base::TimeTicks start = clock_.NowTicks();
     scheduler_->OnTaskStarted(fake_queue_.get(), fake_task_, start);
-    clock_->Advance(base::TimeDelta::FromSecondsD(duration));
-    base::TimeTicks end = clock_->NowTicks();
+    clock_.Advance(base::TimeDelta::FromSecondsD(duration));
+    base::TimeTicks end = clock_.NowTicks();
     scheduler_->OnTaskCompleted(fake_queue_.get(), fake_task_, start, end);
   }
 
@@ -709,7 +706,7 @@
     return scheduler->LoadingTaskQueue();
   }
 
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   TaskQueue::Task fake_task_;
   scoped_refptr<MainThreadTaskQueue> fake_queue_;
   // Only one of mock_task_runner_ or message_loop_ will be set.
@@ -764,10 +761,10 @@
 TEST_F(RendererSchedulerImplTest, TestPostIdleTask) {
   int run_count = 0;
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(2300);
   base::TimeTicks deadline_in_task;
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(100));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
 
@@ -775,22 +772,22 @@
   EXPECT_EQ(0, run_count);  // Shouldn't run yet as no WillBeginFrame.
 
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
   RunUntilIdle();
   EXPECT_EQ(0, run_count);  // Shouldn't run as no DidCommitFrameToCompositor.
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1200));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1200));
   scheduler_->DidCommitFrameToCompositor();
   RunUntilIdle();
   EXPECT_EQ(0, run_count);  // We missed the deadline.
 
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
-  clock_->Advance(base::TimeDelta::FromMilliseconds(800));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(800));
   scheduler_->DidCommitFrameToCompositor();
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
@@ -824,10 +821,10 @@
   // Post two UpdateClockToDeadlineIdleTestTask tasks.
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
-      base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_.get(), &run_count));
+      base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count));
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
-      base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_.get(), &run_count));
+      base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count));
 
   EnableIdleTasks();
   RunUntilIdle();
@@ -849,16 +846,16 @@
 
   // Trigger the beginning of an idle period for 1000ms.
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
   DoMainFrame();
 
   // End the idle period early (after 500ms), and send a WillBeginFrame which
   // specifies that the next idle period should end 1000ms from now.
-  clock_->Advance(base::TimeDelta::FromMilliseconds(500));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(500));
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
 
@@ -867,13 +864,13 @@
 
   // Trigger the start of the idle period before the task to end the previous
   // idle period has been triggered.
-  clock_->Advance(base::TimeDelta::FromMilliseconds(400));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(400));
   scheduler_->DidCommitFrameToCompositor();
 
   // Post a task which simulates running until after the previous end idle
   // period delayed task was scheduled for
   scheduler_->DefaultTaskQueue()->PostTask(FROM_HERE, base::Bind(NullTask));
-  clock_->Advance(base::TimeDelta::FromMilliseconds(300));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(300));
 
   RunUntilIdle();
   EXPECT_EQ(1, run_count);  // We should still be in the new idle period.
@@ -965,17 +962,17 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
   base::TimeTicks loop_end_time =
-      clock_->NowTicks() + base::TimeDelta::FromMilliseconds(
-                               UserModel::kMedianGestureDurationMillis * 2);
+      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(
+                              UserModel::kMedianGestureDurationMillis * 2);
 
   // The UseCase::kCompositorGesture usecase initially deprioritizes compositor
   // tasks (see TestCompositorPolicy_CompositorHandlesInput_WithTouchHandler)
   // but if the gesture is long enough, compositor tasks get prioritized again.
-  while (clock_->NowTicks() < loop_end_time) {
+  while (clock_.NowTicks() < loop_end_time) {
     scheduler_->DidHandleInputEventOnCompositorThread(
         FakeInputEvent(blink::WebInputEvent::kTouchMove),
         RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-    clock_->Advance(base::TimeDelta::FromMilliseconds(16));
+    clock_.Advance(base::TimeDelta::FromMilliseconds(16));
     RunUntilIdle();
   }
 
@@ -1310,7 +1307,7 @@
   // Advance 15s and try again, the loading policy should have ended and the
   // task order should return to the NONE use case where loading tasks are no
   // longer prioritized.
-  clock_->Advance(base::TimeDelta::FromMilliseconds(150000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(150000));
   run_order.clear();
   PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
   EnableIdleTasks();
@@ -1641,7 +1638,7 @@
   EXPECT_EQ(UseCase::kCompositorGesture,
             ForceUpdatePolicyAndGetCurrentUseCase());
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
 }
 
@@ -1652,7 +1649,7 @@
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling,
             ForceUpdatePolicyAndGetCurrentUseCase());
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
 }
 
@@ -1669,7 +1666,7 @@
                                      std::string("D1"), std::string("D2")));
 
   run_order.clear();
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
 
   // Don't post any compositor tasks to simulate a very long running event
   // handler.
@@ -1751,7 +1748,7 @@
   EXPECT_FALSE(is_anticipated_before);
   EXPECT_TRUE(is_anticipated_after);
 
-  clock_->Advance(priority_escalation_after_input_duration() * 2);
+  clock_.Advance(priority_escalation_after_input_duration() * 2);
   default_task_runner_->PostTask(
       FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
                             SimulateInputType::kNone, &is_anticipated_before,
@@ -1765,7 +1762,7 @@
   EXPECT_TRUE(is_anticipated_before);
   EXPECT_TRUE(is_anticipated_after);
 
-  clock_->Advance(subsequent_input_expected_after_input_duration() * 2);
+  clock_.Advance(subsequent_input_expected_after_input_duration() * 2);
   default_task_runner_->PostTask(
       FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(),
                             SimulateInputType::kNone, &is_anticipated_before,
@@ -1834,7 +1831,7 @@
 
   // Simulate the input event being queued for a very long time. The compositor
   // task we post here represents the enqueued input task.
-  clock_->Advance(priority_escalation_after_input_duration() * 2);
+  clock_.Advance(priority_escalation_after_input_duration() * 2);
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kGestureFlingStart),
       WebInputEventResult::kHandledSystem);
@@ -1845,7 +1842,7 @@
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
   // After the escalation period ends we should go back into normal mode.
-  clock_->Advance(priority_escalation_after_input_duration() * 2);
+  clock_.Advance(priority_escalation_after_input_duration() * 2);
   RunUntilIdle();
   EXPECT_EQ(UseCase::kNone, CurrentUseCase());
 }
@@ -1855,10 +1852,10 @@
  public:
   void SetUp() override {
     mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), false);
+        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false);
     mock_scheduler_ = new RendererSchedulerImplForTest(
         CreateTaskQueueManagerWithUnownedClockForTest(
-            nullptr, mock_task_runner_, clock_.get()));
+            nullptr, mock_task_runner_, &clock_));
     Initialize(base::WrapUnique(mock_scheduler_));
   }
 
@@ -1883,7 +1880,7 @@
   ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
 
   mock_scheduler_->ScheduleDelayedPolicyUpdate(
-      clock_->NowTicks(), base::TimeDelta::FromMilliseconds(1));
+      clock_.NowTicks(), base::TimeDelta::FromMilliseconds(1));
   mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
 
   RunUntilIdle();
@@ -1898,7 +1895,7 @@
 
   mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
   mock_scheduler_->ScheduleDelayedPolicyUpdate(
-      clock_->NowTicks(), base::TimeDelta::FromMilliseconds(1));
+      clock_.NowTicks(), base::TimeDelta::FromMilliseconds(1));
 
   RunUntilIdle();
 
@@ -1922,7 +1919,7 @@
       WebInputEventResult::kHandledSystem);
   EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
   RunUntilIdle();
 
   // We finally expect a delayed policy update 100ms later.
@@ -1974,7 +1971,7 @@
       WebInputEventResult::kHandledSystem);
   EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
   RunUntilIdle();
 
   // We finally expect a delayed policy update.
@@ -1997,7 +1994,7 @@
       WebInputEventResult::kHandledSystem);
   EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
   RunUntilIdle();
   // We expect a delayed policy update.
   EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
@@ -2016,7 +2013,7 @@
       WebInputEventResult::kHandledSystem);
   EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
 
-  clock_->Advance(base::TimeDelta::FromMilliseconds(1000));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
   RunUntilIdle();
 
   // We finally expect a delayed policy update.
@@ -2095,9 +2092,10 @@
     base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get());
     for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) {
       if (pair.second) {
-        idle_task_runner_->PostIdleTask(FROM_HERE, pair.first);
+        idle_task_runner_->PostIdleTask(FROM_HERE, std::move(pair.first));
       } else {
-        idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first);
+        idle_task_runner_->PostNonNestableIdleTask(FROM_HERE,
+                                                   std::move(pair.first));
       }
     }
     EnableIdleTasks();
@@ -2145,7 +2143,7 @@
 
 TEST_F(RendererSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) {
   base::TimeDelta ten_millis(base::TimeDelta::FromMilliseconds(10));
-  base::TimeTicks expected_deadline = clock_->NowTicks() + ten_millis;
+  base::TimeTicks expected_deadline = clock_.NowTicks() + ten_millis;
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
@@ -2155,7 +2153,7 @@
   RunUntilIdle();
   EXPECT_EQ(0, run_count);  // Shouldn't run yet as no idle period.
 
-  base::TimeTicks now = clock_->NowTicks();
+  base::TimeTicks now = clock_.NowTicks();
   base::TimeTicks frame_time = now + ten_millis;
   // No main frame is expected until frame_time, so short idle work can be
   // scheduled in the mean time.
@@ -2167,7 +2165,7 @@
 
 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) {
   base::TimeTicks expected_deadline =
-      clock_->NowTicks() + maximum_idle_period_duration();
+      clock_.NowTicks() + maximum_idle_period_duration();
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
@@ -2185,7 +2183,7 @@
 
 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
   base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
-  base::TimeTicks expected_deadline = clock_->NowTicks() + pending_task_delay;
+  base::TimeTicks expected_deadline = clock_.NowTicks() + pending_task_delay;
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
@@ -2210,7 +2208,7 @@
                                         pending_task_delay);
 
   // Advance clock until after delayed task was meant to be run.
-  clock_->Advance(base::TimeDelta::FromMilliseconds(20));
+  clock_.Advance(base::TimeDelta::FromMilliseconds(20));
 
   // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle
   // period. Since there is a late pending delayed task this shouldn't actually
@@ -2222,7 +2220,7 @@
   EXPECT_EQ(0, run_count);
 
   // After the delayed task has been run we should trigger an idle period.
-  clock_->Advance(maximum_idle_period_duration());
+  clock_.Advance(maximum_idle_period_duration());
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 }
@@ -2233,13 +2231,12 @@
   int run_count = 0;
 
   g_max_idle_task_reposts = 3;
-  base::TimeTicks clock_before(clock_->NowTicks());
+  base::TimeTicks clock_before(clock_.NowTicks());
   base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::Bind(&RepostingUpdateClockIdleTestTask,
-                 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
-                 idle_task_runtime, &actual_deadlines));
+      FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
+                            base::RetainedRef(idle_task_runner_), &run_count,
+                            &clock_, idle_task_runtime, &actual_deadlines));
   scheduler_->BeginFrameNotExpectedSoon();
   RunUntilIdle();
   EXPECT_EQ(3, run_count);
@@ -2253,14 +2250,13 @@
   // new BeginMainFrame.
   g_max_idle_task_reposts = 5;
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::Bind(&RepostingUpdateClockIdleTestTask,
-                 base::RetainedRef(idle_task_runner_), &run_count, clock_.get(),
-                 idle_task_runtime, &actual_deadlines));
+      FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
+                            base::RetainedRef(idle_task_runner_), &run_count,
+                            &clock_, idle_task_runtime, &actual_deadlines));
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
       base::Bind(&WillBeginFrameIdleTask, base::Unretained(scheduler_.get()),
-                 next_begin_frame_number_++, clock_.get()));
+                 next_begin_frame_number_++, &clock_));
   RunUntilIdle();
   EXPECT_EQ(4, run_count);
 }
@@ -2282,7 +2278,7 @@
   EXPECT_EQ(0, run_count);
 
   // The long idle period should start after the touchstart policy has finished.
-  clock_->Advance(priority_escalation_after_input_duration());
+  clock_.Advance(priority_escalation_after_input_duration());
   RunUntilIdle();
   EXPECT_EQ(1, run_count);
 }
@@ -2327,7 +2323,7 @@
 
   // Next long idle period will be for the maximum time, so
   // CanExceedIdleDeadlineIfRequired should return true.
-  clock_->Advance(maximum_idle_period_duration());
+  clock_.Advance(maximum_idle_period_duration());
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
       base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
@@ -2339,7 +2335,7 @@
   // Next long idle period will be for the maximum time, so
   // CanExceedIdleDeadlineIfRequired should return true.
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
   EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
@@ -2372,8 +2368,8 @@
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::Bind(&RepostingIdleTestTask,
                             base::RetainedRef(idle_task_runner_), &run_count));
-  clock_->Advance(end_idle_when_hidden_delay() +
-                  base::TimeDelta::FromMilliseconds(10));
+  clock_.Advance(end_idle_when_hidden_delay() +
+                 base::TimeDelta::FromMilliseconds(10));
   RunUntilIdle();
   EXPECT_EQ(2, run_count);
 }
@@ -2485,7 +2481,7 @@
   ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath());
 
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL);
   scheduler_->WillBeginFrame(begin_frame_args);
@@ -2515,7 +2511,7 @@
   // The background signal will not immediately suspend the timer queue.
   scheduler_->SetRendererBackgrounded(true);
   now += base::TimeDelta::FromMilliseconds(1100);
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   EXPECT_THAT(run_order,
               ::testing::ElementsAre(std::string("T1"), std::string("T2")));
@@ -2524,7 +2520,7 @@
   PostTestTasks(&run_order, "T3");
 
   now += base::TimeDelta::FromSeconds(1);
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   EXPECT_THAT(run_order, ::testing::ElementsAre(std::string("T3")));
 
@@ -2532,14 +2528,14 @@
   now = base::TimeTicks() + delay_for_background_tab_stopping() +
         base::TimeDelta::FromMilliseconds(10);
   run_order.clear();
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   ASSERT_TRUE(run_order.empty());
 
   // Timer tasks should be paused until the foregrounded signal.
   PostTestTasks(&run_order, "T4 T5 V1");
   now += base::TimeDelta::FromSeconds(10);
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   EXPECT_THAT(run_order, ::testing::ElementsAre(std::string("V1")));
 
@@ -2569,7 +2565,7 @@
   // The background signal will not immediately suspend the loading queue.
   scheduler_->SetRendererBackgrounded(true);
   now += base::TimeDelta::FromMilliseconds(1100);
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   EXPECT_THAT(run_order,
               ::testing::ElementsAre(std::string("L1"), std::string("L2")));
@@ -2578,7 +2574,7 @@
   PostTestTasks(&run_order, "L3");
 
   now += base::TimeDelta::FromSeconds(1);
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   EXPECT_THAT(run_order, ::testing::ElementsAre(std::string("L3")));
 
@@ -2586,14 +2582,14 @@
   now = base::TimeTicks() + delay_for_background_tab_stopping() +
         base::TimeDelta::FromMilliseconds(10);
   run_order.clear();
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   ASSERT_TRUE(run_order.empty());
 
   // Loading tasks should be paused until the foregrounded signal.
   PostTestTasks(&run_order, "L4 L5");
   now += base::TimeDelta::FromSeconds(10);
-  clock_->SetNowTicks(now);
+  clock_.SetNowTicks(now);
   RunUntilIdle();
   EXPECT_THAT(run_order, ::testing::ElementsAre());
 
@@ -2705,7 +2701,7 @@
       FakeInputEvent(blink::WebInputEvent::kTouchEnd),
       WebInputEventResult::kHandledSystem);
 
-  clock_->Advance(priority_escalation_after_input_duration() * 2);
+  clock_.Advance(priority_escalation_after_input_duration() * 2);
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
 
   PostTestTasks(&run_order, "T1 D1");
@@ -2919,7 +2915,7 @@
     simulate_timer_task_ran_ = false;
 
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -2944,9 +2940,9 @@
     EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
 
     base::TimeDelta time_till_next_frame =
-        EstimatedNextFrameBegin() - clock_->NowTicks();
+        EstimatedNextFrameBegin() - clock_.NowTicks();
     if (time_till_next_frame > base::TimeDelta())
-      clock_->Advance(time_till_next_frame);
+      clock_.Advance(time_till_next_frame);
   }
 }
 
@@ -2958,7 +2954,7 @@
     simulate_timer_task_ran_ = false;
 
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -2984,9 +2980,9 @@
     EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
 
     base::TimeDelta time_till_next_frame =
-        EstimatedNextFrameBegin() - clock_->NowTicks();
+        EstimatedNextFrameBegin() - clock_.NowTicks();
     if (time_till_next_frame > base::TimeDelta())
-      clock_->Advance(time_till_next_frame);
+      clock_.Advance(time_till_next_frame);
   }
 }
 
@@ -3000,7 +2996,7 @@
     simulate_timer_task_ran_ = false;
 
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -3029,9 +3025,9 @@
     EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
 
     base::TimeDelta time_till_next_frame =
-        EstimatedNextFrameBegin() - clock_->NowTicks();
+        EstimatedNextFrameBegin() - clock_.NowTicks();
     if (time_till_next_frame > base::TimeDelta())
-      clock_->Advance(time_till_next_frame);
+      clock_.Advance(time_till_next_frame);
   }
 }
 
@@ -3065,7 +3061,7 @@
   SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
                                  blink::WebInputEvent::kGestureScrollUpdate);
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = false;
@@ -3089,7 +3085,7 @@
     RendererSchedulerImplTest,
     EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = false;
@@ -3114,7 +3110,7 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
 
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = true;
@@ -3226,7 +3222,7 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
 
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = true;
@@ -3286,18 +3282,18 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
   base::TimeTicks first_throttled_run_time =
-      TaskQueueThrottler::AlignedThrottledRunTime(clock_->NowTicks());
+      TaskQueueThrottler::AlignedThrottledRunTime(clock_.NowTicks());
 
   size_t count = 0;
   // With the compositor task taking 10ms, there is not enough time to run this
   // 7ms timer task in the 16ms frame.
   scheduler_->TimerTaskQueue()->PostTask(
-      FROM_HERE, base::Bind(SlowCountingTask, &count, clock_.get(), 7,
+      FROM_HERE, base::Bind(SlowCountingTask, &count, &clock_, 7,
                             scheduler_->TimerTaskQueue()));
 
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3335,7 +3331,7 @@
     // The task runs twice before the system realizes it's too expensive.
     bool throttled_task_has_run = count > 2;
     bool throttled_task_expected_to_have_run =
-        (clock_->NowTicks() > first_throttled_run_time);
+        (clock_.NowTicks() > first_throttled_run_time);
     EXPECT_EQ(throttled_task_expected_to_have_run, throttled_task_has_run)
         << "i = " << i << " count = " << count;
   }
@@ -3349,19 +3345,19 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
   base::TimeTicks first_throttled_run_time =
-      TaskQueueThrottler::AlignedThrottledRunTime(clock_->NowTicks());
+      TaskQueueThrottler::AlignedThrottledRunTime(clock_.NowTicks());
 
   size_t count = 0;
   // With the compositor task taking 10ms, there is not enough time to run this
   // 7ms timer task in the 16ms frame.
   scheduler_->TimerTaskQueue()->PostTask(
-      FROM_HERE, base::Bind(SlowCountingTask, &count, clock_.get(), 7,
+      FROM_HERE, base::Bind(SlowCountingTask, &count, &clock_, 7,
                             scheduler_->TimerTaskQueue()));
 
   std::unique_ptr<RendererScheduler::RendererPauseHandle> paused;
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3385,7 +3381,7 @@
     // Before the policy is updated the queue will be enabled. Subsequently it
     // will be disabled until the throttled queue is pumped.
     bool expect_queue_enabled =
-        (i == 0) || (clock_->NowTicks() > first_throttled_run_time);
+        (i == 0) || (clock_.NowTicks() > first_throttled_run_time);
     if (paused)
       expect_queue_enabled = false;
     EXPECT_EQ(expect_queue_enabled,
@@ -3413,12 +3409,12 @@
   // With the compositor task taking 10ms, there is enough time to run this 6ms
   // timer task in the 16ms frame.
   scheduler_->TimerTaskQueue()->PostTask(
-      FROM_HERE, base::Bind(SlowCountingTask, &count, clock_.get(), 6,
+      FROM_HERE, base::Bind(SlowCountingTask, &count, &clock_, 6,
                             scheduler_->TimerTaskQueue()));
 
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3458,7 +3454,7 @@
       RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
 
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = true;
@@ -3520,7 +3516,7 @@
 
   for (int i = 0; i < 100; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3562,7 +3558,7 @@
 
   for (int i = 0; i < 100; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3606,7 +3602,7 @@
 
   for (int i = 0; i < 100; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3723,16 +3719,16 @@
   size_t timer_count = 0;
   size_t unthrottled_count = 0;
   scheduler_->TimerTaskQueue()->PostTask(
-      FROM_HERE, base::Bind(SlowCountingTask, &timer_count, clock_.get(), 7,
+      FROM_HERE, base::Bind(SlowCountingTask, &timer_count, &clock_, 7,
                             scheduler_->TimerTaskQueue()));
   unthrottled_task_runner->PostTask(
-      FROM_HERE, base::Bind(SlowCountingTask, &unthrottled_count, clock_.get(),
-                            7, unthrottled_task_runner));
+      FROM_HERE, base::Bind(SlowCountingTask, &unthrottled_count, &clock_, 7,
+                            unthrottled_task_runner));
   auto handle = scheduler_->PauseRenderer();
 
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_->NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3915,7 +3911,7 @@
   std::vector<base::TimeTicks> run_times;
 
   timer_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&RecordingTimeTestTask, &run_times, clock_.get()));
+      FROM_HERE, base::Bind(&RecordingTimeTestTask, &run_times, &clock_));
 
   mock_task_runner_->RunUntilTime(base::TimeTicks() +
                                   base::TimeDelta::FromMilliseconds(1100));
@@ -3926,7 +3922,7 @@
   run_times.clear();
 
   timer_task_runner_->PostDelayedTask(
-      FROM_HERE, base::Bind(&RecordingTimeTestTask, &run_times, clock_.get()),
+      FROM_HERE, base::Bind(&RecordingTimeTestTask, &run_times, &clock_),
       base::TimeDelta::FromMilliseconds(200));
 
   scheduler_->SetRendererBackgrounded(false);
@@ -3949,7 +3945,7 @@
       scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold()));
 
   // Wait a second.
-  clock_->Advance(base::TimeDelta::FromSecondsD(2));
+  clock_.Advance(base::TimeDelta::FromSecondsD(2));
 
   AdvanceTimeWithTask(0.5);
   EXPECT_FALSE(
@@ -3985,8 +3981,8 @@
 TEST_F(RendererSchedulerImplTest, ResponsiveMainThreadDuringTask) {
   EXPECT_FALSE(
       scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold()));
-  clock_->Advance(base::TimeDelta::FromSecondsD(2));
-  scheduler_->OnTaskStarted(fake_queue_.get(), fake_task_, clock_->NowTicks());
+  clock_.Advance(base::TimeDelta::FromSecondsD(2));
+  scheduler_->OnTaskStarted(fake_queue_.get(), fake_task_, clock_.NowTicks());
   EXPECT_FALSE(
       scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold()));
 }
@@ -4002,7 +3998,7 @@
       scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold()));
 
   // Advance the clock, so that in the last second, we were responsive.
-  clock_->Advance(base::TimeDelta::FromSecondsD(2));
+  clock_.Advance(base::TimeDelta::FromSecondsD(2));
   // While the queueing time estimator is locked, we believe the thread to still
   // be unresponsive.
   EXPECT_TRUE(
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_cost_estimator_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_cost_estimator_unittest.cc
index bf32311..c3a6d3fe 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/task_cost_estimator_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_cost_estimator_unittest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 
 #include "base/test/simple_test_tick_clock.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -19,26 +18,19 @@
   TaskCostEstimatorTest() {}
   ~TaskCostEstimatorTest() override {}
 
-  void SetUp() override {
-    test_time_source_.reset(new TestTimeSource(&clock_));
-  }
-
   base::SimpleTestTickClock clock_;
-  std::unique_ptr<TestTimeSource> test_time_source_;
 };
 
 class TaskCostEstimatorForTest : public TaskCostEstimator {
  public:
-  TaskCostEstimatorForTest(TestTimeSource* test_time_source,
+  TaskCostEstimatorForTest(base::TickClock* clock,
                            int sample_count,
                            double estimation_percentile)
-      : TaskCostEstimator(test_time_source,
-                          sample_count,
-                          estimation_percentile) {}
+      : TaskCostEstimator(clock, sample_count, estimation_percentile) {}
 };
 
 TEST_F(TaskCostEstimatorTest, BasicEstimation) {
-  TaskCostEstimatorForTest estimator(test_time_source_.get(), 1, 100);
+  TaskCostEstimatorForTest estimator(&clock_, 1, 100);
   base::PendingTask task(FROM_HERE, base::Closure());
 
   estimator.WillProcessTask(task);
@@ -50,7 +42,7 @@
 }
 
 TEST_F(TaskCostEstimatorTest, Clear) {
-  TaskCostEstimatorForTest estimator(test_time_source_.get(), 1, 100);
+  TaskCostEstimatorForTest estimator(&clock_, 1, 100);
   base::PendingTask task(FROM_HERE, base::Closure());
 
   estimator.WillProcessTask(task);
@@ -63,7 +55,7 @@
 }
 
 TEST_F(TaskCostEstimatorTest, NestedRunLoop) {
-  TaskCostEstimatorForTest estimator(test_time_source_.get(), 1, 100);
+  TaskCostEstimatorForTest estimator(&clock_, 1, 100);
   base::PendingTask task(FROM_HERE, base::Closure());
 
   // Make sure we ignore the tasks inside the nested run loop.
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc
index 8ff0aa2..032b4eb 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler_unittest.cc
@@ -15,7 +15,6 @@
 #include "platform/scheduler/base/real_time_domain.h"
 #include "platform/scheduler/base/task_queue_impl.h"
 #include "platform/scheduler/base/task_queue_manager.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h"
 #include "platform/scheduler/renderer/budget_pool.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
index a7be571c..ef8898b 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
@@ -11,7 +11,6 @@
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/WebTaskRunner.h"
 #include "platform/runtime_enabled_features.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/renderer/web_view_scheduler_impl.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
@@ -30,13 +29,12 @@
   ~WebFrameSchedulerImplTest() override {}
 
   void SetUp() override {
-    clock_.reset(new base::SimpleTestTickClock());
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
     mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), true);
+        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true);
     scheduler_.reset(
         new RendererSchedulerImpl(CreateTaskQueueManagerWithUnownedClockForTest(
-            nullptr, mock_task_runner_, clock_.get())));
+            nullptr, mock_task_runner_, &clock_)));
     web_view_scheduler_.reset(
         new WebViewSchedulerImpl(nullptr, nullptr, scheduler_.get(), false));
     web_frame_scheduler_ = web_view_scheduler_->CreateWebFrameSchedulerImpl(
@@ -71,7 +69,7 @@
     return web_frame_scheduler_->UnpausableTaskQueue();
   }
 
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<RendererSchedulerImpl> scheduler_;
   std::unique_ptr<WebViewSchedulerImpl> web_view_scheduler_;
@@ -326,7 +324,7 @@
   web_view_scheduler_->SetPageVisible(false);
 
   // Wait 100 secs virtually and run pending tasks just in case.
-  clock_->Advance(base::TimeDelta::FromSeconds(100));
+  clock_.Advance(base::TimeDelta::FromSeconds(100));
   mock_task_runner_->RunUntilIdle();
 
   observer->CheckObserverState(throttled_count, not_throttled_count,
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler.h
index e90e7ca5..6519f78 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler.h
@@ -109,7 +109,7 @@
   // policy is not affected when the budget expires.
   virtual void GrantVirtualTimeBudget(
       base::TimeDelta budget,
-      WTF::Closure budget_exhausted_callback) = 0;
+      base::OnceClosure budget_exhausted_callback) = 0;
 
   // It's possible for pages to send infinite messages which can arbitrarily
   // block virtual time.  We can prevent this by setting an upper limit on the
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc
index 1d50527..9ebdeeff 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc
@@ -191,10 +191,9 @@
 
 void WebViewSchedulerImpl::GrantVirtualTimeBudget(
     base::TimeDelta budget,
-    WTF::Closure budget_exhausted_callback) {
+    base::OnceClosure budget_exhausted_callback) {
   renderer_scheduler_->VirtualTimeControlTaskQueue()->PostDelayedTask(
-      FROM_HERE, ConvertToBaseCallback(std::move(budget_exhausted_callback)),
-      budget);
+      FROM_HERE, std::move(budget_exhausted_callback), budget);
 }
 
 void WebViewSchedulerImpl::AddVirtualTimeObserver(
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h
index 41cb292e..854aa95 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.h
@@ -53,8 +53,9 @@
   void DisableVirtualTimeForTesting() override;
   bool VirtualTimeAllowedToAdvance() const override;
   void SetVirtualTimePolicy(VirtualTimePolicy virtual_time_policy) override;
-  void GrantVirtualTimeBudget(base::TimeDelta budget,
-                              WTF::Closure budget_exhausted_callback) override;
+  void GrantVirtualTimeBudget(
+      base::TimeDelta budget,
+      base::OnceClosure budget_exhausted_callback) override;
   void SetMaxVirtualTimeTaskStarvationCount(
       int max_task_starvation_count) override;
   void AudioStateChanged(bool is_audio_playing) override;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
index b66c1d6..613fdca 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/test/simple_test_tick_clock.h"
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/WebTaskRunner.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/renderer/web_frame_scheduler_impl.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
@@ -37,13 +36,12 @@
   ~WebViewSchedulerImplTest() override {}
 
   void SetUp() override {
-    clock_.reset(new base::SimpleTestTickClock());
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
     mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), true);
+        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true);
     scheduler_.reset(
         new RendererSchedulerImpl(CreateTaskQueueManagerWithUnownedClockForTest(
-            nullptr, mock_task_runner_, clock_.get())));
+            nullptr, mock_task_runner_, &clock_)));
     web_view_scheduler_.reset(
         new WebViewSchedulerImpl(nullptr, nullptr, scheduler_.get(),
                                  DisableBackgroundTimerThrottling()));
@@ -82,7 +80,7 @@
     return web_frame_scheduler_->LoadingTaskQueue();
   }
 
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<RendererSchedulerImpl> scheduler_;
   std::unique_ptr<WebViewSchedulerImpl> web_view_scheduler_;
@@ -213,7 +211,7 @@
       task_runner->MonotonicallyIncreasingVirtualTimeSeconds() * 1000.0);
 }
 
-WTF::Closure MakeVirtualTimeRecorderTask(
+base::OnceClosure MakeVirtualTimeRecorderTask(
     base::SimpleTestTickClock* clock,
     scoped_refptr<WebTaskRunner> task_runner,
     std::vector<base::TimeTicks>* out_real_times,
@@ -237,19 +235,19 @@
 
   ThrottleableTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(),
+      MakeVirtualTimeRecorderTask(&clock_, ThrottleableTaskRunner(),
                                   &real_times, &virtual_times_ms),
       TimeDelta::FromMilliseconds(2));
 
   ThrottleableTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(),
+      MakeVirtualTimeRecorderTask(&clock_, ThrottleableTaskRunner(),
                                   &real_times, &virtual_times_ms),
       TimeDelta::FromMilliseconds(20));
 
   ThrottleableTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(),
+      MakeVirtualTimeRecorderTask(&clock_, ThrottleableTaskRunner(),
                                   &real_times, &virtual_times_ms),
       TimeDelta::FromMilliseconds(200));
 
@@ -274,20 +272,20 @@
 
   LoadingTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), LoadingTaskRunner(),
-                                  &real_times, &virtual_times_ms),
+      MakeVirtualTimeRecorderTask(&clock_, LoadingTaskRunner(), &real_times,
+                                  &virtual_times_ms),
       TimeDelta::FromMilliseconds(2));
 
   LoadingTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), LoadingTaskRunner(),
-                                  &real_times, &virtual_times_ms),
+      MakeVirtualTimeRecorderTask(&clock_, LoadingTaskRunner(), &real_times,
+                                  &virtual_times_ms),
       TimeDelta::FromMilliseconds(20));
 
   LoadingTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), LoadingTaskRunner(),
-                                  &real_times, &virtual_times_ms),
+      MakeVirtualTimeRecorderTask(&clock_, LoadingTaskRunner(), &real_times,
+                                  &virtual_times_ms),
       TimeDelta::FromMilliseconds(200));
 
   mock_task_runner_->RunUntilIdle();
@@ -617,25 +615,25 @@
 
   ThrottleableTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(),
+      MakeVirtualTimeRecorderTask(&clock_, ThrottleableTaskRunner(),
                                   &real_times, &virtual_times_ms),
       TimeDelta::FromMilliseconds(1));
 
   ThrottleableTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(),
+      MakeVirtualTimeRecorderTask(&clock_, ThrottleableTaskRunner(),
                                   &real_times, &virtual_times_ms),
       TimeDelta::FromMilliseconds(2));
 
   ThrottleableTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(),
+      MakeVirtualTimeRecorderTask(&clock_, ThrottleableTaskRunner(),
                                   &real_times, &virtual_times_ms),
       TimeDelta::FromMilliseconds(5));
 
   ThrottleableTaskRunner()->PostDelayedTask(
       BLINK_FROM_HERE,
-      MakeVirtualTimeRecorderTask(clock_.get(), ThrottleableTaskRunner(),
+      MakeVirtualTimeRecorderTask(&clock_, ThrottleableTaskRunner(),
                                   &real_times, &virtual_times_ms),
       TimeDelta::FromMilliseconds(7));
 
@@ -868,10 +866,10 @@
                                   base::TimeDelta::FromMilliseconds(2500));
 
   ThrottleableTaskQueue()->PostDelayedTask(
-      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
+      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times),
       TimeDelta::FromMilliseconds(1));
   ThrottleableTaskQueue()->PostDelayedTask(
-      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
+      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times),
       TimeDelta::FromMilliseconds(1));
 
   mock_task_runner_->RunUntilTime(base::TimeTicks() +
@@ -888,10 +886,10 @@
   web_view_scheduler_->SetPageVisible(false);
 
   ThrottleableTaskQueue()->PostDelayedTask(
-      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
+      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times),
       TimeDelta::FromMicroseconds(1));
   ThrottleableTaskQueue()->PostDelayedTask(
-      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
+      BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times),
       TimeDelta::FromMicroseconds(1));
 
   mock_task_runner_->RunUntilIdle();
@@ -932,10 +930,9 @@
 
   for (size_t i = 0; i < 3; ++i) {
     ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get())
-        ->PostDelayedTask(
-            BLINK_FROM_HERE,
-            base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
-            TimeDelta::FromMilliseconds(1));
+        ->PostDelayedTask(BLINK_FROM_HERE,
+                          base::Bind(&ExpensiveTestTask, &clock_, &run_times),
+                          TimeDelta::FromMilliseconds(1));
   }
 
   mock_task_runner_->RunUntilTime(base::TimeTicks() +
@@ -954,10 +951,9 @@
 
   for (size_t i = 0; i < 3; ++i) {
     ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get())
-        ->PostDelayedTask(
-            BLINK_FROM_HERE,
-            base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
-            TimeDelta::FromMilliseconds(1));
+        ->PostDelayedTask(BLINK_FROM_HERE,
+                          base::Bind(&ExpensiveTestTask, &clock_, &run_times),
+                          TimeDelta::FromMilliseconds(1));
   }
 
   mock_task_runner_->RunUntilTime(base::TimeTicks() +
@@ -975,10 +971,9 @@
 
   for (size_t i = 0; i < 3; ++i) {
     ThrottleableTaskQueueForScheduler(web_frame_scheduler2.get())
-        ->PostDelayedTask(
-            BLINK_FROM_HERE,
-            base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
-            TimeDelta::FromMilliseconds(1));
+        ->PostDelayedTask(BLINK_FROM_HERE,
+                          base::Bind(&ExpensiveTestTask, &clock_, &run_times),
+                          TimeDelta::FromMilliseconds(1));
   }
 
   mock_task_runner_->RunUntilTime(base::TimeTicks() +
@@ -1001,10 +996,9 @@
 
   for (size_t i = 0; i < 3; ++i) {
     ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get())
-        ->PostDelayedTask(
-            BLINK_FROM_HERE,
-            base::Bind(&ExpensiveTestTask, clock_.get(), &run_times),
-            TimeDelta::FromMilliseconds(1));
+        ->PostDelayedTask(BLINK_FROM_HERE,
+                          base::Bind(&ExpensiveTestTask, &clock_, &run_times),
+                          TimeDelta::FromMilliseconds(1));
   }
 
   mock_task_runner_->RunUntilIdle();
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
index d05f727..cc8019797 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/single_thread_task_runner.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "platform/WebTaskRunner.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "public/platform/WebTraceLocation.h"
@@ -44,11 +43,10 @@
   WebThreadImplForRendererSchedulerTest() {}
 
   void SetUp() override {
-    clock_.reset(new base::SimpleTestTickClock());
-    clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
+    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
     scheduler_.reset(
         new RendererSchedulerImpl(CreateTaskQueueManagerWithUnownedClockForTest(
-            &message_loop_, message_loop_.task_runner(), clock_.get())));
+            &message_loop_, message_loop_.task_runner(), &clock_)));
     default_task_runner_ = scheduler_->DefaultTaskQueue();
     thread_ = scheduler_->CreateMainThread();
   }
@@ -64,7 +62,7 @@
 
  protected:
   base::MessageLoop message_loop_;
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   std::unique_ptr<RendererSchedulerImpl> scheduler_;
   scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
   std::unique_ptr<blink::WebThread> thread_;
diff --git a/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.cc b/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.cc
index 49694f4..b6c1a7f4 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.cc
+++ b/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.cc
@@ -5,7 +5,6 @@
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 
 #include "platform/scheduler/base/task_queue_manager.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/base/thread_controller_impl.h"
 
 namespace blink {
@@ -25,10 +24,10 @@
   ThreadControllerForTest(
       base::MessageLoop* message_loop,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      std::unique_ptr<base::TickClock> time_source)
+      base::TickClock* time_source)
       : ThreadControllerImpl(message_loop,
                              std::move(task_runner),
-                             std::move(time_source)) {}
+                             time_source) {}
 
   void AddNestingObserver(base::RunLoop::NestingObserver* observer) override {
     if (!message_loop_)
@@ -59,16 +58,16 @@
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     base::SimpleTestTickClock* clock) {
   return CreateTaskQueueManagerForTest(message_loop, std::move(task_runner),
-                                       std::make_unique<TestTimeSource>(clock));
+                                       clock);
 }
 
 std::unique_ptr<TaskQueueManager> CreateTaskQueueManagerForTest(
     base::MessageLoop* message_loop,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    std::unique_ptr<base::TickClock> clock) {
+    base::TickClock* clock) {
   return std::make_unique<TaskQueueManagerForTest>(
-      std::make_unique<ThreadControllerForTest>(
-          message_loop, std::move(task_runner), std::move(clock)));
+      std::make_unique<ThreadControllerForTest>(message_loop,
+                                                std::move(task_runner), clock));
 }
 
 }  // namespace scheduler
diff --git a/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.h b/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.h
index df8a7e0..62e514c 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.h
+++ b/third_party/WebKit/Source/platform/scheduler/test/create_task_queue_manager_for_test.h
@@ -24,7 +24,7 @@
 std::unique_ptr<TaskQueueManager> CreateTaskQueueManagerForTest(
     base::MessageLoop* message_loop,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    std::unique_ptr<base::TickClock> clock);
+    base::TickClock* clock);
 
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_view_scheduler.h b/third_party/WebKit/Source/platform/scheduler/test/fake_web_view_scheduler.h
index 4361bec..8e5e28c 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_view_scheduler.h
+++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_view_scheduler.h
@@ -63,7 +63,7 @@
   void AddVirtualTimeObserver(VirtualTimeObserver* observer) override {}
   void RemoveVirtualTimeObserver(VirtualTimeObserver* observer) override {}
   void GrantVirtualTimeBudget(base::TimeDelta budget,
-                              WTF::Closure callback) override {}
+                              base::OnceClosure callback) override {}
   void SetMaxVirtualTimeTaskStarvationCount(int count) override {}
   void AudioStateChanged(bool is_audio_playing) override {}
   bool HasActiveConnectionForTest() const override { return false; }
diff --git a/third_party/WebKit/Source/platform/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc b/third_party/WebKit/Source/platform/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc
index 2f272442..e4688fd 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc
+++ b/third_party/WebKit/Source/platform/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc
@@ -23,7 +23,7 @@
     LazySchedulerMessageLoopDelegateForTests()
     : message_loop_(base::MessageLoop::current()),
       thread_id_(base::PlatformThread::CurrentId()),
-      time_source_(std::make_unique<base::DefaultTickClock>()),
+      time_source_(base::DefaultTickClock::GetInstance()),
       pending_observer_(nullptr) {
   if (message_loop_)
     original_task_runner_ = message_loop_->task_runner();
diff --git a/third_party/WebKit/Source/platform/scheduler/test/lazy_thread_controller_for_test.cc b/third_party/WebKit/Source/platform/scheduler/test/lazy_thread_controller_for_test.cc
index 210fa55..1e8ec0dd 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/lazy_thread_controller_for_test.cc
+++ b/third_party/WebKit/Source/platform/scheduler/test/lazy_thread_controller_for_test.cc
@@ -14,7 +14,7 @@
 LazyThreadControllerForTest::LazyThreadControllerForTest()
     : ThreadControllerImpl(base::MessageLoop::current(),
                            nullptr,
-                           std::make_unique<base::DefaultTickClock>()),
+                           base::DefaultTickClock::GetInstance()),
       thread_ref_(base::PlatformThread::CurrentRef()) {
   if (message_loop_)
     task_runner_ = message_loop_->task_runner();
diff --git a/third_party/WebKit/Source/platform/testing/PaintTestConfigurations.h b/third_party/WebKit/Source/platform/testing/PaintTestConfigurations.h
index f5fec764..9eadc49 100644
--- a/third_party/WebKit/Source/platform/testing/PaintTestConfigurations.h
+++ b/third_party/WebKit/Source/platform/testing/PaintTestConfigurations.h
@@ -41,6 +41,11 @@
     kSlimmingPaintV2 | kRootLayerScrolling,
 };
 
+static constexpr unsigned kSlimmingPaintNonV1TestConfigurations[] = {
+    kSlimmingPaintV175, kSlimmingPaintV175 | kRootLayerScrolling,
+    kSlimmingPaintV2, kSlimmingPaintV2 | kRootLayerScrolling,
+};
+
 static constexpr unsigned kSlimmingPaintV2TestConfigurations[] = {
     kSlimmingPaintV2, kSlimmingPaintV2 | kRootLayerScrolling,
 };
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
index 8bdc309..37065eb 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
@@ -49,7 +49,6 @@
 #include "platform/network/mime/MockMimeRegistry.h"
 #include "platform/scheduler/base/real_time_domain.h"
 #include "platform/scheduler/base/task_queue_manager.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "platform/wtf/CryptographicallyRandomNumber.h"
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp
index 75569425..9742b02 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp
@@ -8,7 +8,6 @@
 #include "components/viz/test/ordered_simple_task_runner.h"
 #include "platform/WaitableEvent.h"
 #include "platform/scheduler/base/real_time_domain.h"
-#include "platform/scheduler/base/test_time_source.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
 #include "platform/scheduler/test/create_task_queue_manager_for_test.h"
 #include "platform/wtf/ThreadSpecific.h"
@@ -42,13 +41,12 @@
 TestingPlatformSupportWithMockScheduler::
     TestingPlatformSupportWithMockScheduler(const Config& config)
     : TestingPlatformSupport(config),
-      clock_(new base::SimpleTestTickClock()),
-      mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_.get(), true)),
+      mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)),
       scheduler_(new scheduler::RendererSchedulerImpl(
           scheduler::CreateTaskQueueManagerWithUnownedClockForTest(
               nullptr,
               mock_task_runner_,
-              clock_.get()))),
+              &clock_))),
       thread_(scheduler_->CreateMainThread()) {
   DCHECK(IsMainThread());
   // Set the work batch size to one so RunPendingTasks behaves as expected.
@@ -101,7 +99,7 @@
 void TestingPlatformSupportWithMockScheduler::RunForPeriodSeconds(
     double seconds) {
   const base::TimeTicks deadline =
-      clock_->NowTicks() + base::TimeDelta::FromSecondsD(seconds);
+      clock_.NowTicks() + base::TimeDelta::FromSecondsD(seconds);
 
   scheduler::TaskQueueManager* task_queue_manager =
       scheduler_->GetSchedulerHelperForTesting()
@@ -118,21 +116,21 @@
         break;
       }
 
-      clock_->SetNowTicks(next_delayed_task);
+      clock_.SetNowTicks(next_delayed_task);
     }
 
-    if (clock_->NowTicks() > deadline)
+    if (clock_.NowTicks() > deadline)
       break;
 
     mock_task_runner_->RunPendingTasks();
   }
 
-  clock_->SetNowTicks(deadline);
+  clock_.SetNowTicks(deadline);
 }
 
 void TestingPlatformSupportWithMockScheduler::AdvanceClockSeconds(
     double seconds) {
-  clock_->Advance(base::TimeDelta::FromSecondsD(seconds));
+  clock_.Advance(base::TimeDelta::FromSecondsD(seconds));
 }
 
 void TestingPlatformSupportWithMockScheduler::SetAutoAdvanceNowToPendingTasks(
@@ -150,7 +148,7 @@
   TestingPlatformSupportWithMockScheduler* platform =
       static_cast<TestingPlatformSupportWithMockScheduler*>(
           Platform::Current());
-  return (platform->clock_->NowTicks() - base::TimeTicks()).InSecondsF();
+  return (platform->clock_.NowTicks() - base::TimeTicks()).InSecondsF();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h
index 0ef550c8..bebebb1 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h
@@ -6,14 +6,11 @@
 #define TestingPlatformSupportWithMockScheduler_h
 
 #include <memory>
+#include "base/test/simple_test_tick_clock.h"
 #include "platform/testing/TestingPlatformSupport.h"
 #include "platform/wtf/Noncopyable.h"
 #include "public/platform/WebThread.h"
 
-namespace base {
-class SimpleTestTickClock;
-}
-
 namespace cc {
 class OrderedSimpleTaskRunner;
 }
@@ -67,7 +64,7 @@
  protected:
   static double GetTestTime();
 
-  std::unique_ptr<base::SimpleTestTickClock> clock_;
+  base::SimpleTestTickClock clock_;
   scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
   std::unique_ptr<scheduler::RendererSchedulerImpl> scheduler_;
   std::unique_ptr<WebThread> thread_;
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.cpp
index 495d40f..7dc21692 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.cpp
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.cpp
@@ -101,7 +101,8 @@
 
 std::unique_ptr<WebRTCPeerConnectionHandler>
 TestingPlatformSupportWithWebRTC::CreateRTCPeerConnectionHandler(
-    WebRTCPeerConnectionHandlerClient*) {
+    WebRTCPeerConnectionHandlerClient*,
+    scoped_refptr<base::SingleThreadTaskRunner>) {
   return std::make_unique<MockWebRTCPeerConnectionHandler>();
 }
 
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.h
index 0c93b0b2..1386f8da 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.h
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithWebRTC.h
@@ -53,7 +53,8 @@
 class TestingPlatformSupportWithWebRTC : public TestingPlatformSupport {
  public:
   std::unique_ptr<WebRTCPeerConnectionHandler> CreateRTCPeerConnectionHandler(
-      WebRTCPeerConnectionHandlerClient*) override;
+      WebRTCPeerConnectionHandlerClient*,
+      scoped_refptr<base::SingleThreadTaskRunner>) override;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp b/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp
index 0b4685f2..54b4f40 100644
--- a/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp
+++ b/third_party/WebKit/Source/platform/text/LocaleWinTest.cpp
@@ -169,9 +169,9 @@
 }
 
 TEST_F(LocaleWinTest, firstDayOfWeek) {
-  EXPECT_EQ(kSunday, FirstDayOfWeek(kEnglishUS));
-  EXPECT_EQ(kMonday, FirstDayOfWeek(kFrenchFR));
-  EXPECT_EQ(kSunday, FirstDayOfWeek(kJapaneseJP));
+  EXPECT_EQ(static_cast<unsigned>(kSunday), FirstDayOfWeek(kEnglishUS));
+  EXPECT_EQ(static_cast<unsigned>(kMonday), FirstDayOfWeek(kFrenchFR));
+  EXPECT_EQ(static_cast<unsigned>(kSunday), FirstDayOfWeek(kJapaneseJP));
 }
 
 TEST_F(LocaleWinTest, monthLabels) {
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
index 2dc4e7e..6dbe401 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
@@ -181,6 +181,7 @@
   bool CanAccessPasswordManager() const { return !IsUnique(); }
   bool CanAccessFileSystem() const { return !IsUnique(); }
   bool CanAccessCacheStorage() const { return !IsUnique(); }
+  bool CanAccessLocks() const { return !IsUnique(); }
 
   // Technically, we should always allow access to sessionStorage, but we
   // currently don't handle creating a sessionStorage area for unique
diff --git a/third_party/WebKit/Source/platform/wtf/Functional.h b/third_party/WebKit/Source/platform/wtf/Functional.h
index 89955f3..e70c89c3 100644
--- a/third_party/WebKit/Source/platform/wtf/Functional.h
+++ b/third_party/WebKit/Source/platform/wtf/Functional.h
@@ -71,28 +71,14 @@
 //
 // 2. To create a same-thread callback that's called only once
 //
-// Use WTF::Bind(), and receive the returned callback as WTF::Function or
-// WTF::Closure. To convert it to base::OnceCallback, use
-// ConvertToBaseCallback().
-//
-// You should not copy WTF::Function so we can ensure it's called only once.
-// It should be always passed by move.
-//
-// To invoke the callback function, do:
-//
-//     std::move(function).Run(<arguments...>);
+// Use WTF::Bind(), and receive the returned callback as base::OnceCallback
+// or base::OnceClosure. Read //docs/callback.md for how to use them.
 //
 // 3. To create a same-thread callback that may be called multiple times
 //
 // Use WTF::BindRepeating(), and receive the returned callback as
-// WTF::RepeatingFunction or WTF::RepeatingClosure. Those types are now an
-// alias of base::RepeatingCallback, so you can just use it interchangably.
-//
-// You can copy WTF::RepeatingFunction.
-//
-// To invoke the callback function, simply do:
-//
-//     function.Run(<arguments...>);
+// base::RepeatingCallback or base::RepeatingClosure (WTF::RepeatingFunction
+// is gone).
 
 // Thread Safety:
 //
@@ -330,12 +316,6 @@
 using Function = base::OnceCallback<Signature>;
 
 template <typename Signature>
-base::OnceCallback<Signature> ConvertToBaseCallback(
-    Function<Signature> function) {
-  return function;
-}
-
-template <typename Signature>
 class CrossThreadFunction;
 
 template <typename R, typename... Args>
@@ -420,9 +400,6 @@
 }
 
 // TODO(yutak): Replace WTF::Function with base::OnceCallback.
-template <typename T>
-using RepeatingFunction = base::RepeatingCallback<T>;
-using RepeatingClosure = base::RepeatingCallback<void()>;
 using Closure = Function<void()>;
 
 template <typename T>
@@ -470,6 +447,4 @@
 using WTF::CrossThreadFunction;
 using WTF::CrossThreadClosure;
 
-using WTF::ConvertToBaseCallback;
-
 #endif  // WTF_Functional_h
diff --git a/third_party/WebKit/Source/platform/wtf/FunctionalTest.cpp b/third_party/WebKit/Source/platform/wtf/FunctionalTest.cpp
index ba0c148..2ad3e32c 100644
--- a/third_party/WebKit/Source/platform/wtf/FunctionalTest.cpp
+++ b/third_party/WebKit/Source/platform/wtf/FunctionalTest.cpp
@@ -138,7 +138,7 @@
 TEST(FunctionalTest, WeakPtr) {
   HasWeakPtrSupport obj;
   int counter = 0;
-  WTF::RepeatingClosure bound =
+  base::RepeatingClosure bound =
       WTF::BindRepeating(&HasWeakPtrSupport::Increment, obj.GetWeakPtr(),
                          WTF::Unretained(&counter));
 
@@ -152,13 +152,13 @@
   EXPECT_EQ(1, counter);
 }
 
-void MakeClosure(Closure** closure_out) {
-  *closure_out = new Closure(WTF::Bind([] {}));
+void MakeClosure(base::OnceClosure** closure_out) {
+  *closure_out = new base::OnceClosure(WTF::Bind([] {}));
   LEAK_SANITIZER_IGNORE_OBJECT(*closure_out);
 }
 
 TEST(FunctionalTest, ThreadRestriction) {
-  Closure* closure = nullptr;
+  base::OnceClosure* closure = nullptr;
 
   base::Thread thread("testing");
   thread.Start();
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py
index f947f34..3157ce4 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor.py
@@ -40,49 +40,53 @@
             absolute_path = self.finder.path_from_chromium_base(relpath)
             if not absolute_path.startswith(self.finder.layout_tests_dir()):
                 continue
-            owners_file, owners = self.find_and_extract_owners(self.filesystem.dirname(relpath))
+            owners_file = self.find_owners_file(self.filesystem.dirname(relpath))
             if not owners_file:
                 continue
+            owners = self.extract_owners(owners_file)
             owned_directory = self.filesystem.dirname(owners_file)
             owned_directory_relpath = self.filesystem.relpath(owned_directory, self.finder.layout_tests_dir())
             email_map[tuple(owners)].add(owned_directory_relpath)
         return {owners: sorted(owned_directories) for owners, owned_directories in email_map.iteritems()}
 
-    def find_and_extract_owners(self, start_directory):
-        """Find the first enclosing OWNERS file for a given path and extract owners.
+    # TODO(robertma): Do we really need to worry about empty OWNERS files?
+    def find_owners_file(self, start_directory):
+        """Find the first enclosing OWNERS file for a given path.
 
         Starting from the given directory, walks up the directory tree until the
         first non-empty OWNERS file is found or LayoutTests/external is reached.
         (OWNERS files with no valid emails are also considered empty.)
 
         Args:
-            start_directory: A relative path from the root of the repository.
+            start_directory: A relative path from the root of the repository, or
+                an absolute path.
 
         Returns:
-            (path, owners): the absolute path to the first non-empty OWNERS file
-            found, and a list of valid owners.
-            Or (None, None) if not found.
+            The absolute path to the first non-empty OWNERS file found, or None
+            if not found.
         """
-        # Absolute paths do not work with path_from_chromium_base (os.path.join).
-        assert not self.filesystem.isabs(start_directory)
-        directory = self.finder.path_from_chromium_base(start_directory)
+        if self.filesystem.isabs(start_directory):
+            directory = start_directory
+        else:
+            directory = self.finder.path_from_chromium_base(start_directory)
         external_root = self.finder.path_from_layout_tests('external')
         # Changes to both LayoutTests/TestExpectations and the entire
         # LayoutTests/FlagExpectations/ directory should be skipped and not
         # raise an assertion.
         if directory == self.finder.layout_tests_dir() or \
            directory.startswith(self.finder.path_from_layout_tests('FlagExpectations')):
-            return None, None
+            return None
         assert directory.startswith(external_root), '%s must start with %s' % (
             directory, external_root)
         while directory != external_root:
             owners_file = self.filesystem.join(directory, 'OWNERS')
             if self.filesystem.isfile(self.finder.path_from_chromium_base(owners_file)):
-                owners = self.extract_owners(owners_file)
-                if owners:
-                    return owners_file, owners
+                # TODO(robertma): Avoid parsing the file twice (find_owners_file
+                # only returns the path, which is read and parsed again later).
+                if self.extract_owners(owners_file):
+                    return owners_file
             directory = self.filesystem.dirname(directory)
-        return None, None
+        return None
 
     def extract_owners(self, owners_file):
         """Extract owners from an OWNERS file.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor_unittest.py
index 9a580c4..6e72505 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/directory_owners_extractor_unittest.py
@@ -43,52 +43,48 @@
              ('b@chromium.org',): ['external/wpt/baz/x']}
         )
 
-    def test_find_and_extract_owners_current_dir(self):
+    def test_find_owners_file_current_dir(self):
         self.filesystem.files = {
             ABS_WPT_BASE + '/foo/OWNERS': 'a@chromium.org'
         }
-        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/foo'),
-                         (ABS_WPT_BASE + '/foo/OWNERS', ['a@chromium.org']))
+        self.assertEqual(self.extractor.find_owners_file(REL_WPT_BASE + '/foo'), ABS_WPT_BASE + '/foo/OWNERS')
 
-    def test_find_and_extract_owners_ancestor(self):
+    def test_find_owners_file_ancestor(self):
         self.filesystem.files = {
             ABS_WPT_BASE + '/x/OWNERS': 'a@chromium.org',
             ABS_WPT_BASE + '/x/y/z.html': '',
         }
-        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/x/y'),
-                         (ABS_WPT_BASE + '/x/OWNERS', ['a@chromium.org']))
+        self.assertEqual(self.extractor.find_owners_file(REL_WPT_BASE + '/x/y'), ABS_WPT_BASE + '/x/OWNERS')
 
-    def test_find_and_extract_owners_not_found(self):
+    def test_find_owners_file_not_found(self):
         self.filesystem.files = {
             ABS_WPT_BASE + '/foo/OWNERS': 'a@chromium.org',
             '/mock-checkout/third_party/WebKit/LayoutTests/external/OWNERS': 'a@chromium.org',
             ABS_WPT_BASE + '/x/y/z.html': '',
         }
-        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/x/y'),
-                         (None, None))
+        self.assertEqual(self.extractor.find_owners_file(REL_WPT_BASE + '/x/y'), None)
 
-    def test_find_and_extract_owners_skip_empty(self):
+    def test_find_owners_file_skip_empty(self):
         self.filesystem.files = {
             ABS_WPT_BASE + '/x/OWNERS': 'a@chromium.org',
             ABS_WPT_BASE + '/x/y/OWNERS': '# b@chromium.org',
             ABS_WPT_BASE + '/x/y/z.html': '',
         }
-        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/x/y'),
-                         (ABS_WPT_BASE + '/x/OWNERS', ['a@chromium.org']))
+        self.assertEqual(self.extractor.find_owners_file(REL_WPT_BASE + '/x/y'), ABS_WPT_BASE + '/x/OWNERS')
 
-    def test_find_and_extract_owners_absolute_path(self):
-        with self.assertRaises(AssertionError):
-            self.extractor.find_and_extract_owners('/absolute/path')
+    def test_find_owners_file_absolute_path(self):
+        self.filesystem.files = {
+            ABS_WPT_BASE + '/foo/OWNERS': 'a@chromium.org'
+        }
+        self.assertEqual(self.extractor.find_owners_file(ABS_WPT_BASE + '/foo'), ABS_WPT_BASE + '/foo/OWNERS')
 
-    def test_find_and_extract_owners_out_of_tree(self):
+    def test_find_owners_file_out_of_tree(self):
         with self.assertRaises(AssertionError):
-            self.extractor.find_and_extract_owners('third_party/WebKit/LayoutTests/other')
+            self.extractor.find_owners_file('third_party/WebKit/LayoutTests/other')
         self.assertEqual(
-            self.extractor.find_and_extract_owners('third_party/WebKit/LayoutTests'),
-            (None, None))
+            self.extractor.find_owners_file('third_party/WebKit/LayoutTests'), None)
         self.assertEqual(
-            self.extractor.find_and_extract_owners('third_party/WebKit/LayoutTests/FlagExpectations/foo-bar'),
-            (None, None))
+            self.extractor.find_owners_file('third_party/WebKit/LayoutTests/FlagExpectations/foo-bar'), None)
 
     def test_extract_owners(self):
         self.filesystem.files = {
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/import_notifier.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/import_notifier.py
new file mode 100644
index 0000000..c34b7018
--- /dev/null
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/import_notifier.py
@@ -0,0 +1,268 @@
+# 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.
+
+"""Sends notifications after automatic imports (WIP).
+
+Automatically file bugs for new failures caused by WPT imports for opted-in
+directories.
+
+Design doc: https://docs.google.com/document/d/1W3V81l94slAC_rPcTKWXgv3YxRxtlSIAxi3yj6NsbBw/edit?usp=sharing
+
+During the implementation phase, we do not open bugs but log everything instead.
+"""
+
+from collections import defaultdict
+import logging
+import re
+
+from webkitpy.common.path_finder import PathFinder
+from webkitpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor
+from webkitpy.w3c.wpt_expectations_updater import UMBRELLA_BUG
+
+_log = logging.getLogger(__name__)
+
+GITHUB_COMMIT_PREFIX = 'https://github.com/w3c/web-platform-tests/commit/'
+SHORT_GERRIT_PREFIX = 'https://crrev.com/c/'
+
+
+class ImportNotifier(object):
+
+    def __init__(self, host, chromium_git, local_wpt):
+        self.host = host
+        self.git = chromium_git
+        self.local_wpt = local_wpt
+
+        self.default_port = host.port_factory.get()
+        self.finder = PathFinder(host.filesystem)
+        self.owners_extractor = DirectoryOwnersExtractor(host.filesystem)
+        self.new_failures_by_directory = defaultdict(list)
+
+    def main(self, wpt_revision_start, wpt_revision_end, rebaselined_tests, test_expectations, issue, patchset):
+        """Files bug reports for new failures.
+
+        Args:
+            wpt_revision_start: The start of the imported WPT revision range
+                (exclusive), i.e. the last imported revision.
+            wpt_revision_end: The end of the imported WPT revision range
+                (inclusive), i.e. the current imported revision.
+            rebaselined_tests: A list of test names that have been rebaselined.
+            test_expectations: A dictionary mapping names of tests that cannot
+                be rebaselined to a list of new test expectation lines.
+            issue: The issue number of the import CL (a string).
+            patchset: The patchset number of the import CL (a string).
+
+        Note: "test names" are paths of the tests relative to LayoutTests.
+        """
+        gerrit_url = SHORT_GERRIT_PREFIX + issue
+        gerrit_url_with_ps = gerrit_url + '/' + patchset + '/'
+
+        changed_test_baselines = self.find_changed_baselines_of_tests(rebaselined_tests)
+        self.examine_baseline_changes(changed_test_baselines, gerrit_url_with_ps)
+        self.examine_new_test_expectations(test_expectations)
+
+        self.file_new_failures(wpt_revision_start, wpt_revision_end, issue, gerrit_url)
+
+    def find_changed_baselines_of_tests(self, rebaselined_tests):
+        """Finds the corresponding changed baselines of each test.
+
+        Args:
+            rebaselined_tests: A list of test names that have been rebaselined.
+
+        Returns:
+            A dictionary mapping test names to paths of their baselines changed
+            in this import CL (paths relative to the root of Chromium repo).
+        """
+        test_baselines = {}
+        changed_files = self.git.changed_files()
+        for test_name in rebaselined_tests:
+            test_without_ext, _ = self.host.filesystem.splitext(test_name)
+            changed_baselines = []
+            # TODO(robertma): Refactor this into layout_tests.port.base.
+            baseline_name = test_without_ext + '-expected.txt'
+            for changed_file in changed_files:
+                if changed_file.endswith(baseline_name):
+                    changed_baselines.append(changed_file)
+            if changed_baselines:
+                test_baselines[test_name] = changed_baselines
+        return test_baselines
+
+    def examine_baseline_changes(self, changed_test_baselines, gerrit_url_with_ps):
+        """Examines all changed baselines to find new failures.
+
+        Args:
+            changed_test_baselines: A dictionary mapping test names to paths of
+                changed baselines.
+            gerrit_url_with_ps: Gerrit URL of this CL with the patchset number.
+        """
+        for test_name, changed_baselines in changed_test_baselines.iteritems():
+            directory = self._find_owned_directory(test_name)
+            if not directory:
+                _log.warning('Cannot find OWNERS of %s', test_name)
+                continue
+
+            for baseline in changed_baselines:
+                if self.more_failures_in_baseline(baseline):
+                    self.new_failures_by_directory[directory].append(
+                        TestFailure(TestFailure.BASELINE_CHANGE, test_name,
+                                    baseline_path=baseline, gerrit_url_with_ps=gerrit_url_with_ps)
+                    )
+
+    def more_failures_in_baseline(self, baseline):
+        diff = self.git.run(['diff', '-U0', 'origin/master', '--', baseline])
+        delta_failures = 0
+        for line in diff.splitlines():
+            if line.startswith('+FAIL'):
+                delta_failures += 1
+            if line.startswith('-FAIL'):
+                delta_failures -= 1
+        return delta_failures > 0
+
+    def examine_new_test_expectations(self, test_expectations):
+        """Examines new test expectations to find new failures.
+
+        Args:
+            test_expectations: A dictionary mapping names of tests that cannot
+                be rebaselined to a list of new test expectation lines.
+        """
+        for test_name, expectation_lines in test_expectations.iteritems():
+            directory = self._find_owned_directory(test_name)
+            if not directory:
+                _log.warning('Cannot find OWNERS of %s', test_name)
+                continue
+
+            for expectation_line in expectation_lines:
+                self.new_failures_by_directory[directory].append(
+                    TestFailure(TestFailure.NEW_EXPECTATION, test_name,
+                                expectation_line=expectation_line)
+                )
+
+    # TODO(robertma): This method should populate a MonorailIssue (TBD) so that
+    # it can be passed to Monorail API and easily tested.
+    def file_new_failures(self, wpt_revision_start, wpt_revision_end, issue, gerrit_url):
+        """Files bug reports for new failures.
+
+        Args:
+            wpt_revision_start: The start of the imported WPT revision range
+                (exclusive), i.e. the last imported revision.
+            wpt_revision_end: The end of the imported WPT revision range
+                (inclusive), i.e. the current imported revision.
+            issue: The issue number of the import CL (a string).
+            gerrit_url: Gerrit URL of the CL.
+        """
+        imported_commits = self.local_wpt.commits_in_range(wpt_revision_start, wpt_revision_end)
+        for directory, failures in self.new_failures_by_directory.iteritems():
+            title = '[WPT] New failures introduced in {} by import {}'.format(directory, issue)
+            _log.info(title)
+
+            full_directory = self.host.filesystem.join(self.finder.layout_tests_dir(), directory)
+            owners_file = self.host.filesystem.join(full_directory, 'OWNERS')
+            owners = self.owners_extractor.extract_owners(owners_file)
+            _log.info("Owners: %s", ' '.join(owners))
+
+            prologue = ('WPT import {} introduced new failures in {}:\n\n'
+                        'List of new failures:\n'.format(gerrit_url, directory))
+            failure_list = ''
+            for failure in failures:
+                failure_list += str(failure) + '\n'
+
+            epilogue = '\nThis import contains upstream changes from {} to {}:\n'.format(
+                wpt_revision_start, wpt_revision_end
+            )
+            commit_list = self.format_commit_list(imported_commits, full_directory)
+
+            description = prologue + failure_list + epilogue + commit_list
+            _log.info(description)
+
+    def format_commit_list(self, imported_commits, directory):
+        """Formats the list of imported WPT commits.
+
+        Imports affecting the given directory will be highlighted.
+
+        Args:
+            imported_commits: A list of imported WPT commits (SHAs).
+            directory: The directory for which the list is formatted (a path
+                relative to the root of Chromium repo).
+
+        Returns:
+            A multi-line string.
+        """
+        commit_list = ''
+        for commit in imported_commits:
+            line = '{}: {}'.format(self.local_wpt.commit_subject(commit), GITHUB_COMMIT_PREFIX + commit)
+            if self.local_wpt.is_commit_affecting_directory(commit, directory):
+                line += ' [affecting this directory]'
+            commit_list += line + '\n'
+        return commit_list
+
+    def _find_owned_directory(self, test_name):
+        """Finds the lowest directory that contains the test and has OWNERS.
+
+        Args:
+            The name of the test (a path relative to LayoutTests).
+
+        Returns:
+            The path of the found directory relative to LayoutTests.
+        """
+        abs_test_path = self.finder.path_from_layout_tests(test_name)
+        owners_file = self.owners_extractor.find_owners_file(self.host.filesystem.dirname(abs_test_path))
+        if not owners_file:
+            return None
+        owned_directory = self.host.filesystem.dirname(owners_file)
+        short_directory = self.host.filesystem.relpath(owned_directory, self.finder.layout_tests_dir())
+        return short_directory
+
+
+class TestFailure(object):
+    """A simple abstraction of a new test failure for the notifier."""
+
+    # Failure types:
+    BASELINE_CHANGE = 1
+    NEW_EXPECTATION = 2
+
+    def __init__(self, failure_type, test_name, expectation_line='', baseline_path='', gerrit_url_with_ps=''):
+        if failure_type == self.BASELINE_CHANGE:
+            assert baseline_path and gerrit_url_with_ps
+        else:
+            assert failure_type == self.NEW_EXPECTATION
+            assert expectation_line
+
+        self.failure_type = failure_type
+        self.test_name = test_name
+        self.expectation_line = expectation_line
+        self.baseline_path = baseline_path
+        self.gerrit_url_with_ps = gerrit_url_with_ps
+
+    def __str__(self):
+        if self.failure_type == self.BASELINE_CHANGE:
+            return self._format_baseline_change()
+        else:
+            return self._format_new_expectation()
+
+    def __eq__(self, other):
+        return (
+            self.failure_type == other.failure_type and
+            self.test_name == other.test_name and
+            self.expectation_line == other.expectation_line and
+            self.baseline_path == other.baseline_path and
+            self.gerrit_url_with_ps == other.gerrit_url_with_ps
+        )
+
+    def _format_baseline_change(self):
+        assert self.failure_type == self.BASELINE_CHANGE
+        result = ''
+        # TODO(robertma): Is there any better way than using regexp?
+        platform = re.search(r'/platform/([^/]+)/', self.baseline_path)
+        if platform:
+            result += '[ {} ] '.format(platform.group(1).capitalize())
+        result += '{} new failing tests: {}{}'.format(
+            self.test_name, self.gerrit_url_with_ps, self.baseline_path)
+        return result
+
+    def _format_new_expectation(self):
+        assert self.failure_type == self.NEW_EXPECTATION
+        # TODO(robertma): Are there saner ways to remove the link to the umbrella bug?
+        line = self.expectation_line
+        if line.startswith(UMBRELLA_BUG):
+            line = line[len(UMBRELLA_BUG):].lstrip()
+        return line
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/import_notifier_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/import_notifier_unittest.py
new file mode 100644
index 0000000..5eec76e1
--- /dev/null
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/import_notifier_unittest.py
@@ -0,0 +1,167 @@
+# 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 unittest
+
+from webkitpy.common.checkout.git_mock import MockGit
+from webkitpy.common.host_mock import MockHost
+from webkitpy.common.system.executive_mock import mock_git_commands
+from webkitpy.w3c.local_wpt_mock import MockLocalWPT
+from webkitpy.w3c.import_notifier import ImportNotifier, TestFailure
+from webkitpy.w3c.wpt_expectations_updater import UMBRELLA_BUG
+
+
+class ImportNotifierTest(unittest.TestCase):
+
+    def setUp(self):
+        self.host = MockHost()
+        self.git = self.host.git()
+        self.local_wpt = MockLocalWPT()
+        self.notifier = ImportNotifier(self.host, self.git, self.local_wpt)
+
+    def test_find_changed_baselines_of_tests(self):
+        changed_files = [
+            'third_party/WebKit/LayoutTests/external/wpt/foo/bar.html',
+            'third_party/WebKit/LayoutTests/external/wpt/foo/bar-expected.txt',
+            'third_party/WebKit/LayoutTests/platform/linux/external/wpt/foo/bar-expected.txt',
+            'third_party/WebKit/LayoutTests/external/wpt/random_stuff.html',
+        ]
+        self.git.changed_files = lambda: changed_files
+        self.assertEqual(self.notifier.find_changed_baselines_of_tests(['external/wpt/foo/bar.html']),
+                         {'external/wpt/foo/bar.html': [
+                             'third_party/WebKit/LayoutTests/external/wpt/foo/bar-expected.txt',
+                             'third_party/WebKit/LayoutTests/platform/linux/external/wpt/foo/bar-expected.txt',
+                         ]})
+
+    def test_more_failures_in_baseline_more_fails(self):
+        # Replacing self.host.executive won't work here, because ImportNotifier
+        # has been instantiated with a MockGit backed by an empty MockExecutive.
+        executive = mock_git_commands({
+            'diff': ('diff --git a/foo-expected.txt b/foo-expected.txt\n'
+                     '--- a/foo-expected.txt\n'
+                     '+++ b/foo-expected.txt\n'
+                     '-FAIL an old failure\n'
+                     '+FAIL new failure 1\n'
+                     '+FAIL new failure 2\n')
+        })
+        self.notifier.git = MockGit(executive=executive)
+        self.assertTrue(self.notifier.more_failures_in_baseline('foo-expected.txt'))
+        self.assertEqual(executive.calls, [['git', 'diff', '-U0', 'origin/master', '--', 'foo-expected.txt']])
+
+    def test_more_failures_in_baseline_fewer_fails(self):
+        executive = mock_git_commands({
+            'diff': '''diff --git a/foo-expected.txt b/foo-expected.txt
+--- a/foo-expected.txt
++++ b/foo-expected.txt
+-FAIL an old failure
+-FAIL new failure 1
++FAIL new failure 2
+'''
+        })
+        self.notifier.git = MockGit(executive=executive)
+        self.assertFalse(self.notifier.more_failures_in_baseline('foo-expected.txt'))
+
+    def test_more_failures_in_baseline_same_fails(self):
+        executive = mock_git_commands({
+            'diff': '''diff --git a/foo-expected.txt b/foo-expected.txt
+--- a/foo-expected.txt
++++ b/foo-expected.txt
+-FAIL an old failure
++FAIL new failure 1
+'''
+        })
+        self.notifier.git = MockGit(executive=executive)
+        self.assertFalse(self.notifier.more_failures_in_baseline('foo-expected.txt'))
+
+    def test_examine_baseline_changes(self):
+        self.host.filesystem.write_text_file(
+            '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt/foo/OWNERS',
+            'test@chromium.org'
+        )
+        changed_test_baselines = {'external/wpt/foo/bar.html': [
+            'third_party/WebKit/LayoutTests/external/wpt/foo/bar-expected.txt',
+            'third_party/WebKit/LayoutTests/platform/linux/external/wpt/foo/bar-expected.txt',
+        ]}
+        gerrit_url_with_ps = 'https://crrev.com/c/12345/3/'
+        self.notifier.more_failures_in_baseline = lambda _: True
+        self.notifier.examine_baseline_changes(changed_test_baselines, gerrit_url_with_ps)
+
+        self.assertEqual(
+            self.notifier.new_failures_by_directory,
+            {'external/wpt/foo': [
+                TestFailure(TestFailure.BASELINE_CHANGE, 'external/wpt/foo/bar.html',
+                            baseline_path='third_party/WebKit/LayoutTests/external/wpt/foo/bar-expected.txt',
+                            gerrit_url_with_ps=gerrit_url_with_ps),
+                TestFailure(TestFailure.BASELINE_CHANGE, 'external/wpt/foo/bar.html',
+                            baseline_path='third_party/WebKit/LayoutTests/platform/linux/external/wpt/foo/bar-expected.txt',
+                            gerrit_url_with_ps=gerrit_url_with_ps),
+            ]}
+        )
+
+    def test_examine_new_test_expectations(self):
+        self.host.filesystem.write_text_file(
+            '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt/foo/OWNERS',
+            'test@chromium.org'
+        )
+        test_expectations = {'external/wpt/foo/bar.html': [
+            'crbug.com/12345 [ Linux ] external/wpt/foo/bar.html [ Fail ]',
+            'crbug.com/12345 [ Win ] external/wpt/foo/bar.html [ Timeout ]',
+        ]}
+        self.notifier.examine_new_test_expectations(test_expectations)
+        self.assertEqual(
+            self.notifier.new_failures_by_directory,
+            {'external/wpt/foo': [
+                TestFailure(TestFailure.NEW_EXPECTATION, 'external/wpt/foo/bar.html',
+                            expectation_line='crbug.com/12345 [ Linux ] external/wpt/foo/bar.html [ Fail ]'),
+                TestFailure(TestFailure.NEW_EXPECTATION, 'external/wpt/foo/bar.html',
+                            expectation_line='crbug.com/12345 [ Win ] external/wpt/foo/bar.html [ Timeout ]'),
+            ]}
+        )
+
+    def test_format_commit_list(self):
+        imported_commits = ['SHA1', 'SHA2']
+
+        def _is_commit_affecting_directory(commit, directory):
+            self.assertIn(commit, imported_commits)
+            self.assertEqual(directory, 'directory')
+            return commit == 'SHA1'
+
+        self.local_wpt.is_commit_affecting_directory = _is_commit_affecting_directory
+        self.assertEqual(
+            self.notifier.format_commit_list(imported_commits, 'directory'),
+            'Fake subject: https://github.com/w3c/web-platform-tests/commit/SHA1 [affecting this directory]\n'
+            'Fake subject: https://github.com/w3c/web-platform-tests/commit/SHA2\n'
+        )
+
+    def test_test_failure_to_str_baseline_change(self):
+        failure = TestFailure(
+            TestFailure.BASELINE_CHANGE, 'external/wpt/foo/bar.html',
+            baseline_path='third_party/WebKit/LayoutTests/external/wpt/foo/bar-expected.txt',
+            gerrit_url_with_ps='https://crrev.com/c/12345/3/')
+        self.assertEqual(str(failure),
+                         'external/wpt/foo/bar.html new failing tests: https://crrev.com/c/12345/3/'
+                         'third_party/WebKit/LayoutTests/external/wpt/foo/bar-expected.txt')
+
+        platform_failure = TestFailure(
+            TestFailure.BASELINE_CHANGE, 'external/wpt/foo/bar.html',
+            baseline_path='third_party/WebKit/LayoutTests/platform/linux/external/wpt/foo/bar-expected.txt',
+            gerrit_url_with_ps='https://crrev.com/c/12345/3/')
+        self.assertEqual(str(platform_failure),
+                         '[ Linux ] external/wpt/foo/bar.html new failing tests: https://crrev.com/c/12345/3/'
+                         'third_party/WebKit/LayoutTests/platform/linux/external/wpt/foo/bar-expected.txt')
+
+    def test_test_failure_to_str_new_expectation(self):
+        failure = TestFailure(
+            TestFailure.NEW_EXPECTATION, 'external/wpt/foo/bar.html',
+            expectation_line='crbug.com/12345 [ Linux ] external/wpt/foo/bar.html [ Fail ]'
+        )
+        self.assertEqual(str(failure),
+                         'crbug.com/12345 [ Linux ] external/wpt/foo/bar.html [ Fail ]')
+
+        failure_with_umbrella_bug = TestFailure(
+            TestFailure.NEW_EXPECTATION, 'external/wpt/foo/bar.html',
+            expectation_line=UMBRELLA_BUG + ' external/wpt/foo/bar.html [ Fail ]'
+        )
+        self.assertEqual(str(failure_with_umbrella_bug),
+                         'external/wpt/foo/bar.html [ Fail ]')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
index bd6907e..ee15546 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
@@ -162,6 +162,35 @@
         """
         return self.run(['git', 'log', '-1', '--grep', grep_str])
 
+    def commits_in_range(self, revision_start, revision_end):
+        """Finds all commits in the given range.
+
+        Args:
+            revision_start: The start of the revision range (exclusive).
+            revision_end: The end of the revision range (inclusive).
+
+        Return:
+            A list of (SHA, commit subject) pairs ordered reverse-chronologically.
+        """
+        revision_range = revision_start + '..' + revision_end
+        output = self.run(['git', 'rev-list', '--pretty=oneline', revision_range])
+        commits = []
+        for line in output.splitlines():
+            # Split at the first space.
+            commits.append(tuple(line.strip().split(' ', 1)))
+        return commits
+
+    def is_commit_affecting_directory(self, commit, directory):
+        """Checks if a commit affects a directory."""
+        exit_code = self.run(['git', 'diff-tree', '--quiet', '--no-commit-id', commit, '--', directory],
+                             return_exit_code=True)
+        return exit_code == 1
+
+    def commit_subject(self, commit):
+        """Returns the subject of a commit."""
+        output = self.run(['git', 'show', '--format=%s', '-q', commit])
+        return output.strip()
+
     # Note: the regexes in the two following methods use the start-of-line
     # anchor ^ to prevent matching quoted text in commit messages. The end-of-
     # line anchor $ is omitted to accommodate trailing whitespaces and non-
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_mock.py
index 90cc3de..25fad4f 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_mock.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_mock.py
@@ -33,6 +33,13 @@
         self.apply_patch_called += 1
         return error
 
+    # This is a dummy stub intended to be replaced in tests.
+    def is_commit_affecting_directory(self, _, __):
+        return False
+
+    def commit_subject(self, _):
+        return 'Fake subject'
+
     def seek_change_id(self, change_id):
         return change_id in self.change_ids
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
index 159b6f7f..171f07d4 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
@@ -105,6 +105,24 @@
 
         self.assertEqual(local_wpt.test_patch('dummy patch'), (False, 'MOCK failed applying patch'))
 
+    def test_is_commit_affecting_directory(self):
+        host = MockHost()
+        # return_exit_code=True is passed to run() in the method under test,
+        # so the mock return value should be exit code instead of output.
+        host.executive = mock_git_commands({'diff-tree': 1}, strict=True)
+        local_wpt = LocalWPT(host, 'token')
+
+        self.assertTrue(local_wpt.is_commit_affecting_directory('HEAD', 'css/'))
+        self.assertEqual(host.executive.calls, [['git', 'diff-tree', '--quiet', '--no-commit-id', 'HEAD', '--', 'css/']])
+
+    def test_commit_subject(self):
+        host = MockHost()
+        host.executive = mock_git_commands({'show': 'Fake subject\n'}, strict=True)
+        local_wpt = LocalWPT(host, 'token')
+
+        self.assertTrue(local_wpt.commit_subject('HEAD'), 'Fake subject')
+        self.assertEqual(host.executive.calls, [['git', 'show', '--format=%s', '-q', 'HEAD']])
+
     def test_seek_change_id(self):
         host = MockHost()
         local_wpt = LocalWPT(host, 'token')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
index 844a1b9..a860d1ed 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -15,6 +15,7 @@
 import datetime
 import json
 import logging
+import re
 
 from webkitpy.common.net.buildbot import current_build_link
 from webkitpy.common.net.git_cl import GitCL
@@ -25,6 +26,7 @@
 from webkitpy.w3c.chromium_exportable_commits import exportable_commits_over_last_n_commits
 from webkitpy.w3c.common import read_credentials, is_testharness_baseline, is_file_exportable
 from webkitpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor
+from webkitpy.w3c.import_notifier import ImportNotifier
 from webkitpy.w3c.local_wpt import LocalWPT
 from webkitpy.w3c.test_copier import TestCopier
 from webkitpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater
@@ -58,8 +60,14 @@
         # Another Git instance with local WPT as CWD, which can only be
         # instantiated after the working directory is created.
         self.wpt_git = None
-        # The WPT revision we are importing.
+        # The WPT revision we are importing and the one imported last time.
         self.wpt_revision = None
+        self.last_wpt_revision = None
+        # A list of rebaselined tests and a dictionary of new test expectations
+        # mapping failing tests to platforms to
+        # wpt_expectations_updater.SimpleTestResult.
+        self.rebaselined_tests = None
+        self.new_test_expectations = None
         self.verbose = False
 
     def main(self, argv=None):
@@ -98,6 +106,7 @@
 
         _log.debug('Noting the revision we are importing.')
         self.wpt_revision = self.wpt_git.latest_git_commit()
+        self.last_wpt_revision = self._get_last_imported_wpt_revision()
         import_commit = 'wpt@%s' % self.wpt_revision
 
         _log.info('Importing %s to Chromium %s', import_commit, chromium_revision)
@@ -156,6 +165,9 @@
         if not self.run_commit_queue_for_cl():
             return 1
 
+        if not self.send_notifications(local_wpt):
+            return 1
+
         return 0
 
     def update_expectations_for_cl(self):
@@ -529,7 +541,7 @@
         """
         _log.info('Adding test expectations lines to LayoutTests/TestExpectations.')
         expectation_updater = WPTExpectationsUpdater(self.host)
-        expectation_updater.run(args=[])
+        self.rebaselined_tests, self.new_test_expectations = expectation_updater.update_expectations()
 
     def update_all_test_expectations_files(self, deleted_tests, renamed_tests):
         """Updates all test expectations files for tests that have been deleted or renamed.
@@ -596,3 +608,27 @@
         if not abs_path.startswith(self.finder.layout_tests_dir()):
             return None
         return self.fs.relpath(abs_path, self.finder.layout_tests_dir())
+
+    def _get_last_imported_wpt_revision(self):
+        """Finds the last imported WPT revision."""
+        # TODO(robertma): Only match commit subjects.
+        output = self.chromium_git.most_recent_log_matching('^Import wpt@', self.finder.chromium_base())
+        # No line-start anchor (^) below because of the formatting of output.
+        result = re.search(r'Import wpt@(\w+)', output)
+        if result:
+            return result.group(1)
+        else:
+            _log.error('Cannot find last WPT import.')
+            return None
+
+    def send_notifications(self, local_wpt):
+        # Check the format of these values.
+        issue = self.git_cl.run(['status', '--field=id']).strip()
+        # FIXME(robertma): this does not work! https://crbug.com/792611
+        patchset = self.git_cl.run(['status', '--field=patch']).strip()
+        # Construct the notifier here so that any errors won't affect the import.
+        notifier = ImportNotifier(self.host, self.chromium_git, local_wpt)
+        notifier.main(self.last_wpt_revision, self.wpt_revision,
+                      self.rebaselined_tests, self.new_test_expectations,
+                      issue, patchset)
+        return True
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
index 2e88d6f6..a20d008 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
@@ -12,15 +12,24 @@
 import argparse
 import copy
 import logging
+from collections import defaultdict, namedtuple
 
 from webkitpy.common.memoized import memoized
 from webkitpy.common.net.git_cl import GitCL
 from webkitpy.common.path_finder import PathFinder
+from webkitpy.common.system.executive import ScriptError
+from webkitpy.common.system.log_utils import configure_logging
 from webkitpy.w3c.wpt_manifest import WPTManifest
 
 _log = logging.getLogger(__name__)
 
 MARKER_COMMENT = '# ====== New tests from wpt-importer added here ======'
+UMBRELLA_BUG = 'crbug.com/626703'
+
+# TODO(robertma): Investigate reusing layout_tests.models.test_expectations and
+# alike in this module.
+
+SimpleTestResult = namedtuple('SimpleTestResult', ['expected', 'actual', 'bug'])
 
 
 class WPTExpectationsUpdater(object):
@@ -34,24 +43,33 @@
         self.ports_with_all_pass = set()
 
     def run(self, args=None):
-        """Downloads text new baselines and adds test expectations lines."""
         parser = argparse.ArgumentParser(description=__doc__)
         parser.add_argument('-v', '--verbose', action='store_true', help='More verbose logging.')
         args = parser.parse_args(args)
 
         log_level = logging.DEBUG if args.verbose else logging.INFO
-        logging.basicConfig(level=log_level, format='%(message)s')
+        configure_logging(logging_level=log_level, include_time=True)
 
+        self.update_expectations()
+
+        return 0
+
+    def update_expectations(self):
+        """Downloads text new baselines and adds test expectations lines.
+
+        Returns:
+            A pair: A set of tests that are rebaselined, and a dictionary
+            mapping tests that couldn't be rebaselined to lists of expectation
+            lines written to TestExpectations.
+        """
         issue_number = self.get_issue_number()
         if issue_number == 'None':
-            _log.error('No issue on current branch.')
-            return 1
+            raise ScriptError('No issue on current branch.')
 
         build_to_status = self.get_latest_try_jobs()
         _log.debug('Latest try jobs: %r', build_to_status)
         if not build_to_status:
-            _log.error('No try job information was collected.')
-            return 1
+            raise ScriptError('No try job information was collected.')
 
         # The manifest may be used below to do check which tests are reference tests.
         WPTManifest.ensure_manifest(self.host)
@@ -71,10 +89,17 @@
             # platform_result is a dict mapping platforms to results.
             test_expectations[test_name] = self.merge_same_valued_keys(platform_result)
 
-        test_expectations = self.download_text_baselines(test_expectations)
-        test_expectation_lines = self.create_line_list(test_expectations)
+        # At this point, test_expectations looks like: {
+        #     'test-with-failing-result': {
+        #         ('port-name1', 'port-name2'): SimpleTestResult,
+        #         'port-name3': SimpleTestResult
+        #     }
+        # }
+
+        rebaselined_tests, test_expectations = self.download_text_baselines(test_expectations)
+        test_expectation_lines = self.create_line_dict(test_expectations)
         self.write_to_test_expectations(test_expectation_lines)
-        return 0
+        return rebaselined_tests, test_expectation_lines
 
     def get_issue_number(self):
         """Returns current CL number. Can be replaced in unit tests."""
@@ -96,12 +121,8 @@
 
         Returns:
             A dictionary with the structure: {
-                test-with-failing-result: {
-                    'full-port-name': {
-                        'expected': 'TIMEOUT',
-                        'actual': 'CRASH',
-                        'bug': 'crbug.com/11111'
-                    }
+                'test-with-failing-result': {
+                    'full-port-name': SimpleTestResult
                 }
             }
             If results could be fetched but none are failing,
@@ -116,37 +137,40 @@
             _log.warning('No results for build %s', build)
             self.ports_with_no_results.add(self.port_name(build))
             return {}
-        test_results = [result for result in layout_test_results.didnt_run_as_expected_results() if not result.did_pass()]
-        return self.generate_results_dict(self.port_name(build), test_results)
+        failing_test_results = [result for result in layout_test_results.didnt_run_as_expected_results() if not result.did_pass()]
+        return self.generate_results_dict(self.port_name(build), failing_test_results)
 
     @memoized
     def port_name(self, build):
         return self.host.builders.port_name_for_builder_name(build.builder_name)
 
-    def generate_results_dict(self, full_port_name, test_results):
+    def generate_results_dict(self, full_port_name, layout_test_results):
         """Makes a dict with results for one platform.
 
         Args:
             full_port_name: The fully-qualified port name, e.g. "win-win10".
-            test_results: A list of LayoutTestResult objects.
+            layout_test_results: A list of LayoutTestResult objects.
 
         Returns:
-            A dict mapping the full port name to a dict with the results for
-            the given test and platform.
+            A dictionary with the structure: {
+                'test-name': {
+                    'full-port-name': SimpleTestResult
+                }
+            }
         """
         test_dict = {}
-        for result in test_results:
+        for result in layout_test_results:
             test_name = result.test_name()
 
             if not self.port.is_wpt_test(test_name):
                 continue
 
             test_dict[test_name] = {
-                full_port_name: {
-                    'expected': result.expected_results(),
-                    'actual': result.actual_results(),
-                    'bug': 'crbug.com/626703'
-                }
+                full_port_name: SimpleTestResult(
+                    expected=result.expected_results(),
+                    actual=result.actual_results(),
+                    bug=UMBRELLA_BUG
+                )
             }
         return test_dict
 
@@ -220,22 +244,15 @@
             matching_value_keys = set()
         return merged_dict
 
-    def get_expectations(self, results, test_name=''):
-        """Returns a set of test expectations to use based on results.
+    def get_expectations(self, result, test_name=''):
+        """Returns a set of test expectations based on the result of a test.
 
         Returns a set of one or more test expectations based on the expected
         and actual results of a given test name. This function is to decide
         expectations for tests that could not be rebaselined.
 
         Args:
-            results: A dictionary that maps one test to its results. Example:
-                {
-                    'test_name': {
-                        'expected': 'PASS',
-                        'actual': 'FAIL',
-                        'bug': 'crbug.com/11111'
-                    }
-                }
+            result: A SimpleTestResult.
             test_name: The test name string (optional).
 
         Returns:
@@ -248,52 +265,61 @@
         # expectation is correct.
         # We also want to skip any new manual tests that are not automated;
         # see crbug.com/708241 for context.
-        if (results['actual'] == 'MISSING' or
-                '-manual.' in test_name and results['actual'] == 'TIMEOUT'):
+        if (result.actual == 'MISSING' or
+                '-manual.' in test_name and result.actual == 'TIMEOUT'):
             return {'Skip'}
         expectations = set()
         failure_types = ('TEXT', 'IMAGE+TEXT', 'IMAGE', 'AUDIO')
         other_types = ('TIMEOUT', 'CRASH', 'PASS')
-        for actual in results['actual'].split():
+        for actual in result.actual.split():
             if actual in failure_types:
                 expectations.add('Failure')
             if actual in other_types:
                 expectations.add(actual.capitalize())
         return expectations
 
-    def create_line_list(self, merged_results):
+    def create_line_dict(self, merged_results):
         """Creates list of test expectations lines.
 
         Traverses through the given |merged_results| dictionary and parses the
         value to create one test expectations line per key.
 
+        Test expectation lines have the following format:
+            ['BUG_URL [PLATFORM(S)] TEST_NAME [EXPECTATION(S)]']
+
         Args:
             merged_results: A dictionary with the format:
                 {
-                    'test_name': {
-                        'platform': {
-                            'expected: 'PASS',
-                            'actual': 'FAIL',
-                            'bug': 'crbug.com/11111'
-                        }
+                    'test-with-failing-result': {
+                        ('port-name1', 'port-name2'): SimpleTestResult,
+                        'port-name3': SimpleTestResult
                     }
                 }
 
         Returns:
-            A list of test expectations lines with the format:
-            ['BUG_URL [PLATFORM(S)] TEST_NAME [EXPECTATION(S)]']
+            A dictionary from test names to a list of test expectation lines
+            (each SimpleTestResult turns into a line).
         """
-        line_list = []
+        line_dict = defaultdict(list)
         for test_name, port_results in sorted(merged_results.iteritems()):
             if not self.port.is_wpt_test(test_name):
-                _log.warning('Non-WPT test "%s" unexpectedly passed to create_line_list.', test_name)
+                _log.warning('Non-WPT test "%s" unexpectedly passed to create_line_dict.', test_name)
                 continue
-            for port_names, results in sorted(port_results.iteritems()):
-                line_list.append(self._create_line(test_name, port_names, results))
-        return line_list
+            for port_names, result in sorted(port_results.iteritems()):
+                line_dict[test_name].append(self._create_line(test_name, port_names, result))
+        return line_dict
 
-    def _create_line(self, test_name, port_names, results):
-        """Constructs and returns a test expectation line string."""
+    def _create_line(self, test_name, port_names, result):
+        """Constructs a test expectation line string.
+
+        Args:
+            test_name: The test name string.
+            port_names: A list of full port names that the line should apply to.
+            result: A SimpleTestResult.
+
+        Returns:
+            A string that contains a line of test expectation.
+        """
         port_names = self.tuple_or_value_to_list(port_names)
 
         # The set of ports with no results is assumed to have have no
@@ -307,22 +333,22 @@
         # also apply to any ports that we weren't able to get results for.
         port_names.extend(self.ports_with_no_results)
 
-        specifier_part = self.specifier_part(port_names, test_name)
+        specifier_part = self.specifier_part(test_name, port_names)
 
-        line_parts = [results['bug']]
+        line_parts = [result.bug]
         if specifier_part:
             line_parts.append(specifier_part)
         line_parts.append(test_name)
-        line_parts.append('[ %s ]' % ' '.join(self.get_expectations(results, test_name)))
+        line_parts.append('[ %s ]' % ' '.join(self.get_expectations(result, test_name)))
 
         return ' '.join(line_parts)
 
-    def specifier_part(self, port_names, test_name):
+    def specifier_part(self, test_name, port_names):
         """Returns the specifier part for a new test expectations line.
 
         Args:
+            test_name: The test name string.
             port_names: A list of full port names that the line should apply to.
-            test_name: The test name for the expectation line.
 
         Returns:
             The specifier part of the new expectation line, e.g. "[ Mac ]".
@@ -411,7 +437,7 @@
                 self.host.builders.platform_specifier_for_builder(builder_name).lower())
         return frozenset(all_platform_specifiers)
 
-    def write_to_test_expectations(self, line_list):
+    def write_to_test_expectations(self, line_dict):
         """Writes the given lines to the TestExpectations file.
 
         The place in the file where the new lines are inserted is after a marker
@@ -419,14 +445,18 @@
         including the marker line is appended to the end of the file.
 
         Args:
-            line_list: A list of lines to add to the TestExpectations file.
+            line_dict: A dictionary from test names to a list of test expectation lines.
         """
-        if not line_list:
+        if not line_dict:
             _log.info('No lines to write to TestExpectations.')
             return
+
         _log.info('Lines to write to TestExpectations:')
-        for line in line_list:
-            _log.info('  %s', line)
+        line_list = []
+        for lines in line_dict.itervalues():
+            for line in lines:
+                line_list.append(line)
+                _log.info('  %s', line)
 
         expectations_file_path = self.port.path_to_generic_test_expectations_file()
         file_contents = self.host.filesystem.read_text_file(expectations_file_path)
@@ -441,6 +471,7 @@
 
         self.host.filesystem.write_text_file(expectations_file_path, file_contents)
 
+    # TODO(robertma): Unit test this method.
     def download_text_baselines(self, test_results):
         """Fetches new baseline files for tests that should be rebaselined.
 
@@ -450,16 +481,18 @@
         failure test dictionary and the resulting dictionary is returned.
 
         Args:
-            test_results: A dict mapping test name to platform to test results.
+            test_results: A dictionary of failing test results, mapping test
+                names to lists of platforms to SimpleTestResult.
 
         Returns:
-            An updated test_results dictionary which should only contain
-            test failures for tests that couldn't be rebaselined.
+            A pair: A set of tests that are rebaselined, and a modified copy of
+            the test_results dictionary containing only tests that couldn't be
+            rebaselined.
         """
         tests_to_rebaseline, test_results = self.get_tests_to_rebaseline(test_results)
         if not tests_to_rebaseline:
             _log.info('No tests to rebaseline.')
-            return test_results
+            return tests_to_rebaseline, test_results
         _log.info('Tests to rebaseline:')
         for test in tests_to_rebaseline:
             _log.info('  %s', test)
@@ -473,43 +506,49 @@
             '--no-trigger-jobs',
             '--fill-missing',
         ] + tests_to_rebaseline)
-        return test_results
+        return tests_to_rebaseline, test_results
 
     def get_tests_to_rebaseline(self, test_results):
-        """Returns a list of tests to download new baselines for.
+        """Filters failing tests that can be rebaselined.
 
         Creates a list of tests to rebaseline depending on the tests' platform-
         specific results. In general, this will be non-ref tests that failed
         due to a baseline mismatch (rather than crash or timeout).
 
         Args:
-            test_results: A dictionary of failing test results, mapping tests
-                to platforms to result dicts.
+            test_results: A dictionary of failing test results, mapping test
+                names to lists of platforms to SimpleTestResult.
 
         Returns:
             A pair: A set of tests to be rebaselined, and a modified copy of
-            the test results dictionary. The tests to be rebaselined should
+            the test_results dictionary. The tests to be rebaselined should
             include testharness.js tests that failed due to a baseline mismatch.
         """
         new_test_results = copy.deepcopy(test_results)
         tests_to_rebaseline = set()
-        for test_path in test_results:
-            for platform, result in test_results[test_path].iteritems():
-                if self.can_rebaseline(test_path, result):
-                    del new_test_results[test_path][platform]
-                    tests_to_rebaseline.add(test_path)
+        for test_name in test_results:
+            for platforms, result in test_results[test_name].iteritems():
+                if self.can_rebaseline(test_name, result):
+                    del new_test_results[test_name][platforms]
+                    tests_to_rebaseline.add(test_name)
         return sorted(tests_to_rebaseline), new_test_results
 
-    def can_rebaseline(self, test_path, result):
-        if self.is_reference_test(test_path):
+    def can_rebaseline(self, test_name, result):
+        """Checks if a test can be rebaselined.
+
+        Args:
+            test_name: The test name string.
+            result: A SimpleTestResult.
+        """
+        if self.is_reference_test(test_name):
             return False
-        if result['actual'] in ('CRASH', 'TIMEOUT', 'MISSING'):
+        if result.actual in ('CRASH', 'TIMEOUT', 'MISSING'):
             return False
         return True
 
-    def is_reference_test(self, test_path):
-        """Checks whether a given file is a testharness.js test."""
-        return bool(self.port.reference_files(test_path))
+    def is_reference_test(self, test_name):
+        """Checks whether a given test is a reference test."""
+        return bool(self.port.reference_files(test_name))
 
     def _get_try_bots(self):
         return self.host.builders.all_try_builder_names()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
index da20181..7c580f83 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
@@ -11,10 +11,11 @@
 from webkitpy.common.net.git_cl import TryJobStatus
 from webkitpy.common.net.git_cl_mock import MockGitCL
 from webkitpy.common.net.layout_test_results import LayoutTestResult, LayoutTestResults
+from webkitpy.common.system.executive import ScriptError
 from webkitpy.common.system.log_testing import LoggingTestCase
 from webkitpy.layout_tests.builder_list import BuilderList
 from webkitpy.layout_tests.port.factory_mock import MockPortFactory
-from webkitpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater, MARKER_COMMENT
+from webkitpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater, SimpleTestResult, MARKER_COMMENT
 
 
 class WPTExpectationsUpdaterTest(LoggingTestCase):
@@ -202,11 +203,11 @@
             results_dict,
             {
                 'external/wpt/x/failing-test.html': {
-                    'test-mac-mac10.10': {
-                        'actual': 'IMAGE',
-                        'expected': 'PASS',
-                        'bug': 'crbug.com/626703',
-                    },
+                    'test-mac-mac10.10': SimpleTestResult(
+                        actual='IMAGE',
+                        expected='PASS',
+                        bug='crbug.com/626703',
+                    ),
                 },
             })
 
@@ -251,73 +252,76 @@
 
     def test_get_expectations(self):
         updater = WPTExpectationsUpdater(self.mock_host())
+        # Positional arguments of SimpleTestResult: (expected, actual, bug)
         self.assertEqual(
-            updater.get_expectations({'expected': 'FAIL', 'actual': 'PASS'}),
+            updater.get_expectations(SimpleTestResult('FAIL', 'PASS', 'bug')),
             {'Pass'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'FAIL', 'actual': 'TIMEOUT'}),
+            updater.get_expectations(SimpleTestResult('FAIL', 'TIMEOUT', 'bug')),
             {'Timeout'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'TIMEOUT', 'actual': 'PASS'}),
+            updater.get_expectations(SimpleTestResult('TIMEOUT', 'PASS', 'bug')),
             {'Pass'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'PASS', 'actual': 'TEXT PASS'}),
+            updater.get_expectations(SimpleTestResult('PASS', 'TEXT PASS', 'bug')),
             {'Pass', 'Failure'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'PASS', 'actual': 'TIMEOUT CRASH TEXT'}),
+            updater.get_expectations(SimpleTestResult('PASS', 'TIMEOUT CRASH TEXT', 'bug')),
             {'Crash', 'Failure', 'Timeout'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'SLOW CRASH FAIL TIMEOUT', 'actual': 'PASS'}),
+            updater.get_expectations(SimpleTestResult('SLOW CRASH FAIL TIMEOUT', 'PASS', 'bug')),
             {'Pass'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'Pass', 'actual': 'IMAGE+TEXT IMAGE IMAGE'}),
+            updater.get_expectations(SimpleTestResult('Pass', 'IMAGE+TEXT IMAGE IMAGE', 'bug')),
             {'Failure'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'Pass', 'actual': 'MISSING'}),
+            updater.get_expectations(SimpleTestResult('Pass', 'MISSING', 'bug')),
             {'Skip'})
         self.assertEqual(
-            updater.get_expectations({'expected': 'Pass', 'actual': 'TIMEOUT'}, test_name='foo/bar-manual.html'),
+            updater.get_expectations(SimpleTestResult('Pass', 'TIMEOUT', 'bug'), test_name='foo/bar-manual.html'),
             {'Skip'})
 
-    def test_create_line_list_old_tests(self):
+    def test_create_line_dict_old_tests(self):
         # In this example, there are two failures that are not in wpt.
         updater = WPTExpectationsUpdater(self.mock_host())
         results = {
             'fake/test/path.html': {
-                'one': {'expected': 'FAIL', 'actual': 'PASS', 'bug': 'crbug.com/test'},
-                'two': {'expected': 'FAIL', 'actual': 'PASS', 'bug': 'crbug.com/test'},
+                'one': SimpleTestResult(expected='FAIL', actual='PASS', bug='crbug.com/test'),
+                'two': SimpleTestResult(expected='FAIL', actual='PASS', bug='crbug.com/test'),
             }
         }
-        self.assertEqual(updater.create_line_list(results), [])
+        self.assertEqual(updater.create_line_dict(results), {})
 
-    def test_create_line_list_new_tests(self):
+    def test_create_line_dict_new_tests(self):
         # In this example, there are three unexpected results for wpt tests.
         # The new test expectation lines are sorted by test, and then specifier.
         updater = WPTExpectationsUpdater(self.mock_host())
         results = {
             'external/wpt/test/zzzz.html': {
-                'test-mac-mac10.10': {'expected': 'PASS', 'actual': 'TEXT', 'bug': 'crbug.com/test'},
+                'test-mac-mac10.10': SimpleTestResult(expected='PASS', actual='TEXT', bug='crbug.com/test'),
             },
             'virtual/foo/external/wpt/test/zzzz.html': {
-                'test-linux-trusty': {'expected': 'FAIL', 'actual': 'PASS', 'bug': 'crbug.com/test'},
-                'test-mac-mac10.11': {'expected': 'FAIL', 'actual': 'TIMEOUT', 'bug': 'crbug.com/test'},
+                'test-linux-trusty': SimpleTestResult(expected='FAIL', actual='PASS', bug='crbug.com/test'),
+                'test-mac-mac10.11': SimpleTestResult(expected='FAIL', actual='TIMEOUT', bug='crbug.com/test'),
             },
             'unrelated/test.html': {
-                'test-linux-trusty': {'expected': 'FAIL', 'actual': 'PASS', 'bug': 'crbug.com/test'},
+                'test-linux-trusty': SimpleTestResult(expected='FAIL', actual='PASS', bug='crbug.com/test'),
             },
         }
         self.assertEqual(
-            updater.create_line_list(results),
-            [
-                'crbug.com/test [ Mac10.10 ] external/wpt/test/zzzz.html [ Failure ]',
-                'crbug.com/test [ Trusty ] virtual/foo/external/wpt/test/zzzz.html [ Pass ]',
-                'crbug.com/test [ Mac10.11 ] virtual/foo/external/wpt/test/zzzz.html [ Timeout ]',
-            ])
+            updater.create_line_dict(results),
+            {
+                'external/wpt/test/zzzz.html': ['crbug.com/test [ Mac10.10 ] external/wpt/test/zzzz.html [ Failure ]'],
+                'virtual/foo/external/wpt/test/zzzz.html': [
+                    'crbug.com/test [ Trusty ] virtual/foo/external/wpt/test/zzzz.html [ Pass ]',
+                    'crbug.com/test [ Mac10.11 ] virtual/foo/external/wpt/test/zzzz.html [ Timeout ]',
+                ],
+            })
 
     def test_specifier_part(self):
         updater = WPTExpectationsUpdater(self.mock_host())
-        self.assertEqual(updater.specifier_part(['test-mac-mac10.10'], 'x/y.html'), '[ Mac10.10 ]')
-        self.assertEqual(updater.specifier_part([], 'x/y.html'), '')
+        self.assertEqual(updater.specifier_part('x/y.html', ['test-mac-mac10.10']), '[ Mac10.10 ]')
+        self.assertEqual(updater.specifier_part('x/y.html', []), '')
 
     def test_skipped_specifiers_when_test_is_wontfix(self):
         host = self.mock_host()
@@ -378,11 +382,11 @@
         host.filesystem.write_text_file('/test.checkout/LayoutTests/external/wpt/test.html', '')
         updater = WPTExpectationsUpdater(host)
         self.assertEqual(
-            updater.specifier_part(['test-mac-mac10.10', 'test-win-win7', 'test-win-win10'], 'external/wpt/test.html'), '')
+            updater.specifier_part('external/wpt/test.html', ['test-mac-mac10.10', 'test-win-win7', 'test-win-win10']), '')
         self.assertEqual(
-            updater.specifier_part(['test-win-win7', 'test-win-win10'], 'external/wpt/test.html'), '[ Win ]')
+            updater.specifier_part('external/wpt/test.html', ['test-win-win7', 'test-win-win10']), '[ Win ]')
         self.assertEqual(
-            updater.specifier_part(['test-win-win7', 'test-win-win10'], 'external/wpt/another.html'), '[ Win ]')
+            updater.specifier_part('external/wpt/another.html', ['test-win-win7', 'test-win-win10']), '[ Win ]')
 
     def test_merge_dicts_with_conflict_raise_exception(self):
         updater = WPTExpectationsUpdater(self.mock_host())
@@ -441,11 +445,11 @@
         ]
         self.assertEqual(updater.generate_results_dict('test-mac-mac10.10', layout_test_list), {
             'external/wpt/test/name.html': {
-                'test-mac-mac10.10': {
-                    'expected': 'bar',
-                    'actual': 'foo',
-                    'bug': 'crbug.com/626703',
-                }
+                'test-mac-mac10.10': SimpleTestResult(
+                    expected='bar',
+                    actual='foo',
+                    bug='crbug.com/626703',
+                )
             }
         })
 
@@ -456,8 +460,8 @@
             expectations_path,
             MARKER_COMMENT + '\n')
         updater = WPTExpectationsUpdater(host)
-        line_list = ['crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]']
-        updater.write_to_test_expectations(line_list)
+        line_dict = {'fake/file/path.html': ['crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]']}
+        updater.write_to_test_expectations(line_dict)
         value = host.filesystem.read_text_file(expectations_path)
         self.assertMultiLineEqual(
             value,
@@ -471,8 +475,8 @@
             expectations_path,
             'crbug.com/111 [ Trusty ] foo/bar.html [ Failure ]\n')
         updater = WPTExpectationsUpdater(host)
-        line_list = ['crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]']
-        updater.write_to_test_expectations(line_list)
+        line_dict = {'fake/file/path.html': ['crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]']}
+        updater.write_to_test_expectations(line_dict)
         value = host.filesystem.read_text_file(expectations_path)
         self.assertMultiLineEqual(
             value,
@@ -487,7 +491,7 @@
             expectations_path,
             MARKER_COMMENT + '\n' + 'crbug.com/123 [ Trusty ] fake/file/path.html [ Pass ]\n')
         updater = WPTExpectationsUpdater(host)
-        updater.write_to_test_expectations([])
+        updater.write_to_test_expectations({})
         value = host.filesystem.read_text_file(expectations_path)
         self.assertMultiLineEqual(
             value,
@@ -510,9 +514,9 @@
         updater = WPTExpectationsUpdater(host)
         two = {
             'external/wpt/test/path.html': {
-                'one': {'expected': 'FAIL', 'actual': 'PASS'},
-                'two': {'expected': 'FAIL', 'actual': 'TIMEOUT'},
-                'three': {'expected': 'FAIL', 'actual': 'PASS'},
+                'one': SimpleTestResult(expected='FAIL', actual='PASS', bug='bug'),
+                'two': SimpleTestResult(expected='FAIL', actual='TIMEOUT', bug='bug'),
+                'three': SimpleTestResult(expected='FAIL', actual='PASS', bug='bug'),
             }
         }
         tests_to_rebaseline, _ = updater.get_tests_to_rebaseline(two)
@@ -525,9 +529,9 @@
         updater = WPTExpectationsUpdater(host)
         two = {
             'external/wpt/reftest.html': {
-                'one': {'expected': 'FAIL', 'actual': 'PASS', 'bug': 'crbug.com/test'},
-                'two': {'expected': 'FAIL', 'actual': 'TIMEOUT', 'bug': 'crbug.com/test'},
-                'three': {'expected': 'FAIL', 'actual': 'PASS', 'bug': 'crbug.com/test'},
+                'one': SimpleTestResult(expected='FAIL', actual='PASS', bug='crbug.com/test'),
+                'two': SimpleTestResult(expected='FAIL', actual='TIMEOUT', bug='crbug.com/test'),
+                'three': SimpleTestResult(expected='FAIL', actual='PASS', bug='crbug.com/test'),
             }
         }
         tests_to_rebaseline, _ = updater.get_tests_to_rebaseline(two)
@@ -537,8 +541,8 @@
         host = self.mock_host()
         results = {
             'external/wpt/test/path.html': {
-                'one': {'expected': 'PASS', 'actual': 'TEXT'},
-                'two': {'expected': 'PASS', 'actual': 'TIMEOUT'},
+                'one': SimpleTestResult(expected='PASS', actual='TEXT', bug='bug'),
+                'two': SimpleTestResult(expected='PASS', actual='TIMEOUT', bug='bug'),
             },
         }
         results_copy = copy.deepcopy(results)
@@ -549,7 +553,7 @@
         # since that should be covered by downloading a new baseline.
         self.assertEqual(modified_test_results, {
             'external/wpt/test/path.html': {
-                'two': {'expected': 'PASS', 'actual': 'TIMEOUT'},
+                'two': SimpleTestResult(expected='PASS', actual='TIMEOUT', bug='bug'),
             },
         })
         # The original dict isn't modified.
@@ -559,8 +563,8 @@
         host = self.mock_host()
         results = {
             'external/wpt/test/path.html': {
-                'one': {'expected': 'SLOW', 'actual': 'TEXT'},
-                'two': {'expected': 'SLOW', 'actual': 'TIMEOUT'},
+                'one': SimpleTestResult(expected='SLOW', actual='TEXT', bug='bug'),
+                'two': SimpleTestResult(expected='SLOW', actual='TIMEOUT', bug='bug'),
             },
         }
         results_copy = copy.deepcopy(results)
@@ -571,7 +575,7 @@
         # since that should be covered by downloading a new baseline.
         self.assertEqual(modified_test_results, {
             'external/wpt/test/path.html': {
-                'two': {'expected': 'SLOW', 'actual': 'TIMEOUT'},
+                'two': SimpleTestResult(expected='SLOW', actual='TIMEOUT', bug='bug'),
             },
         })
         # The original dict isn't modified.
@@ -580,14 +584,16 @@
     def test_run_no_issue_number(self):
         updater = WPTExpectationsUpdater(self.mock_host())
         updater.git_cl = MockGitCL(updater.host, issue_number='None')
-        self.assertEqual(1, updater.run(args=[]))
-        self.assertLog(['ERROR: No issue on current branch.\n'])
+        with self.assertRaises(ScriptError) as e:
+            updater.run(args=[])
+        self.assertEqual(e.exception.message, 'No issue on current branch.')
 
     def test_run_no_try_results(self):
         updater = WPTExpectationsUpdater(self.mock_host())
         updater.git_cl = MockGitCL(updater.host, {})
-        self.assertEqual(1, updater.run(args=[]))
-        self.assertLog(['ERROR: No try job information was collected.\n'])
+        with self.assertRaises(ScriptError) as e:
+            updater.run(args=[])
+        self.assertEqual(e.exception.message, 'No try job information was collected.')
 
     def test_new_manual_tests_get_skip_expectation(self):
         host = self.mock_host()
@@ -601,14 +607,15 @@
                     'test-mac-mac10.11',
                     'test-win-win7',
                     'test-win-win10',
-                ): {'expected': 'PASS', 'actual': 'MISSING', 'bug': 'crbug.com/test'}
+                ): SimpleTestResult(expected='PASS', actual='MISSING', bug='crbug.com/test')
             }
         }
         tests_to_rebaseline, _ = updater.get_tests_to_rebaseline(results)
         self.assertEqual(tests_to_rebaseline, [])
         self.assertEqual(
-            updater.create_line_list(results),
-            ['crbug.com/test external/wpt/x-manual.html [ Skip ]'])
+            updater.create_line_dict(results),
+            {'external/wpt/x-manual.html': ['crbug.com/test external/wpt/x-manual.html [ Skip ]']}
+        )
 
     def test_one_platform_has_no_results(self):
         # In this example, there is a failure that has been observed on
@@ -623,10 +630,11 @@
                     'test-linux-precise',
                     'test-linux-trusty',
                     'test-mac-mac10.11',
-                ): {'expected': 'PASS', 'actual': 'TEXT', 'bug': 'crbug.com/test'}
+                ): SimpleTestResult(expected='PASS', actual='TEXT', bug='crbug.com/test')
             }
         }
         updater.ports_with_no_results = {'test-mac-mac10.10'}
         self.assertEqual(
-            updater.create_line_list(results),
-            ['crbug.com/test [ Linux Mac ] external/wpt/x.html [ Failure ]'])
+            updater.create_line_dict(results),
+            {'external/wpt/x.html': ['crbug.com/test [ Linux Mac ] external/wpt/x.html [ Failure ]']}
+        )
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index 660acd8..437e1f9 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -245,7 +245,6 @@
     "platform/WebLoadingBehaviorFlag.h",
     "platform/WebLocalizedString.h",
     "platform/WebMediaConstraints.h",
-    "platform/WebMediaDeviceInfo.h",
     "platform/WebMediaKeySystemConfiguration.h",
     "platform/WebMediaKeySystemMediaCapability.h",
     "platform/WebMediaPlayer.h",
@@ -535,7 +534,6 @@
     "web/WebLocalFrame.h",
     "web/WebMeaningfulLayout.h",
     "web/WebMediaDeviceChangeObserver.h",
-    "web/WebMediaDevicesRequest.h",
     "web/WebMediaPlayerAction.h",
     "web/WebMediaStreamRegistry.h",
     "web/WebMemoryStatistics.h",
@@ -782,6 +780,7 @@
     "platform/modules/hyphenation/hyphenation.mojom",
     "platform/modules/insecure_input/insecure_input_service.mojom",
     "platform/modules/keyboard_lock/keyboard_lock.mojom",
+    "platform/modules/locks/lock_manager.mojom",
     "platform/modules/manifest/manifest.mojom",
     "platform/modules/manifest/manifest_manager.mojom",
     "platform/modules/notifications/notification.mojom",
diff --git a/third_party/WebKit/public/platform/InterfaceRegistry.h b/third_party/WebKit/public/platform/InterfaceRegistry.h
index c041e2c..bbed26f3 100644
--- a/third_party/WebKit/public/platform/InterfaceRegistry.h
+++ b/third_party/WebKit/public/platform/InterfaceRegistry.h
@@ -44,7 +44,8 @@
 #if INSIDE_BLINK
   template <typename Interface>
   void AddInterface(
-      WTF::RepeatingFunction<void(mojo::InterfaceRequest<Interface>)> factory) {
+      base::RepeatingCallback<void(mojo::InterfaceRequest<Interface>)>
+          factory) {
     AddInterface(Interface::Name_,
                  WTF::BindRepeating(
                      &InterfaceRegistry::ForwardToInterfaceFactory<Interface>,
@@ -65,7 +66,7 @@
 
   template <typename Interface>
   void AddAssociatedInterface(
-      WTF::RepeatingFunction<void(mojo::AssociatedInterfaceRequest<Interface>)>
+      base::RepeatingCallback<void(mojo::AssociatedInterfaceRequest<Interface>)>
           factory) {
     AddAssociatedInterface(
         Interface::Name_,
@@ -77,8 +78,7 @@
  private:
   template <typename Interface>
   static void ForwardToInterfaceFactory(
-      const WTF::RepeatingFunction<void(mojo::InterfaceRequest<Interface>)>&
-          factory,
+      base::RepeatingCallback<void(mojo::InterfaceRequest<Interface>)> factory,
       mojo::ScopedMessagePipeHandle handle) {
     factory.Run(mojo::InterfaceRequest<Interface>(std::move(handle)));
   }
@@ -93,8 +93,8 @@
 
   template <typename Interface>
   static void ForwardToAssociatedInterfaceFactory(
-      const WTF::RepeatingFunction<
-          void(mojo::AssociatedInterfaceRequest<Interface>)>& factory,
+      base::RepeatingCallback<void(mojo::AssociatedInterfaceRequest<Interface>)>
+          factory,
       mojo::ScopedInterfaceEndpointHandle handle) {
     factory.Run(mojo::AssociatedInterfaceRequest<Interface>(std::move(handle)));
   }
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index 17c9687..66f01b6 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -576,7 +576,8 @@
   // May return null if WebRTC functionality is not avaliable or if it's out of
   // resources.
   virtual std::unique_ptr<WebRTCPeerConnectionHandler>
-  CreateRTCPeerConnectionHandler(WebRTCPeerConnectionHandlerClient*);
+  CreateRTCPeerConnectionHandler(WebRTCPeerConnectionHandlerClient*,
+                                 scoped_refptr<base::SingleThreadTaskRunner>);
 
   // Creates a WebMediaRecorderHandler to record MediaStreams.
   // May return null if the functionality is not available or out of resources.
diff --git a/third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h b/third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h
index 277c01c..645f5fb 100644
--- a/third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h
+++ b/third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h
@@ -49,7 +49,8 @@
     enum class MessageType {
       kLicenseRequest,
       kLicenseRenewal,
-      kLicenseRelease
+      kLicenseRelease,
+      kIndividualizationRequest
     };
 
     virtual void Message(MessageType,
diff --git a/third_party/WebKit/public/platform/WebInputEvent.h b/third_party/WebKit/public/platform/WebInputEvent.h
index 0335e45..9853653 100644
--- a/third_party/WebKit/public/platform/WebInputEvent.h
+++ b/third_party/WebKit/public/platform/WebInputEvent.h
@@ -177,6 +177,8 @@
     kTouchMove,
     kTouchEnd,
     kTouchCancel,
+    // TODO(nzolghadr): This event should be replaced with
+    // kPointerCausedUaAction
     kTouchScrollStarted,
     kTouchTypeLast = kTouchScrollStarted,
 
@@ -186,7 +188,8 @@
     kPointerUp,
     kPointerMove,
     kPointerCancel,
-    kPointerTypeLast = kPointerCancel,
+    kPointerCausedUaAction,
+    kPointerTypeLast = kPointerCausedUaAction,
 
     kTypeLast = kTouchTypeLast
   };
@@ -246,6 +249,11 @@
     // not actual physical movement of the pointer
     kRelativeMotionEvent = 1 << 22,
 
+    // Indication this event was injected by the devtools.
+    // TODO(dtapuska): Remove this flag once we are able to bind callbacks
+    // in event sending.
+    kFromDebugger = 1 << 23,
+
     // The set of non-stateful modifiers that specifically change the
     // interpretation of the key being pressed. For example; IsLeft,
     // IsRight, IsComposing don't change the meaning of the key
@@ -380,6 +388,7 @@
       CASE_TYPE(PointerUp);
       CASE_TYPE(PointerMove);
       CASE_TYPE(PointerCancel);
+      CASE_TYPE(PointerCausedUaAction);
     }
 #undef CASE_TYPE
     NOTREACHED();
diff --git a/third_party/WebKit/public/platform/WebMediaDeviceInfo.h b/third_party/WebKit/public/platform/WebMediaDeviceInfo.h
deleted file mode 100644
index 7ac9a56..0000000
--- a/third_party/WebKit/public/platform/WebMediaDeviceInfo.h
+++ /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. ``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
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebMediaDeviceInfo_h
-#define WebMediaDeviceInfo_h
-
-#include "WebCommon.h"
-#include "WebPrivatePtr.h"
-#include "WebString.h"
-
-namespace blink {
-
-class WebMediaDeviceInfoPrivate;
-
-class WebMediaDeviceInfo {
- public:
-  enum MediaDeviceKind {
-    kMediaDeviceKindAudioInput,
-    kMediaDeviceKindAudioOutput,
-    kMediaDeviceKindVideoInput
-  };
-
-  WebMediaDeviceInfo() {}
-  WebMediaDeviceInfo(const WebMediaDeviceInfo& other) { Assign(other); }
-  ~WebMediaDeviceInfo() { Reset(); }
-
-  WebMediaDeviceInfo& operator=(const WebMediaDeviceInfo& other) {
-    Assign(other);
-    return *this;
-  }
-
-  BLINK_PLATFORM_EXPORT void Assign(const WebMediaDeviceInfo&);
-
-  BLINK_PLATFORM_EXPORT void Initialize(const WebString& device_id,
-                                        MediaDeviceKind,
-                                        const WebString& label,
-                                        const WebString& group_id);
-  BLINK_PLATFORM_EXPORT void Reset();
-  bool IsNull() const { return private_.IsNull(); }
-
-  BLINK_PLATFORM_EXPORT WebString DeviceId() const;
-  BLINK_PLATFORM_EXPORT MediaDeviceKind Kind() const;
-  BLINK_PLATFORM_EXPORT WebString Label() const;
-  BLINK_PLATFORM_EXPORT WebString GroupId() const;
-
- private:
-  WebPrivatePtr<WebMediaDeviceInfoPrivate> private_;
-};
-
-}  // namespace blink
-
-#endif  // WebMediaDeviceInfo_h
diff --git a/third_party/WebKit/public/platform/WebPointerEvent.h b/third_party/WebKit/public/platform/WebPointerEvent.h
index 9814f9f..3257701 100644
--- a/third_party/WebKit/public/platform/WebPointerEvent.h
+++ b/third_party/WebKit/public/platform/WebPointerEvent.h
@@ -29,11 +29,9 @@
                                         const WebTouchPoint&);
   BLINK_PLATFORM_EXPORT WebPointerEvent(WebInputEvent::Type,
                                         const WebMouseEvent&);
-
-  // TODO(crbug.com/736014): We need a clarified definition of the scale and
-  // the coordinate space on these attributes.
-  float width;
-  float height;
+  // Creates a PointerCausedUaAction pointer event.
+  BLINK_PLATFORM_EXPORT WebPointerEvent(WebPointerProperties::PointerType,
+                                        double time_stamp_seconds);
 
   // ------------ Touch Point Specific ------------
 
@@ -41,6 +39,10 @@
 
   // ------------ Touch Event Specific ------------
 
+  // A unique identifier for the touch event. Valid ids start at one and
+  // increase monotonically. Zero means an unknown id.
+  uint32_t unique_touch_event_id;
+
   // Whether the event is blocking, non-blocking, all event
   // listeners were passive or was forced to be non-blocking.
   DispatchType dispatch_type;
@@ -54,9 +56,16 @@
   // scroll.
   bool touch_start_or_first_touch_move;
 
-  // A unique identifier for the touch event. Valid ids start at one and
-  // increase monotonically. Zero means an unknown id.
-  uint32_t unique_touch_event_id;
+  // ------------ Common fields across pointer types ------------
+
+  // True if this pointer was processed as part of gesture detection and it may
+  // cause scrolling.
+  bool scroll_capable;
+
+  // TODO(crbug.com/736014): We need a clarified definition of the scale and
+  // the coordinate space on these attributes.
+  float width;
+  float height;
 
 #if INSIDE_BLINK
   bool IsCancelable() const { return dispatch_type == kBlocking; }
diff --git a/third_party/WebKit/public/platform/WebThread.h b/third_party/WebKit/public/platform/WebThread.h
index e077107..9230455 100644
--- a/third_party/WebKit/public/platform/WebThread.h
+++ b/third_party/WebKit/public/platform/WebThread.h
@@ -26,6 +26,7 @@
 #define WebThread_h
 
 #include "WebCommon.h"
+#include "base/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
 
 #include <stdint.h>
@@ -53,11 +54,7 @@
  public:
   // An IdleTask is passed a deadline in CLOCK_MONOTONIC seconds and is
   // expected to complete before this deadline.
-  class IdleTask {
-   public:
-    virtual ~IdleTask() {}
-    virtual void Run(double deadline_seconds) = 0;
-  };
+  using IdleTask = base::OnceCallback<void(double deadline_seconds)>;
 
   class BLINK_PLATFORM_EXPORT TaskObserver {
    public:
diff --git a/third_party/WebKit/public/platform/modules/locks/OWNERS b/third_party/WebKit/public/platform/modules/locks/OWNERS
new file mode 100644
index 0000000..e26183dc
--- /dev/null
+++ b/third_party/WebKit/public/platform/modules/locks/OWNERS
@@ -0,0 +1,4 @@
+file://content/browser/locks/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/WebKit/public/platform/modules/locks/lock_manager.mojom b/third_party/WebKit/public/platform/modules/locks/lock_manager.mojom
new file mode 100644
index 0000000..d65262c2
--- /dev/null
+++ b/third_party/WebKit/public/platform/modules/locks/lock_manager.mojom
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module blink.mojom;
+
+import "url/mojo/origin.mojom";
+
+// An opaque handle passed from the browser process to a child process to reflect a
+// held lock. The lock is released when the handle is dropped.
+interface LockHandle {};
+
+interface LockRequest {
+  // Request was granted.
+  Granted(LockHandle lock_handle);
+
+  // Request failed; e.g. request was only "if available" and it was not.
+  Failed();
+
+  // TODO(jsbell): Abort() is not yet used.
+  Abort(string reason);
+};
+
+interface LockManager {
+  enum LockMode {
+    SHARED,
+    EXCLUSIVE
+  };
+
+  enum WaitMode {
+    WAIT,
+    NO_WAIT
+  };
+
+  RequestLock(url.mojom.Origin origin, array<string> scope, LockMode mode, WaitMode wait, LockRequest request);
+};
diff --git a/third_party/WebKit/public/platform/modules/notifications/notification_service.mojom b/third_party/WebKit/public/platform/modules/notifications/notification_service.mojom
index 556d315..e3374c9 100644
--- a/third_party/WebKit/public/platform/modules/notifications/notification_service.mojom
+++ b/third_party/WebKit/public/platform/modules/notifications/notification_service.mojom
@@ -4,6 +4,7 @@
 
 module blink.mojom;
 
+import "mojo/common/string16.mojom";
 import "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom";
 
 // Service through which Blink can request notifications to be shown, closed or
@@ -13,4 +14,8 @@
   // with the interface connection. Required to be synchronous due to the
   // Notification.permission JavaScript getter.
   [Sync] GetPermissionStatus() => (PermissionStatus status);
+
+  // Shows a notification that is not associated with a service worker.
+  // TODO(crbug.com/595685): Pass the rest of the notification data through.
+  DisplayNonPersistentNotification(mojo.common.mojom.String16 title);
 };
diff --git a/third_party/WebKit/public/platform/scheduler/child/single_thread_idle_task_runner.h b/third_party/WebKit/public/platform/scheduler/child/single_thread_idle_task_runner.h
index 3a4b000..9b239cfc 100644
--- a/third_party/WebKit/public/platform/scheduler/child/single_thread_idle_task_runner.h
+++ b/third_party/WebKit/public/platform/scheduler/child/single_thread_idle_task_runner.h
@@ -34,7 +34,7 @@
 class SingleThreadIdleTaskRunner
     : public base::RefCountedThreadSafe<SingleThreadIdleTaskRunner> {
  public:
-  typedef base::Callback<void(base::TimeTicks)> IdleTask;
+  using IdleTask = base::OnceCallback<void(base::TimeTicks)>;
 
   // Used to request idle task deadlines and signal posting of idle tasks.
   class BLINK_PLATFORM_EXPORT Delegate {
@@ -68,17 +68,17 @@
       Delegate* delegate);
 
   virtual void PostIdleTask(const base::Location& from_here,
-                            const IdleTask& idle_task);
+                            IdleTask idle_task);
 
   // |idle_task| is eligible to run after the next time an idle period starts
   // after |delay|.  Note this has after wake-up semantics, i.e. unless
   // something else wakes the CPU up, this won't run.
   virtual void PostDelayedIdleTask(const base::Location& from_here,
                                    const base::TimeDelta delay,
-                                   const IdleTask& idle_task);
+                                   IdleTask idle_task);
 
   virtual void PostNonNestableIdleTask(const base::Location& from_here,
-                                       const IdleTask& idle_task);
+                                       IdleTask idle_task);
 
   bool RunsTasksInCurrentSequence() const;
 
@@ -95,7 +95,7 @@
 
   void EnqueueReadyDelayedIdleTasks();
 
-  using DelayedIdleTask = std::pair<const base::Location, base::Closure>;
+  using DelayedIdleTask = std::pair<const base::Location, base::OnceClosure>;
 
   scoped_refptr<base::SingleThreadTaskRunner> idle_priority_task_runner_;
   std::multimap<base::TimeTicks, DelayedIdleTask> delayed_idle_tasks_;
diff --git a/third_party/WebKit/public/platform/scheduler/child/webthread_base.h b/third_party/WebKit/public/platform/scheduler/child/webthread_base.h
index 1ef152a..1253b746 100644
--- a/third_party/WebKit/public/platform/scheduler/child/webthread_base.h
+++ b/third_party/WebKit/public/platform/scheduler/child/webthread_base.h
@@ -38,7 +38,7 @@
   PlatformThreadId ThreadId() const override = 0;
 
   virtual void PostIdleTask(const WebTraceLocation& location,
-                            IdleTask* idle_task);
+                            IdleTask idle_task);
 
   void AddTaskObserver(TaskObserver* observer) override;
   void RemoveTaskObserver(TaskObserver* observer) override;
@@ -69,9 +69,8 @@
   virtual void AddTaskTimeObserverInternal(TaskTimeObserver*) {}
   virtual void RemoveTaskTimeObserverInternal(TaskTimeObserver*) {}
 
-  static void RunWebThreadIdleTask(
-      std::unique_ptr<WebThread::IdleTask> idle_task,
-      base::TimeTicks deadline);
+  static void RunWebThreadIdleTask(WebThread::IdleTask idle_task,
+                                   base::TimeTicks deadline);
 
  private:
   typedef std::map<TaskObserver*, TaskObserverAdapter*> TaskObserverMap;
diff --git a/third_party/WebKit/public/web/WebMediaDevicesRequest.h b/third_party/WebKit/public/web/WebMediaDevicesRequest.h
deleted file mode 100644
index 83e2783..0000000
--- a/third_party/WebKit/public/web/WebMediaDevicesRequest.h
+++ /dev/null
@@ -1,81 +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. ``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
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebMediaDevicesRequest_h
-#define WebMediaDevicesRequest_h
-
-#include "public/platform/WebCommon.h"
-#include "public/platform/WebPrivatePtr.h"
-#include "public/platform/WebSecurityOrigin.h"
-#include "public/platform/WebString.h"
-
-namespace blink {
-
-class MediaDevicesRequest;
-class WebDocument;
-class WebMediaDeviceInfo;
-template <typename T>
-class WebVector;
-
-class WebMediaDevicesRequest {
- public:
-  WebMediaDevicesRequest() {}
-  WebMediaDevicesRequest(const WebMediaDevicesRequest& request) {
-    Assign(request);
-  }
-  ~WebMediaDevicesRequest() { Reset(); }
-
-  WebMediaDevicesRequest& operator=(const WebMediaDevicesRequest& other) {
-    Assign(other);
-    return *this;
-  }
-
-  BLINK_EXPORT void Reset();
-  bool IsNull() const { return private_.IsNull(); }
-  BLINK_EXPORT bool Equals(const WebMediaDevicesRequest&) const;
-  BLINK_EXPORT void Assign(const WebMediaDevicesRequest&);
-
-  BLINK_EXPORT WebSecurityOrigin GetSecurityOrigin() const;
-  BLINK_EXPORT WebDocument OwnerDocument() const;
-
-  BLINK_EXPORT void RequestSucceeded(WebVector<WebMediaDeviceInfo>);
-
-#if INSIDE_BLINK
-  WebMediaDevicesRequest(MediaDevicesRequest*);
-  operator MediaDevicesRequest*() const;
-#endif
-
- private:
-  WebPrivatePtr<MediaDevicesRequest> private_;
-};
-
-inline bool operator==(const WebMediaDevicesRequest& a,
-                       const WebMediaDevicesRequest& b) {
-  return a.Equals(b);
-}
-
-}  // namespace blink
-
-#endif  // WebMediaDevicesRequest_h
diff --git a/third_party/WebKit/public/web/WebUserMediaClient.h b/third_party/WebKit/public/web/WebUserMediaClient.h
index aa220f9..2dfeea4 100644
--- a/third_party/WebKit/public/web/WebUserMediaClient.h
+++ b/third_party/WebKit/public/web/WebUserMediaClient.h
@@ -34,7 +34,6 @@
 namespace blink {
 
 class WebApplyConstraintsRequest;
-class WebMediaDevicesRequest;
 class WebMediaStreamTrack;
 class WebUserMediaRequest;
 class WebMediaDeviceChangeObserver;
@@ -45,7 +44,6 @@
 
   virtual void RequestUserMedia(const WebUserMediaRequest&) = 0;
   virtual void CancelUserMediaRequest(const WebUserMediaRequest&) = 0;
-  virtual void RequestMediaDevices(const WebMediaDevicesRequest&) = 0;
   virtual void SetMediaDeviceChangeObserver(
       const WebMediaDeviceChangeObserver&) = 0;
   virtual void ApplyConstraints(const WebApplyConstraintsRequest&) = 0;
diff --git a/third_party/blanketjs/OWNERS b/third_party/blanketjs/OWNERS
index ffaee23..1eac0a3 100644
--- a/third_party/blanketjs/OWNERS
+++ b/third_party/blanketjs/OWNERS
@@ -1,2 +1 @@
-kelvinp@chromium.org
 jamiewalch@chromium.org
diff --git a/third_party/boringssl/crypto_test_data.cc b/third_party/boringssl/crypto_test_data.cc
index f529221..75c355c 100644
--- a/third_party/boringssl/crypto_test_data.cc
+++ b/third_party/boringssl/crypto_test_data.cc
@@ -2558,10 +2558,11 @@
     "917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 0\nA = 0\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 86fb0b8dc161c41de2adb0f3ddcc8ad49c1efd729a52793a3ac987d4011c9c1dadb18657dca718df75c8ddcc49d60f152c46ab85ae9076ee7bfd405679a7da3a5195a1bbfd7d2b998c7b135ea91f8c445cbafe1276fa502c2a85477716829a2e0d24ba02623405a3654bed8f355bc7ccdb67c3f9a01e249e358b60d7699498a9\nA = 816610e6018ca47074d55750dd16a281019dbf95dc752605794cbb8ea8d75775317ce685737859728320b529fb3b4414b40bf3a93d08d8994a21ae54682cc1c357eb529837a7b0129a0843eebd9341c9bee3a8ae30475bdbff517e885a0c9f2b6a680643bd981efb53bf9dd49f3dc3cb757e117895fb34b1b4336d9bf8384558\nE = 8622c37631e428402343dccf8ed09d47b3f4201e95058910289a62707c3ce0b7113c390056cc4796cc9893e471b12cb3f63f900f3356ffd25c8b2fed6f6a7fba2c684eb241ca706c76cecbf72473d8a58c02338e40714b5610465cc319f0a529a7aa3898d9e638b247abd1380c6e8f7fa210c9f1a1a2164db6db83a6bba79436\nM = fda6f9d8588e3614f5a68ce867a5619f6ddbb8d64450ff402e1c4f1a08b518f79dca21e5983c207c5b7324c16895a1e9f1282fc6cf60b0645f6b02b652ed5b129e67c939e854ab492dec30ea878c3edde10a4b7d1d14c57100c6cbcc5fc085a0d7308715ed132fb917251919c727487fedb66500d5610b0014a43419acfbb92f\n\nModExp = 1\nA = 9edfce4691f46eadaa2043c7b1092b831ed50f3429f0bca02f985c0b77c686d951be84d772ae4b55f08935bed6e3206c8441574f215736b5c1c1b7595b3b789b55cf56db83741b10144d6767ba2b97b23a5e83504c60e06ab22834b0145655aa0463108317a379cbfc8a93de8a66925a999b8b02bf88dd85fb9898cefe9c95c8\nE = 0\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 0\nA = 0\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 442866609915aa6f1bae9dfb59e721e1b63f42c0f75fbf0a88344120fbbd7aacf15208fb7c9d8bb8477d553cbd826d7e685ad764a8423e81c2131c040ee83a03cab8d5ce50866a941b48c78e9f1330794d908562d4141cfbf26e8c80c69551339eec41e37e2b37b54330f7bd75748f8d26d56ab9eb3b0c127540484c6445a7fa\nA = 8ff65e2cbcbcd8697cc3ce9a26855d6422ac7eb4e66500648c08be697e005cc3c854a54cfab91d43489cd60be8b516a9b3c9688e5e009a1689c6b164a133859a5464ef422c86344fef42cc477c9df27768377c126a066d1b62f593b7f6d6e906feaee16addb7cfbfc043d741b7dc81a87c17f167b7b8ef1b1fb3dfd1eb14102d\nE = a3be10ef04535fca6784e5dbf3733d677dedd50fabbc3a860496628950b4747a328c2ce0d903cbe1e700f0af30f59fb917202257815097a2b516df5d0a82642faeffdfc3b7883766c78fc4be5901ebef891a9ca27f3bcf00960729e659bb3fddd54a19ce628e95ab86e4c7a168588bc9f67b05dd21a583acd8dc36e615945648\nM = dcb68f6aa530ae9b31d078e2e82670adcc98228e7cf1aa59f81e66426ef14b1591b833d889463564c75b5fd5551ea295a0da581dd80f62c7008ff0f26a1c9f4f756431d48198af157149be8698336b306b0a8b8635d3fc2c4c2194ecc4d2af31ca1892917cc2e621d702eaaeed0d9a0c3dca575451eb8bc5487e313988cae745\n\nModExp = 1\nA = fe9f77f7d0475e00ec964c0effb9b8e079c32e376ce77a9c40ce4018c3df44a77b4f294d9565502b2b79accb30cb58dda6d15e1543b6d4a53296543ed11c7f51baab60283ef03fae37dfeacb431392487ec2839551a933895c4dbf18844f7b375d3e6f558d3c39993cea1bbf7fb743a6a07bd3753c03eb7298811476d7f3ff1d\nE = 0\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 0\nA = 0\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\nModExp = 91fd879d02f95a9f40fcd1037726f73892caf84e9b43b4aa4126d9062a0d22c464e7af2fbd91aa849612d99d9519b724a7fb1cb018fffdcff321d883ab2519953c9f174f09dd8f13ac87339887385966eb4a94842276637b2c36c0a5036b1d3bbea438bc6efd4b4851c7ec06879d60694df894717569bcd31c4b13d80df6cbca\nA = cdec5edc1cb3ea974342b85aabc0f9385cf877ca328747d40dd4d297623ad69ab6582653faeed5aef225208305135cfbee32e066cb43e18afacea3a32acc8aabbc49617ac33e741651924ae56dd6aa044a12a1ea50fef573b5befb2f4b21b9cf83ab2aaa6fd153580a0761666ade8fb94f202a3c3dc4f33297eabb4564374168\nE = a0bc148ed50a9b54036bb8fa1f214979052ebd47db8b347af3bb03b806bb457b468ba34781f8a25f289a7a90af4903dc14809a166df2f4c3527de2ea6911cb1afb9071a4afbb522a7d50634d66fd584c73f32d05217dc9f7f16394c68a692a953492ca85f89cc11da95fd8cac6231647923ced48a1b3b0ee68c010286d452836\nM = e7a96cf6fa930f73c8bdc2726bbba246001a9d27f39cc2b978c99dc6f15af0e8aaf26b565302f1112e607e2df4066948baba931b89cd9bbdea2072e05b9a4968fdf282c43d997987c3a3a0434e925a679ac81f316b7a7b724b79be3d6888b66f4512759bf66cfaaa88b9513dd27a44aaea75437268a014c4eb50ba2e50093511\n\n# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in\n# order to test the const time precomputation scattering/gathering.\n\nModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b\nA = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898\nE = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f\nM = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d\n\nModExp = a7f5844fa9e7202d4b70ee252c9846e63d3d091b0387768ded872cec53458e19df0d9b4960226e269b8ca5dd4c4eda423a67b6dbb48235c08c12c6c7c78db47287756d3ed9cecb9232f7d18d5d80b9676cb68ba4a290c97e220beb1a069976b5e6022a4c1e5ddbeec86b62dda24ffea1deda37695c9f61a8817218e6370c0679\nA = 7d6d0cc947ceb949cdc4e9e1044f5deca5bb05a491041e0d85bc4b92a0944a57c72845fad91e59010c61ad1712bd2f612d53a846a044632262a9f2e3373b062fde2484e0c165ff947f2469f743ab6e2e5e13c640fc4029b1c9213eb8473c674e7f9e95a4a5c5636d4656c1e696962340d77b322daba47d6fc894f2a2cd9e0afc\nE = b78012afe806e2344d004c739c97324256850980ac97d88c4ed9a838517639ca112e235978d21a176c33f5a68703aba0f2a05501bbe3fc8d49a000fbf530cdb431581dfaf8683cb15a2aee5e239cbc542827100da3b47babf4a16ca7c588aff9912e674abb449e0b767a15e415f4e7f2bbd6380d7131da3df8d49b13bfd35ce3\nM = b72d5c55bd2998472f1965e75a51be6155c1ba04656da8f66bcb34db36a7b1db66a89d1d05b1bde10206acf85be7b474ab689220faf1bb52ab39d8dc00512dd4e26df1179c11b973e1274db85a88c7cc2a17113abdffe58cb930ddc5f3ccc4d68b4e65c913730509f7ce5656e8bbaba9b1be177ab9f766678f018fea05da9cdf\n\nModExp = 465ff295786a88496828fdc763e9292d557",
     "957544e9322b7996807b87fdbfa7a11614bffeec557ca831c4824c8e4ca3b1a1c7f3f4f95ec3fd6a86b73bb13d78b73af2b3c7e76954d0cc03bcb0cd606867ebb3765a8b3d0108cbe4f343a14016be9c33f6d200f0dc547e7d6b02bfab1e79dcdf9c9835a814cc6c855a12ebeb66d\nA = 89ad02bea3e9ab839a6e23f20122409daba52c68e1e893034b30d321c0305434a6af940015e3fa5ca9c35230da34beeb1ed4fbce6c1da3a8bfe3f3ae172276c1d1723b47ee61e6f8fcfdafad102d6f7ee2a79f510c7edb93096205a40a6c9e665b88b18f39a979e2e61286d939952a6f02fe8148b7515bb25f4252337cb6e60d\nE = cbd6ac628cc7afa3c61bee9c22a06a395087ec1811fe9681b55216700c435996c815e7cec8aaa90016dd2382d0306a5414630124e14f3d396a4ba02ee17851bf720f1607ff813e4bbddf01338983db12f59bd6371a738eee3eeb716f21051d6174d2d6c77602942b9edaac18d4b3a723096c0d00dd23a8a605c585022f311560\nM = fa7a3e40364c8a8d0f14f0213a3f3e035222ca0ea19d46d10ba41580e5dd2805c8a133f3856d7d5d97f922ea540e5eb0d10ad04dfdbb74f518f58da0099a6fc2b3f3def92985176e07fc78aff2faebccca10a429794e5f15ff92f75fe90f527c60ddea8093a9078c703c372ca09f7aeb27ade02f3595308c61dd9c44e62fd101\n\nModExp = cf08bf00261402102e9fe03f3074471dcf0e9b3c96d4d1503f099f24ec85e1901b023e9e048c1ad042244f5f70b38b25a99f4c0a7b57d5844bb0d0137367f45f4ce2cc7746105b77414768cb97648dc5721149aed2d4c682408cc0d50d26dd0bd77e848911f8625c727cac5f32e63bcb548f41a57d718d772f23983a42f603bd\nA = a419646a6631c2c69b18f7aa65011825eb31692eecaee9d74f92d92203811b68e9764bda31a1585bdf69b6273fc6f9f508c395ac081336506525dad88473512f08a205621ac8b16e9864c7a7c5a4f17435de00d0b32badec6ce4897e3e1076c562b6d9523f63d0b2079eaa416cb090471657763f24931d955d1fa2720c80a9c9\nE = d5a6f4a1842aaee39805356dc8d0d678ee03b2c81277345beccb2742f899132feb43271f95968a01ae68aa8277201851992dc0aa7a71c90aae71b124d873ee264ea400fb131be0fc6c4ce8c04c45f6bdaca89ac743635caf6158983d257e21cef6800d7f990e912ba21bbfb8fb779afa4abd19e07e7e07eee9908493d1ca502c\nM = e739689b6cc6def1d45fb1a2ab551643beeb303f4aaa4da47ee5e4948510f8445b4c40e99ae8354dede60b2ba6694e93bc4d573b7e8adf871b7a9a9636eb7d70f2e49328e2d7978143b177cee8374ef01bd1ee2d95862765883f5e7971668b53ef0ff41b6539faf63c397522b0bdce916388e72e26c8d3d2e58dadeb9eb5d479\n\nModExp = 827e6312ec3b14600203bb83f5b277ded197b2967363630ef673240df05edd3ba8ab2b11c86251a612206569c6c33952b31e264f129909bfe723bd0ee1624b36cfcfaa893a6ec8b5a1f7de79f83e79b459a3350f89f412ad1cfd6bc4c2a7a29272c783d6ecceeb1398fa17041835643f4debef9b5e87b098d104bb8912dddf7c\nA = b8e49c637829021d32db3a39a0c1e58cdd4c6e4eda7e8e9293be379e9c2e2d184f929d278598a81ae231cfedcf69cce4a6e31cda3c8ac14d753a7311f2436e29795f0dfb60259a0f61a997918ff984aa2284b43a9d64c974059e9682adfffd018305835f74eda8c75fe4877d811c1620f654ec9f7f32d1af5ce59115e2f41785\nE = 80e0febf369d234bf1aaad4f82df2e2ff02882c3184781f6ccdf4f7cd93b6887af86830077c84dfb02109ada05b40970b1c65228b0c19030bd6361c3537fee22a8155c03b4e7007ca006c6daa3659518d05bb81ea0079456d0ef6116df248dffdb0c935f321f5a1034deefd5a9414a0652aa6548de33325b474b9e5a8507a082\nM = d5eb1d14af842a9973274f7463d90cf0ccff19c47d710edbae184478d4f29b02693ed7958bd487054327b9e6d8879e24c9af7730b92f323eeac05558da6c1b952e5dbf13de236050a77628bb5325fe0d14cc5773bf73338759d5ab43c212b414581280f1cee250007e53791b800b61c90de0328acd7bc43fbdda48158939392d\n\nModExp = 4a1efd29c7e78549f5cd4deed1454b37462c7810ee6a8a2493b764dfa479be13b314cf9ff98259517d61865567ef499a511630c0038c97914625df181c6fe07892f329f98b344a78d751e9471483eebaa7977371bf97bb25187ae7e93a9227d6c124ccb4644423c961a11ae59c4354f89d5a95164c23d9aa256e289e9cc0858e\nA = bd86c9211fa6a47a06e5016c46cb8a99e34a043a29e22f8c3196fa7197c26b38927b8d9bc0ddc11a5fa4bcc44deb69dbf37cbe7ebc9a2fad6c74e09ab5a9dd929fa04ab4319b6caad1035739be78ba631fb0748d9e53944836d37ccda6e6a62823c696d8f31139ccd7f2f86b22fa026ecf433cfb1271a3539ac4f1c83aaac059\nE = c40b9972006d28a84c2769a86e526a2b274f73afc7c5c6a2742166757f61b5f5fdbb228afa157af62af989ffe966f232bba9e6beef5403d1690ade31a6410f7f349a35bc4267a129afd647993df7d45cc0e1a1ba4678d7f1b6e8a344d8ff7037679e1f4db25a454e4246f6b55c416567fcfa188e8a3865115851d9edf0aa8902\nM = cf424d7af75ce7eef90cad75ae55ca8810cc7b4703fdb5bce701e7bac07e0c371cae06df2aa8facb55a0faa6793e4d2bd9d7969703743b9be170be82792aeea55e2bc0f7ab7617b276486bf474dee2f4556aab595ff3ef115139cfe5e21ccd4ee05c0e1cf901bd85df86cc17195a783b0be836d00bee82ce064077f9191188f9\n\nModExp = 3137a3049fd4ad2e26d870f5c998cf11bfe82101884a82e85e43facd0928cd7434a2e346ca124619769fa141bbe92ad6f36b99231032ddaec3b349a410f82b5ca36f45e56e5fb85dc63d32053dc90805d3f1854ab385281a71a57726bf97158494e7476057214ca7379ab8b70f5bdc15f70bdad3adf33c3a1f9cd1b6bbbad556\nA = 39a1dc6a4c3f14d9c350ee968d5ce139ef725952c967a2d1bedf48ace22091283525be03807e2e263d2640be77f0525247bcd07149bba50568cec5a082c87d72962cf9e43bcb5cdb1e7e9a650fb53e0ec2fad37f09a9f036c0d7dfa528fef846769f80a9a60854910ca1b4ee05dba82ed2ee018348d6b3e52a764b8ffae61e0\nE = deaee3a3f80c9f684ed7110c0653847ccc7be5ff6d982fd4b49f59b5dd35f7210b1077babbcedbc127df35cd469dc6e569a0f84e58149b5605c94b09fd7f0b098d02b4a04631328b3fae39e6c2fce25334225cab71829abdb9507cb903701559660f2c08c3b743336119d1260a0db27054cad3f28bc1b04b2289baa58fb33965\nM = 938388927d06ed3bb1286c0f06d3054cb0ee16dc7a0bbbf13a45293c09a5f40f1d611b2e1a1b0ec2ef109b508e27af4274954905cae52034f8740a744153b4d22059f0dd262ea51785522098ecacced6da07709ee6b5acc8c4e99331379a7c3de7f4e2d1431e43b19570140955b7bcba118dfbaa552cbfa2be531e8f781166ed\n\nModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510\nA = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83\nE = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693\nM = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11\n\nModExp = 75c3f79ab7c991b98e65505342a8a563cfb08b5d3ccf8664c7db1de50256b1d17ebf7096dc98c7bb5d7f027a894ae5cbb14dee04d5d445e775ad7e239acc82673b0ac2d819a69c83864f34e73d9a636f05de8279619a067b4c90ad038db5910447e03841d2034635018f08cbcd21efa00994247763a249082594128112f95232\nA = 34def7d76f6f158a359fd12759fb889cdf6af0a24830dc3e84283a1ab4e9b2647a6a36b86482f829b2cdf3e3d6028f9a884b1f64f7262315446bea8b0231828e2f3d990fb103c17f820b39e4b8427c85643ceeca8f5dc8f191d1255768300e859bd7d88c770319ef38269660d221cb3bc061389b6fc0783485ef042b1c7d6fef\nE = c6c46453dd5aac6b37277a446b1d0c69cbe476eeff55b3ac35edb89ba97116b0e7783660f2c7b31b2a2d6c4709d0ab45d01a838100694b0777c9c9c14c959b07c437c73a5eabb7402f1001e802d797a2e7707285834fb6440a1c2f727f7bb84ddb2a49312d32fa0ce620c43872655cb5c394749c9e75d7fa25be00efe50d47d6\nM = fbbab6698a9142095c46b38a732592e4366c1838b84bf40f8c8fc7b630f73380a0d09765562365798f8c8030ed1b6728329d8bb06e882c35a1d59bfe84146a9db2afe42a414014e247390281c782fce806d62adb54778d2bcb49555459429d6ed446af5359657667f6aa19e8e3e0e24ab2bc312b2d90b5cb1ce6f2f15af15d9d\n\nModExp = ba16d7f3f6e162ce248490d164a13c00e7720d8a667e2d3ebeb13f1663e15ef5408d5b56cbc7bc793a8ca787cc50f8e15e0e9d4ee764531d04a9114eea556bb3e206ed7d85267151a056b6e68fbf35e03f2cf829708ffe1de13e95ecfe365aff1eea36340ffcd3892dee659fb1ecbe50f5080e54737c10f9c1ba638b14ef537e\nA = 9025e6183706105e948b1b0edf922f9011b9e11887d70adb00b26f272b9e76a38f3099084d9cccf12d04b1a99c0f654f8b9ed90c6dff9478c60bf05d58d734ab60eaefa14a22230ec60c90dc1f0704b61eef0bef345785ae0e6a9af7db069cf6bd2b4e0fe58a0ade83c7e46a04b9fe1d24cb9b65c6f80de713e61d70eae5b286\nE = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae159400943725570726cdc92b3ea94f9f206729516fdda83e31d815b0c7720e7598a91d992273e3bd8ac413b441d8f1dfe5aa7c3bf3ef573adc38292676217467731e6cf440a59611b8110af88d3e62f60209b513b01fbb69a097458ad02096b5e38f0\nM = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31",
     "515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7\n\n\n# RSAZ 512-bit.\n#\n# These are regression tests for code which historically reached the RSAZ-512\n# code. That has since been removed, but the test vectors remain. Note that the\n# lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4\nA = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE =  be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same as above except A is negative.\nModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd\nA = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364\nE =   be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM =  f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE =  be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490\nE =   be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM =  f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\nE =  be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25\nA = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE =   be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1\nM =  f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491\n\n\n# RSAZ 1024-bit.\n# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot.\n\n# Control: No relationship between A and M except that A < M and they're the same number of limbs.\nModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7\nA = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# Same as above except A is negative.\nModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10\nA = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8\nE = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575\nM = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7\n\n# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.\nModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nA =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Same inputs as above except A is negative. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 1\nA =  -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c1",
-    "6f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d\nA =  -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n\n# Exp tests.\n#\n# These test vectors satisfy A ^ E = Exp.\n\nExp = aa6d7ac431\nA = d0e07\nE = 2\n\nExp = 12d416b110dbb4e467ff0c89a22122f4da8240\nA = 1a18cf6\nE = 6\n\nExp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000\nA = 2a3acbd2\nE = d\n\nExp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1\nA = 54b3ae461\nE = 1a\n\nExp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f\nA = fccec0f6df\nE = 25\n\n\n# ModSqrt tests.\n#\n# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime.\n# ModSqrt is in [0, (P-1)/2].\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 5\n\nModSqrt = 1\nA = -4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 2\nA = 4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 2\nA = 4\nP = 7\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 4\nA = 10\nP = b\n\nModSqrt = 0\nA = 0\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 2\nA = 4\nP = b\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 3\nA = 9\nP = d\n\nModSqrt = 8\nA = d\nP = 11\n\nModSqrt = 6\nA = df\nP = 11\n\nModSqrt = 4\nA = 10\nP = 11\n\nModSqrt = 5\nA = 90\nP = 11\n\nModSqrt = 3\nA = 80\nP = 11\n\nModSqrt = 9\nA = -e\nP = 13\n\nModSqrt = 7\nA = 7d\nP = 13\n\nModSqrt = 6\nA = 37\nP = 13\n\nModSqrt = 1\nA = 1\nP = 13\n\nModSqrt = 8\nA = 1a\nP = 13\n\nModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec\nA = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d\nA = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444\nA = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4\nA = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4\nA = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66\nA = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d\nA = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387\nA = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87\nA = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23\nA = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba\nA = 17878f8048227573a9d70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc\nA = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a\nA = 3413afae333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080\nA = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c\n",
-    "A = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247\nA = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065\nA = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d\nA = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14\nA = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0\nA = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c\nA = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106\nA = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e\nA = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096\nA = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852\nA = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077\nA = 55e55e5f94dc3d7aabc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71\nA = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0\nA = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5\nA = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556\nA = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f\nA = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029\nA = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e\nA = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c\nA = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31\nA = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765\nA = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a\nA = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb\nA = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f\nA = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186\nA = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# NotModSquare tests.\n#\n# These test vectors are such that NotModSquare is not a square modulo P.\n\nNotModSquare = 03\nP = 07\n\nNotModSquare = 05\nP = 07\n\nNotModSquare = 06\nP = 07\n\nNotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# ModInv tests.\n#\n# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M.\n\nModInv = 00\nA = 00\nM = 01\n\nModInv = 00\nA = 01\nM = 01\n\nModInv = 00\nA = 02\nM = 01\n\nModInv = 00\nA = 03\nM = 01\n",
+    "6f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a \"correct top\" isn't the right length for RSAZ.\nModExp = 0\nA =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# A is negative, and A (mod M) is the right length for RSAZ.\nModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d\nA =  -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\nE = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103\nM =  b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965\n\n# Regression test for CVE-2017-3738.\nModExp = d360792bd8210786607817c3dda64cc38c8d0f25569597cb1f363c7919a0c3587baff01a2283edaeb04fc288ac0ab3f279b2a89ffcb452d8bdf72422a9f9780f4aa702dc964cf033149d3a339883062cab8564aebdbfac0bf68985e522c6fe545b346044690c525ca85d3f4eb3e3c25cdf541545afc84a309e9b1d7807003461\nA = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020df\nE = 2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020FF2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020\nM = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2020202020ff\n\n\n# Exp tests.\n#\n# These test vectors satisfy A ^ E = Exp.\n\nExp = aa6d7ac431\nA = d0e07\nE = 2\n\nExp = 12d416b110dbb4e467ff0c89a22122f4da8240\nA = 1a18cf6\nE = 6\n\nExp = 49a3b33e23d84f1ce0d5d83f5dcb651d50cf3920f0143da2310d0512a90a06cd8f38977df8a756c30883de38df092000\nA = 2a3acbd2\nE = d\n\nExp = 5b4a0d5a956f885f275712b194459980f24708bfb6393d71bd37dce852ce455724f5ee5030775fb86b4295edc98afaafc097e4d82a97c0078ec0eac763db16549c5145c4cf2d3124f88cf9a5c71da0625afb99b26801786fe49a778415dc025954021753d08691947a208b613f0be5c1\nA = 54b3ae461\nE = 1a\n\nExp = a0ea5f6a4de49beb8fb7f0dab280d6a32c5a3814c9a5153a7944cec0a9028497846a8a89044348721a0bb5f0c3ded3e980574ea321b0cdb0ead4f4e93841ea7478a7f15d9729b646a8165813a0750e8124f5465dda9b105e1bbeff18fd09c09a2e26610d9176d253b877c3a8908a6be521cbe1e472a7a1b7820e4e890f8f28aacd34609c686e76e15b01bd9324a71290812724ea564d11c874a6765b262c3e57d479da0287a76026a1e8fe53da0b02405da1d379eaa30fc65f\nA = fccec0f6df\nE = 25\n\n\n# ModSqrt tests.\n#\n# These test vectors satisfy ModSqrt * ModSqrt = A (mod P) with P a prime.\n# ModSqrt is in [0, (P-1)/2].\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = 1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 1\nA = -1\nP = 2\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = -3\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 3\n\nModSqrt = 0\nA = 0\nP = 5\n\nModSqrt = 1\nA = -4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 2\nA = 4\nP = 5\n\nModSqrt = 0\nA = -5\nP = 5\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 0\nA = 0\nP = 7\n\nModSqrt = 2\nA = 4\nP = 7\n\nModSqrt = 3\nA = -5\nP = 7\n\nModSqrt = 4\nA = 10\nP = b\n\nModSqrt = 0\nA = 0\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 3\nA = -2\nP = b\n\nModSqrt = 2\nA = 4\nP = b\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 2\nA = 1e\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 0\nA = -d\nP = d\n\nModSqrt = 3\nA = 9\nP = d\n\nModSqrt = 8\nA = d\nP = 11\n\nModSqrt = 6\nA = df\nP = 11\n\nModSqrt = 4\nA = 10\nP = 11\n\nModSqrt = 5\nA = 90\nP = 11\n\nModSqrt = 3\nA = 80\nP = 11\n\nModSqrt = 9\nA = -e\nP = 13\n\nModSqrt = 7\nA = 7d\nP = 13\n\nModSqrt = 6\nA = 37\nP = 13\n\nModSqrt = 1\nA = 1\nP = 13\n\nModSqrt = 8\nA = 1a\nP = 13\n\nModSqrt = 54d4cf0fafe265056a29016778cea6b712bc66a132fb5e6b6865e9b49e4c97ec\nA = 599c10484b22d0b5a115268c7538ca99b3253a311a4ab1ca11c3665b0bec393a1167d1ad94fb84cb2c7ad7e2c933e8f613bdd08fe1f1aa4a9b0b9de0c8a7c9d4\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 38a7365a15365e911286c1be2a7afe76ef390234d76269e04dee17313f6ea54d\nA = 1c4aabb4d8369710131c664ecf2849e963c1bc31d66e0b939bacf99a870c71f24ed71bdddcf566f3908271fee43fc1ebb51eac7e3153efae641b49d2e796a12a\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 35ab18a560dece04725667f640ca61d1d59f14d191f94c79f58531acd097d444\nA = 685168ae855d60eba220d803f5296459b30a289580668db9ed51bca51cc2d453a937e13819ae34f7a9a143ac96d17420c53919167e46279b562b550be1cd9abc\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 288370029e87024175e5bec0eab0929179f42e16995e7f6194eefc61061e54f4\nA = 2a14ab77c045bdc48220ba9c463e1a4b4049cb01edb53be0937767eb2ec19b7d719855052281250a36a0b76d9a5d967d0756e1ded7a052f7056191ad66bcfc9\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 32255cf01dc943577ec2bcb221b98491d7a1130d046d6c68e95fedff643ce3a4\nA = e26f6dd46a513a1dd3fb14b71be1d4c9e9d79eda1cde10ea4d1eb8abfd4d5857572205e247184dd0cbefa37b5c0bf680ba2bd28c5741f725cfe2aae37419baf\nP = cfc4ccae35458ab5be1a1bc0664188253301f8702af4f8fb19fed12de0c653b1\n\nModSqrt = 5172345e801ada63fbc4782e32583cc3b4fea88b9e6dfd542f3542f8538ade66\nA = 40dafa8342b302bb04b1f3ddb3b9015a8fc1b597857c115b40631c7be9e22de89358fca23b331596ee5ff304dad7811e6d8e8822f7aa533c9e7c882634ea550\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 4dcf63c423bf0e39aca2293d57f6792d023db649d6719fe936446904b9f7e60d\nA = 5bcdb514bbe84261e169203e8017909b60c9bb330400c766ee01b0189378e70e61867a164a12643ddc9e94b61e09e5b158cbe85be228a3cc48f95a552958b8f2\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = cf77c5c2d12a500b75cbfb1f3e66ee75d886b9365cf4f8b4d1bd18a6be0f387\nA = 4652ddc2ea7b460d8ec3c9059b8f9b5dae6cac55b51f2ad86fcb336b25235737965cc515e2ff0b54835015b7ebeeda6fadd986471d8cb424d309fc353d1e269\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 1e0549e4c5a26023e9d24fd8c67419960746f82b1ecd113bdac66f570a475d87\nA = 5f4a6d450ab1390d96ab1deaa0ba18f897cb63daf0c9e1ef6c08e804c26b5e842f6c08f13db5d4a6e88f07af2a3cb04fa06fc3e59c410b9356f025ed81acc74\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 144481a781d831c1ca046ca9e322d79ad4d2c6dd9f780bea9d1ced9cd20b7b23\nA = 4c254fabca441017132b9eacd4ca40a336db3e5c09715773fa07af095989a91cc968ff07a9ff56ed06b0ce0c5269f7b2ab68564ecab9f4467a7e96b6cc6b21b7\nP = a6813d316f9aca30f98b4f864b8b4b8f51493af930bd4d3a1b205a710e99add3\n\nModSqrt = 216fecc7667f488a3d2d102a38b46b4860ab858300b8638af4f34e1103fd73ba\nA = 17878f8048227573a9d",
+    "70f53c0e76ff13fe9f56e9c984c92514d3d13dec23c816661f0618d21371b80dfd885cb59551bdf80046f65f22ea9b89c78645a6e455a\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 458e5e789ccd2417174f7e30bb31914b9656bd8cf2b9f5a9752a8737a67707bc\nA = 5c7d39a4bb04e69201aa519f80ee7e62ea14ca55e13656d1da3f45367e2fb2d061aa2940708d02ac67d35cd2ccf54a1bf95bcbc759779e692cfdcbb3aa1a05b\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 543125a16c2bb8b8f8a2c39c497e5224ec77533602d7dbe24002e32dcbd2ef1a\nA = 3413afae333b2ad9ff45c7f3c7e5934b3127e8b1a55225958ee6ccf42423e81559bf070ad3f3353b78c0ffd41475af49f59d268ef78bdae879f5155e8d1cc07\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 10e16859c67bdb2eaab52a7c847dbf37162eda258a9f6262ebacfe4cbbbc1080\nA = 21ce7905894faf220bdf4a82a2d855994ca2dc9feaecaa53c7f146e1f49934215695e9bb46ba370b7005a90c399674caa8969eb442e7914d90f749774d7fd194\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 32a00586adc6f6cc2b1a04e1be0ab569fde235e1436c38b6af92bc5ebd60bc1c\nA = 350da4fd8cf03c12f7dd6ac6d3ab801a3413964083e374662aaf878d6838b97d4feb9e52cd307a25b113e101661a865463ee2480c626aa4e2ec437d72e7bae4c\nP = bd37c850cf7d702bac879f3c21a51a5a4df2b8eb0935861e0753a6eb62261a95\n\nModSqrt = 971f75bc7afa8b4b50f1d4b05e52deac7d4836a08d30546f29649bf1ca6a247\nA = 655ed4c5d8d0afb4f9360372ee1ef1303898d2423e585108a3303faedb55064d2ef25666ed4c4d71fe6063fea1f3142b435714b0e30b339dd791d347c884654\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 48fa882b7cb6a29de9e3769f72eb67f1efd4d2af56f0c7e410c610efcbce2065\nA = 14f3503f33b243800eac1defaab33e04c01e80163fb3efd03860970cc016832431ca4fc6d1b760f4f40166b0b8b3c40dbebc81460cc10890172243770338f090\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 236fd7e397ea7f8bc2a288eb7236ca41936fa702b7dccca56c8852e147511f7d\nA = 1bbd0980feac854782813bcde4da85e8a054549a1b515e065da4236528035e756882e29e762cf60453e375cca9dc6ff637f9558bf86646e3b928f68f82af7efe\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 693f0cbe8c81b0afde0cd2f83e53795dcae6b0cc4ba930ab5c752400d787f14\nA = 7b20f9664b23907e152ab8c9a907f72e8670c1c38ab4cd1411ea7c2159c09aa131afe068929b8e6ad1409b74c04975180d1cd0a9fa74e923c3fd451e8da2c34\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 4a086c50b0bad576501ddb6280743b2c9d247841eb7f14d90561432ff7dca6f0\nA = 4367431ec0cd0d7626538b93a090c30fe0c97c18ca03b97ddae304b619112b5b4d02bf0f041fa3fd673f9ef2ceb07eb2079d11c56dd903b1a87e8252a97b8079\nP = 9810151ad4bc9c5d68fc326395b509f2625bfebca1c3801ad4da7539fdbaa6f7\n\nModSqrt = 18f8433fa468d8065157708f1f1e53b8e31d39c6011fbc2bad93de1b5548e19c\nA = 739c032bb4139c199c40f548d37234298772e4ccb9d3ba28412b60ad23b4c465b0787e2382f1c5a4a87af2d20eb978b7dcbe73f2112249477d15c8a85e54a79\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 49e3c8eef5e067cabd51a7c01384ce05ab8f4342f655559d8a689eb7b20e0106\nA = 18400c2cc3e06b99b4e39c77b9af5ff0e9c683f1708321afa4cd5b6988d13b36b1d9eb4379b7902d9ceb40c03f814b2b6a01b90509bbb4532f13ab1571c4d04a\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 35548c530745f440329325cc8a5fbd90c16a7f0788879a4869bc4d4f73acda0e\nA = 181a3c5ab02566e7166c4d6d2f2bd4a8ecc25991a98d270bde80cf4332766a7068b14240bf5f5dcd45e90ef252596da3eb05b11d68b2063f7b3a825742593ca9\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 1ab7046e6af061ade5f9719008fa4d989007e2a579a134a5b9f19ec410984096\nA = 1008a03e211fab0d45856377079bc96b0776c2d4c0175661f3493246cea2ab0a02a706c85314fb707ad9906bedb2cfd577d62092ae08ff21d7b949373ea954c7\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 2be9e3e7515960d90f115b89f60dedc173a73ce163b4036e85b7b6a76fd90852\nA = 392053a9f0100540a8e1a0c353e922068a84dad3a4a8e8962fbc0bee2b6a06e20d08ade16eb1409a16acfcac3db5c43c421505e07035ca308b15c4a6db0864c0\nP = adcd56924f73836ebe4dccfe006ad3b1e5076562cd11b161642cab7af2284659\n\nModSqrt = 5b301bb93bdcf050183107e36258b53b4805918114ea1c2227b0911d5b4dc077\nA = 55e55e5f94dc3d7aabc921f6469d85fa2e1e92a87347c57afad5872306ae69f9fb99297d1e3e793dd9e8632244208154de5da7114fd876383bf1422f7ece024\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 2df9609e2f5a5156c3260461b2ee52eacdef00bd8b091479813143a6c5283f71\nA = 2099325b7f12fe77353ddf3f2b2c5ef77b49671b150af954cf84e9675e3ecde3e057084641a633d19533b4712ab49924c8b5c31d591abcc88291f51253fa2a7\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = dfab751710e9008e25e422d1199d6fbec4dc7fba35b4da9d225a746eb4126a0\nA = c006af53d4737fb293584df6ffe2e4cb3fd8dc77fb7c1f13b97bb9c249e3ee5fb9feff7488265b3093906c08a4946f142ac7b491937d24bfba6413366ce371d\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 26bc030008d6c60a09fb0e16093a649fcb40c6c21a8e2da2353ba4b07c4f85d5\nA = 1eaabcfad2ed349ac9356e6f4da0b301266ddde811cb0f817aba8f5c10fb8b8ba9d0ef2dd386b668f16eac296118fdb8cb7afe1b865648c81c2fa3cf21f2711b\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = 35051b1482ec2578f3dc0000a422cb5111e43c37f1ac20b1844d3de2128c4556\nA = 315ff9de178681116f2a5fa78eebf4818e1d680435eacdfaf9d0e5c4fc01fc034b352c82fd52c81ca30d68864952dacc99d08269c9dd7ca99ccf22da98c3840\nP = d43280ac150f725f4a2a1dceb1c79bcac57855a4eba72ae93762d09bcb2444fb\n\nModSqrt = a5474252885cacf004c460a7793ff0b0a2187bb1a9ed700ae3470199faef71f\nA = 19856fc1351c4b02abf573bb2fc6ff92355fa369d62bb8f2260fa772fb1693f509a56cad661930abcac049dd70f4b16bed4a4c172e73e772504c9990ce7f92f\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 12daf4722387ecf47de1b0b6b110a062dc5ea2685bc9dbde66b8d15622985029\nA = fb8479787069116abc42abfd7dc0c24d2ad04fe0c04b42a6dff714af715d17e0fd77855f950f264542b06d48e8818de813ddb7975798b7debefcdaa5ff86beb\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 397996ed5c0ac6ad32e43c337e9de421b87774cc162bf7ac7bbedf4a9029255e\nA = 5aa04353321bd2de92481be740357f979da464b53aa39111fdbb734cf7af6b3857d1baa08d3a126a3dd34a2fbae2bf2b84e900686c1d31505b390185acef5fe5\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 2cf4b844a54ba359dc592ef1b49f43fcfeae84d1087edfefdd0b9174b43c0a3c\nA = 365a8650510bcfd8fa87432f167cf487234c215857403b9270b5eebeafa48cd6da47fd60dc311b94d1d72baad0447c31f0b212d755f46c256e16e5e015e6546e\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 9277c73043ff767c3fa606f0cd66b9d854a600c8c18287f191ce277758c3f31\nA = 62cec3901626d03e8df66299a87c54b1f7a55cafc99f0b6bba1b5d51a3d2b7d2171c9135a9d8a5346d436e0136b12e515e703e3cd84ecfe154eb94c6772a6d72\nP = dc315fd52684fba79e577a204de9053b11a5d7a414263fec9eff6ff62188829d\n\nModSqrt = 4189e5a90c1b1abdc1c7c05b3587e6f362e06f927b6cf5f0d271aab3d6f90765\nA = 336b8d0f9dac842c696bc020f49c6aa023842c16f2052eb02f17959006554ca0012042c80c72590f21c6bf5a3714c9cb552aa69730e33db93a56a909b273f39\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 36ccd38cb5a6bd8a73bca55936a2227c503664422c2296faf7e2b1c6a375a43a\nA = fecfd60a376befbe48d2c4f6d070d716d2f403cd5daefbce62b720df44deb605162c8f20f49fd7ec30d4f8e70d803d45b3a44b5d912baa3410d991165d7c507\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 198fc8569be172dc9b71023ed3d42d2ba94bae4099643f6517ab03f540527fdb\nA = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ec\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = 21b7f74c30ded681d6138cf8e6fd798f32a049e94138e982f1845df3dc9e686f\nA = 9a30b791c1ba4f394b4e3dcd5837e474237f4fe8987b255c098a47b2c14c598ec69d2beae444dd4fe9c4ede8173d2b187677cc706a3c28f3b81627d8a5fb6fd\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\nModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186\nA = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f",
+    "2ab5ffc3e246b41c32f71e951f\n\n\n# NotModSquare tests.\n#\n# These test vectors are such that NotModSquare is not a square modulo P.\n\nNotModSquare = 03\nP = 07\n\nNotModSquare = 05\nP = 07\n\nNotModSquare = 06\nP = 07\n\nNotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e\nP = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f\n\n\n# ModInv tests.\n#\n# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M.\n\nModInv = 00\nA = 00\nM = 01\n\nModInv = 00\nA = 01\nM = 01\n\nModInv = 00\nA = 02\nM = 01\n\nModInv = 00\nA = 03\nM = 01\n",
 };
-static const size_t kLen35 = 835053;
+static const size_t kLen35 = 836140;
 
 static const char *kData36[] = {
     "# Negation tests.\n#\n# The following tests satisfy A = -B (mod P).\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000000\nB = 0000000000000000000000000000000000000000000000000000000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000001\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000003\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffffc\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000007\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffff8\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000000f\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffff0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000001f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffffe0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000003f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffffc0\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000007f\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffff80\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000000ff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffff00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000001ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffe00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000003ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffffc00\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000007ff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffff800\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000000fff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffff000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000001fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffe000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000003fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffffc000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000007fff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffff8000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000000ffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffff0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000001ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffe0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000003ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffffc0000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000007ffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffff80000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000000fffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffff00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000001fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffe00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000003fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffffc00000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000007fffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffff800000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000000ffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffff000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000001ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffe000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000003ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffffc000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000007ffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffff8000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000000fffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffff0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000001fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffe0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000003fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffffc0000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000007fffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffff80000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000000ffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000001ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffe00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000003ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffffc00000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000007ffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffff800000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000000fffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffff000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000001fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffe000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000003fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffffc000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000007fffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffff8000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000000ffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffff0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000001ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffe0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000003ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffffc0000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000007ffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffff80000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000000fffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffff00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000001fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffe00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000003fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffffc00000000000\n\nTest = Negate\nA = 00000000000000000000000000000000000000000000000000007fffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffff800000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000000ffffffffffff\nB = ffffffff00000001000000000000000000000000ffffffffffff000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000001ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffe000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000003ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffffc000000000000\n\nTest = Negate\nA = 0000000000000000000000000000000000000000000000000007ffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffff8000000000000\n\nTest = Negate\nA = 000000000000000000000000000000000000000000000000000fffffffffffff\nB = ffffffff00000001000000000000000000000000fffffffffff0000000000000\n\nTest = Negate\nA ",
diff --git a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
index bc3440d..89b81ed 100644
--- a/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
+++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
@@ -77,7 +77,7 @@
 	vmovdqu	256-128(%rsi),%ymm8
 
 	leaq	192(%rsp),%rbx
-	vpbroadcastq	.Land_mask(%rip),%ymm15
+	vmovdqu	.Land_mask(%rip),%ymm15
 	jmp	.LOOP_GRANDE_SQR_1024
 
 .align	32
@@ -829,10 +829,10 @@
 	vpmuludq	192-128(%rcx),%ymm11,%ymm12
 	vpaddq	%ymm12,%ymm6,%ymm6
 	vpmuludq	224-128(%rcx),%ymm11,%ymm13
-	vpblendd	$3,%ymm14,%ymm9,%ymm9
+	vpblendd	$3,%ymm14,%ymm9,%ymm12
 	vpaddq	%ymm13,%ymm7,%ymm7
 	vpmuludq	256-128(%rcx),%ymm11,%ymm0
-	vpaddq	%ymm9,%ymm3,%ymm3
+	vpaddq	%ymm12,%ymm3,%ymm3
 	vpaddq	%ymm0,%ymm8,%ymm8
 
 	movq	%rbx,%rax
@@ -845,7 +845,9 @@
 	vmovdqu	-8+64-128(%rsi),%ymm13
 
 	movq	%r10,%rax
+	vpblendd	$0xfc,%ymm14,%ymm9,%ymm9
 	imull	%r8d,%eax
+	vpaddq	%ymm9,%ymm4,%ymm4
 	andl	$0x1fffffff,%eax
 
 	imulq	16-128(%rsi),%rbx
@@ -1074,7 +1076,6 @@
 
 	decl	%r14d
 	jnz	.Loop_mul_1024
-	vpermq	$0,%ymm15,%ymm15
 	vpaddq	(%rsp),%ymm12,%ymm0
 
 	vpsrlq	$29,%ymm0,%ymm12
@@ -1730,7 +1731,7 @@
 
 .align	64
 .Land_mask:
-.quad	0x1fffffff,0x1fffffff,0x1fffffff,-1
+.quad	0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff
 .Lscatter_permd:
 .long	0,2,4,6,7,7,7,7
 .Lgather_permd:
diff --git a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
index 6eb7afc5..6dd50af 100644
--- a/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
+++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
@@ -77,7 +77,7 @@
 	vmovdqu	256-128(%rsi),%ymm8
 
 	leaq	192(%rsp),%rbx
-	vpbroadcastq	L$and_mask(%rip),%ymm15
+	vmovdqu	L$and_mask(%rip),%ymm15
 	jmp	L$OOP_GRANDE_SQR_1024
 
 .p2align	5
@@ -829,10 +829,10 @@
 	vpmuludq	192-128(%rcx),%ymm11,%ymm12
 	vpaddq	%ymm12,%ymm6,%ymm6
 	vpmuludq	224-128(%rcx),%ymm11,%ymm13
-	vpblendd	$3,%ymm14,%ymm9,%ymm9
+	vpblendd	$3,%ymm14,%ymm9,%ymm12
 	vpaddq	%ymm13,%ymm7,%ymm7
 	vpmuludq	256-128(%rcx),%ymm11,%ymm0
-	vpaddq	%ymm9,%ymm3,%ymm3
+	vpaddq	%ymm12,%ymm3,%ymm3
 	vpaddq	%ymm0,%ymm8,%ymm8
 
 	movq	%rbx,%rax
@@ -845,7 +845,9 @@
 	vmovdqu	-8+64-128(%rsi),%ymm13
 
 	movq	%r10,%rax
+	vpblendd	$0xfc,%ymm14,%ymm9,%ymm9
 	imull	%r8d,%eax
+	vpaddq	%ymm9,%ymm4,%ymm4
 	andl	$0x1fffffff,%eax
 
 	imulq	16-128(%rsi),%rbx
@@ -1074,7 +1076,6 @@
 
 	decl	%r14d
 	jnz	L$oop_mul_1024
-	vpermq	$0,%ymm15,%ymm15
 	vpaddq	(%rsp),%ymm12,%ymm0
 
 	vpsrlq	$29,%ymm0,%ymm12
@@ -1729,7 +1730,7 @@
 
 .p2align	6
 L$and_mask:
-.quad	0x1fffffff,0x1fffffff,0x1fffffff,-1
+.quad	0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff
 L$scatter_permd:
 .long	0,2,4,6,7,7,7,7
 L$gather_permd:
diff --git a/third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm
index a06e6f6c..32624ba 100644
--- a/third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm
+++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm
@@ -103,7 +103,7 @@
 	vmovdqu	ymm8,YMMWORD[((256-128))+rsi]
 
 	lea	rbx,[192+rsp]
-	vpbroadcastq	ymm15,QWORD[$L$and_mask]
+	vmovdqu	ymm15,YMMWORD[$L$and_mask]
 	jmp	NEAR $L$OOP_GRANDE_SQR_1024
 
 ALIGN	32
@@ -891,10 +891,10 @@
 	vpmuludq	ymm12,ymm11,YMMWORD[((192-128))+rcx]
 	vpaddq	ymm6,ymm6,ymm12
 	vpmuludq	ymm13,ymm11,YMMWORD[((224-128))+rcx]
-	vpblendd	ymm9,ymm9,ymm14,3
+	vpblendd	ymm12,ymm9,ymm14,3
 	vpaddq	ymm7,ymm7,ymm13
 	vpmuludq	ymm0,ymm11,YMMWORD[((256-128))+rcx]
-	vpaddq	ymm3,ymm3,ymm9
+	vpaddq	ymm3,ymm3,ymm12
 	vpaddq	ymm8,ymm8,ymm0
 
 	mov	rax,rbx
@@ -907,7 +907,9 @@
 	vmovdqu	ymm13,YMMWORD[((-8+64-128))+rsi]
 
 	mov	rax,r10
+	vpblendd	ymm9,ymm9,ymm14,0xfc
 	imul	eax,r8d
+	vpaddq	ymm4,ymm4,ymm9
 	and	eax,0x1fffffff
 
 	imul	rbx,QWORD[((16-128))+rsi]
@@ -1136,7 +1138,6 @@
 
 	dec	r14d
 	jnz	NEAR $L$oop_mul_1024
-	vpermq	ymm15,ymm15,0
 	vpaddq	ymm0,ymm12,YMMWORD[rsp]
 
 	vpsrlq	ymm12,ymm0,29
@@ -1823,7 +1824,7 @@
 
 ALIGN	64
 $L$and_mask:
-	DQ	0x1fffffff,0x1fffffff,0x1fffffff,-1
+	DQ	0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff
 $L$scatter_permd:
 	DD	0,2,4,6,7,7,7,7
 $L$gather_permd:
diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js
index c3e1fe15..b069e4dc 100644
--- a/third_party/closure_compiler/externs/file_manager_private.js
+++ b/third_party/closure_compiler/externs/file_manager_private.js
@@ -203,7 +203,8 @@
 
 /**
  * @typedef {{
- *   extensionId: string,
+ *   providerId: string,
+ *   extensionId: (string|undefined),
  *   name: string,
  *   configurable: boolean,
  *   watchable: boolean,
@@ -211,7 +212,7 @@
  *   source: string
  * }}
  */
-var ProvidingExtension;
+var Provider;
 
 /**
  * @typedef {{
@@ -630,19 +631,19 @@
 chrome.fileManagerPrivate.isPiexLoaderEnabled = function(callback) {};
 
 /**
- * Returns list of available providing extensions.
- * @param {function((!Array<!ProvidingExtension>|undefined))} callback
+ * Returns list of available providers.
+ * @param {function((!Array<!Provider>|undefined))} callback
  */
-chrome.fileManagerPrivate.getProvidingExtensions = function(callback) {};
+chrome.fileManagerPrivate.getProviders = function(callback) {};
 
 /**
  * Requests adding a new provided file system. If not possible, then an error
  * via chrome.runtime.lastError is returned.
- * @param {string} extensionId
+ * @param {string} providerId
  * @param {function()} callback
  */
 chrome.fileManagerPrivate.addProvidedFileSystem =
-    function(extensionId, callback) {};
+    function(providerId, callback) {};
 
 /**
  * Requests configuring an existing file system. If not possible, then returns
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium
index 5f6534db..fb1d4419 100644
--- a/third_party/harfbuzz-ng/README.chromium
+++ b/third_party/harfbuzz-ng/README.chromium
@@ -19,4 +19,7 @@
 harfbuzz.gyp accordingly, update the NEWS file from HarfBuzz' release notes, and
 bump the version numbers in README.chromium.
 
-Locally patch hb-private.hh to silence unusued variable warnings in MSVC.
\ No newline at end of file
+Locally patch hb-private.hh to silence unusued variable warnings in MSVC.
+
+Locally patching hb_set implementation back to the pre 1.6.1 implemention as we
+observe a set of timeToFirst*Paint performance regressions in issue 781794.
diff --git a/third_party/harfbuzz-ng/src/hb-set-private.hh b/third_party/harfbuzz-ng/src/hb-set-private.hh
index 5971e9b..71a843f 100644
--- a/third_party/harfbuzz-ng/src/hb-set-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-set-private.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2012,2017  Google, Inc.
+ * Copyright © 2012  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -35,398 +35,136 @@
  * hb_set_t
  */
 
-/* TODO Keep a free-list so we can free pages that are completely zeroed.  At that
- * point maybe also use a sentinel value for "all-1" pages? */
+
+/* TODO Make this faster and memmory efficient. */
 
 struct hb_set_t
 {
-  struct page_map_t
-  {
-    inline int cmp (const page_map_t *o) const { return (int) o->major - (int) major; }
-
-    uint32_t major;
-    uint32_t index;
-  };
-
-  struct page_t
-  {
-    inline void init0 (void) { memset (&v, 0, sizeof (v)); }
-    inline void init1 (void) { memset (&v, 0xff, sizeof (v)); }
-
-    inline unsigned int len (void) const
-    { return ARRAY_LENGTH_CONST (v); }
-
-    inline bool is_empty (void) const
-    {
-      for (unsigned int i = 0; i < len (); i++)
-        if (v[i])
-	  return false;
-      return true;
-    }
-
-    inline void add (hb_codepoint_t g) { elt (g) |= mask (g); }
-    inline void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
-    inline bool has (hb_codepoint_t g) const { return !!(elt (g) & mask (g)); }
-
-    inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
-    {
-     elt_t *la = &elt (a);
-     elt_t *lb = &elt (b);
-     if (la == lb)
-       *la |= (mask (b) << 1) - mask(a);
-     else
-     {
-       *la |= ~(mask (a) - 1);
-       la++;
-
-       memset (la, 0xff, (char *) lb - (char *) la);
-
-       *lb |= ((mask (b) << 1) - 1);
-
-     }
-    }
-
-    inline bool is_equal (const page_t *other) const
-    {
-      return 0 == memcmp (&v, &other->v, sizeof (v));
-    }
-
-    inline unsigned int get_population (void) const
-    {
-      unsigned int pop = 0;
-      for (unsigned int i = 0; i < len (); i++)
-        pop += _hb_popcount (v[i]);
-      return pop;
-    }
-
-    inline bool next (hb_codepoint_t *codepoint) const
-    {
-      unsigned int m = (*codepoint + 1) & MASK;
-      if (!m)
-      {
-	*codepoint = INVALID;
-	return false;
-      }
-      unsigned int i = m / ELT_BITS;
-      unsigned int j = m & ELT_MASK;
-
-      for (; j < ELT_BITS; j++)
-        if (v[i] & (elt_t (1) << j))
-	  goto found;
-      for (i++; i < len (); i++)
-        if (v[i])
-	  for (j = 0; j < ELT_BITS; j++)
-	    if (v[i] & (elt_t (1) << j))
-	      goto found;
-
-      *codepoint = INVALID;
-      return false;
-
-    found:
-      *codepoint = i * ELT_BITS + j;
-      return true;
-    }
-    inline hb_codepoint_t get_min (void) const
-    {
-      for (unsigned int i = 0; i < len (); i++)
-        if (v[i])
-	{
-	  elt_t e = v[i];
-	  for (unsigned int j = 0; j < ELT_BITS; j++)
-	    if (e & (elt_t (1) << j))
-	      return i * ELT_BITS + j;
-	}
-      return INVALID;
-    }
-    inline hb_codepoint_t get_max (void) const
-    {
-      for (int i = len () - 1; i >= 0; i--)
-        if (v[i])
-	{
-	  elt_t e = v[i];
-	  for (int j = ELT_BITS - 1; j >= 0; j--)
-	    if (e & (elt_t (1) << j))
-	      return i * ELT_BITS + j;
-	}
-      return 0;
-    }
-
-    static const unsigned int PAGE_BITS = 512; /* Use to tune. */
-    static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
-
-    typedef uint64_t elt_t;
-
-#if 0 && HAVE_VECTOR_SIZE
-    /* The vectorized version does not work with clang as non-const
-     * elt() errs "non-const reference cannot bind to vector element". */
-    typedef elt_t vector_t __attribute__((vector_size (PAGE_BITS / 8)));
-#else
-    typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
-#endif
-
-    vector_t v;
-
-    static const unsigned int ELT_BITS = sizeof (elt_t) * 8;
-    static const unsigned int ELT_MASK = ELT_BITS - 1;
-    static const unsigned int BITS = sizeof (vector_t) * 8;
-    static const unsigned int MASK = BITS - 1;
-    static_assert (PAGE_BITS == BITS, "");
-
-    elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; }
-    elt_t const &elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
-    elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & ELT_MASK); }
-  };
-  static_assert (page_t::PAGE_BITS == sizeof (page_t) * 8, "");
-
   hb_object_header_t header;
   ASSERT_POD ();
   bool in_error;
-  hb_prealloced_array_t<page_map_t, 8> page_map;
-  hb_prealloced_array_t<page_t, 8> pages;
 
-  inline bool resize (unsigned int count)
-  {
-    if (unlikely (in_error)) return false;
-    if (!pages.resize (count) || !page_map.resize (count))
-    {
-      pages.resize (page_map.len);
-      in_error = true;
-      return false;
-    }
-    return true;
+  inline void init (void) {
+    hb_object_init (this);
+    clear ();
   }
-
+  inline void fini (void) {
+  }
   inline void clear (void) {
     if (unlikely (hb_object_is_inert (this)))
       return;
     in_error = false;
-    page_map.resize (0);
-    pages.resize (0);
+    memset (elts, 0, sizeof elts);
   }
   inline bool is_empty (void) const {
-    unsigned int count = pages.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!pages[i].is_empty ())
+    for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
+      if (elts[i])
         return false;
     return true;
   }
-
   inline void add (hb_codepoint_t g)
   {
     if (unlikely (in_error)) return;
     if (unlikely (g == INVALID)) return;
-    page_t *page = page_for_insert (g);
-    if (unlikely (!page)) return;
-    page->add (g);
+    if (unlikely (g > MAX_G)) return;
+    elt (g) |= mask (g);
   }
   inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
   {
-    if (unlikely (in_error || a > b || a == INVALID || b == INVALID)) return;
-    unsigned int ma = get_major (a);
-    unsigned int mb = get_major (b);
-    if (ma == mb)
-    {
-      page_t *page = page_for_insert (a);
-      if (unlikely (!page)) return;
-      page->add_range (a, b);
-    }
-    else
-    {
-      page_t *page = page_for_insert (a);
-      if (unlikely (!page)) return;
-      page->add_range (a, major_start (ma + 1) - 1);
-
-      for (unsigned int m = ma + 1; m < mb; m++)
-      {
-	page = page_for_insert (major_start (m));
-	if (unlikely (!page)) return;
-	page->init1 ();
-      }
-
-      page = page_for_insert (b);
-      if (unlikely (!page)) return;
-      page->add_range (major_start (mb), b);
-    }
+    if (unlikely (in_error)) return;
+    /* TODO Speedup */
+    for (unsigned int i = a; i < b + 1; i++)
+      add (i);
   }
   inline void del (hb_codepoint_t g)
   {
     if (unlikely (in_error)) return;
-    page_t *p = page_for (g);
-    if (!p)
-      return;
-    p->del (g);
+    if (unlikely (g > MAX_G)) return;
+    elt (g) &= ~mask (g);
   }
   inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
   {
-    /* TODO Optimize, like add_range(). */
     if (unlikely (in_error)) return;
+    /* TODO Speedup */
     for (unsigned int i = a; i < b + 1; i++)
       del (i);
   }
   inline bool has (hb_codepoint_t g) const
   {
-    const page_t *p = page_for (g);
-    if (!p)
-      return false;
-    return p->has (g);
+    if (unlikely (g > MAX_G)) return false;
+    return !!(elt (g) & mask (g));
   }
   inline bool intersects (hb_codepoint_t first,
 			  hb_codepoint_t last) const
   {
-    hb_codepoint_t c = first - 1;
-    return next (&c) && c <= last;
+    if (unlikely (first > MAX_G)) return false;
+    if (unlikely (last  > MAX_G)) last = MAX_G;
+    unsigned int end = last + 1;
+    for (hb_codepoint_t i = first; i < end; i++)
+      if (has (i))
+        return true;
+    return false;
+  }
+  inline bool is_equal (const hb_set_t *other) const
+  {
+    for (unsigned int i = 0; i < ELTS; i++)
+      if (elts[i] != other->elts[i])
+        return false;
+    return true;
   }
   inline void set (const hb_set_t *other)
   {
     if (unlikely (in_error)) return;
-    unsigned int count = other->pages.len;
-    if (!resize (count))
-      return;
-
-    memcpy (pages.array, other->pages.array, count * sizeof (pages.array[0]));
-    memcpy (page_map.array, other->page_map.array, count * sizeof (page_map.array[0]));
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] = other->elts[i];
   }
-
-  inline bool is_equal (const hb_set_t *other) const
-  {
-    unsigned int na = pages.len;
-    unsigned int nb = other->pages.len;
-
-    unsigned int a = 0, b = 0;
-    for (; a < na && b < nb; )
-    {
-      if (page_at (a).is_empty ()) { a++; continue; }
-      if (other->page_at (b).is_empty ()) { b++; continue; }
-      if (page_map[a].major != other->page_map[b].major ||
-	  !page_at (a).is_equal (&other->page_at (b)))
-        return false;
-      a++;
-      b++;
-    }
-    for (; a < na; a++)
-      if (!page_at (a).is_empty ()) { return false; }
-    for (; b < nb; b++)
-      if (!other->page_at (b).is_empty ()) { return false; }
-
-    return true;
-  }
-
-  template <class Op>
-  inline void process (const hb_set_t *other)
-  {
-    if (unlikely (in_error)) return;
-
-    unsigned int na = pages.len;
-    unsigned int nb = other->pages.len;
-
-    unsigned int count = 0;
-    unsigned int a = 0, b = 0;
-    for (; a < na && b < nb; )
-    {
-      if (page_map[a].major == other->page_map[b].major)
-      {
-        count++;
-	a++;
-	b++;
-      }
-      else if (page_map[a].major < other->page_map[b].major)
-      {
-        if (Op::passthru_left)
-	  count++;
-        a++;
-      }
-      else
-      {
-        if (Op::passthru_right)
-	  count++;
-        b++;
-      }
-    }
-    if (Op::passthru_left)
-      count += na - a;
-    if (Op::passthru_right)
-      count += nb - b;
-
-    if (!resize (count))
-      return;
-
-    /* Process in-place backward. */
-    a = na;
-    b = nb;
-    for (; a && b; )
-    {
-      if (page_map[a - 1].major == other->page_map[b - 1].major)
-      {
-	a--;
-	b--;
-        Op::process (page_at (--count).v, page_at (a).v, other->page_at (b).v);
-      }
-      else if (page_map[a - 1].major > other->page_map[b - 1].major)
-      {
-        a--;
-        if (Op::passthru_left)
-	  page_at (--count).v = page_at (a).v;
-      }
-      else
-      {
-        b--;
-        if (Op::passthru_right)
-	  page_at (--count).v = other->page_at (b).v;
-      }
-    }
-    if (Op::passthru_left)
-      while (a)
-	page_at (--count).v = page_at (--a).v;
-    if (Op::passthru_right)
-      while (b)
-	page_at (--count).v = other->page_at (--b).v;
-    assert (!count);
-  }
-
   inline void union_ (const hb_set_t *other)
   {
-    process<HbOpOr> (other);
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] |= other->elts[i];
   }
   inline void intersect (const hb_set_t *other)
   {
-    process<HbOpAnd> (other);
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] &= other->elts[i];
   }
   inline void subtract (const hb_set_t *other)
   {
-    process<HbOpMinus> (other);
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] &= ~other->elts[i];
   }
   inline void symmetric_difference (const hb_set_t *other)
   {
-    process<HbOpXor> (other);
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] ^= other->elts[i];
+  }
+  inline void invert (void)
+  {
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] = ~elts[i];
   }
   inline bool next (hb_codepoint_t *codepoint) const
   {
     if (unlikely (*codepoint == INVALID)) {
-      *codepoint = get_min ();
-      return *codepoint != INVALID;
-    }
-
-    page_map_t map = {get_major (*codepoint), 0};
-    unsigned int i;
-    page_map.bfind (&map, &i);
-    if (i < page_map.len)
-    {
-      if (pages[page_map[i].index].next (codepoint))
-      {
-	*codepoint += page_map[i].major * page_t::PAGE_BITS;
-        return true;
+      hb_codepoint_t i = get_min ();
+      if (i != INVALID) {
+        *codepoint = i;
+	return true;
+      } else {
+	*codepoint = INVALID;
+        return false;
       }
-      i++;
     }
-    for (; i < page_map.len; i++)
-    {
-      hb_codepoint_t m = pages[page_map[i].index].get_min ();
-      if (m != INVALID)
-      {
-	*codepoint = page_map[i].major * page_t::PAGE_BITS + m;
+    for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
+      if (has (i)) {
+        *codepoint = i;
 	return true;
       }
-    }
     *codepoint = INVALID;
     return false;
   }
@@ -450,66 +188,46 @@
 
   inline unsigned int get_population (void) const
   {
-    unsigned int pop = 0;
-    unsigned int count = pages.len;
-    for (unsigned int i = 0; i < count; i++)
-      pop += pages[i].get_population ();
-    return pop;
+    unsigned int count = 0;
+    for (unsigned int i = 0; i < ELTS; i++)
+      count += _hb_popcount32 (elts[i]);
+    return count;
   }
   inline hb_codepoint_t get_min (void) const
   {
-    unsigned int count = pages.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!page_at (i).is_empty ())
-        return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
+    for (unsigned int i = 0; i < ELTS; i++)
+      if (elts[i])
+	for (unsigned int j = 0; j < BITS; j++)
+	  if (elts[i] & (1u << j))
+	    return i * BITS + j;
     return INVALID;
   }
   inline hb_codepoint_t get_max (void) const
   {
-    unsigned int count = pages.len;
-    for (int i = count - 1; i >= 0; i++)
-      if (!page_at (i).is_empty ())
-        return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_max ();
+    for (unsigned int i = ELTS; i; i--)
+      if (elts[i - 1])
+	for (unsigned int j = BITS; j; j--)
+	  if (elts[i - 1] & (1u << (j - 1)))
+	    return (i - 1) * BITS + (j - 1);
     return INVALID;
   }
 
+  typedef uint32_t elt_t;
+  static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */
+  static const unsigned int SHIFT = 5;
+  static const unsigned int BITS = (1 << SHIFT);
+  static const unsigned int MASK = BITS - 1;
+  static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
   static  const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
 
-  inline page_t *page_for_insert (hb_codepoint_t g)
-  {
-    page_map_t map = {get_major (g), pages.len};
-    unsigned int i;
-    if (!page_map.bfind (&map, &i))
-    {
-      if (!resize (pages.len + 1))
-	return nullptr;
+  elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
+  elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
+  elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
 
-      pages[map.index].init0 ();
-      memmove (&page_map[i + 1], &page_map[i], (page_map.len - 1 - i) * sizeof (page_map[0]));
-      page_map[i] = map;
-    }
-    return &pages[page_map[i].index];
-  }
-  inline page_t *page_for (hb_codepoint_t g)
-  {
-    page_map_t key = {get_major (g)};
-    const page_map_t *found = page_map.bsearch (&key);
-    if (found)
-      return &pages[found->index];
-    return nullptr;
-  }
-  inline const page_t *page_for (hb_codepoint_t g) const
-  {
-    page_map_t key = {get_major (g)};
-    const page_map_t *found = page_map.bsearch (&key);
-    if (found)
-      return &pages[found->index];
-    return nullptr;
-  }
-  inline page_t &page_at (unsigned int i) { return pages[page_map[i].index]; }
-  inline const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; }
-  inline unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; }
-  inline hb_codepoint_t major_start (unsigned int major) const { return major * page_t::PAGE_BITS; }
+  elt_t elts[ELTS]; /* XXX 8kb */
+
+  static_assert ((sizeof (elt_t) * 8 == BITS), "");
+  static_assert ((sizeof (elt_t) * 8 * ELTS > MAX_G), "");
 };
 
 
diff --git a/third_party/harfbuzz-ng/src/hb-set.cc b/third_party/harfbuzz-ng/src/hb-set.cc
index d61a24c0..f3fe1ba4 100644
--- a/third_party/harfbuzz-ng/src/hb-set.cc
+++ b/third_party/harfbuzz-ng/src/hb-set.cc
@@ -45,8 +45,7 @@
   if (!(set = hb_object_create<hb_set_t> ()))
     return hb_set_get_empty ();
 
-  set->page_map.init();
-  set->pages.init();
+  set->clear ();
 
   return set;
 }
@@ -96,8 +95,7 @@
 {
   if (!hb_object_destroy (set)) return;
 
-  set->page_map.finish();
-  set->pages.finish();
+  set->fini ();
 
   free (set);
 }
@@ -375,15 +373,14 @@
  * hb_set_invert:
  * @set: a set.
  *
- *
+ * 
  *
  * Since: 0.9.10
- *
- * Deprecated: 1.6.1
  **/
 void
 hb_set_invert (hb_set_t *set)
 {
+  set->invert ();
 }
 
 /**
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium
index ed641ea4..ae7207d 100644
--- a/third_party/libvpx/README.chromium
+++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@
 License File: source/libvpx/LICENSE
 Security Critical: yes
 
-Date: Sunday November 26 2017
+Date: Wednesday December 06 2017
 Branch: master
-Commit: cbe62b9c2d2b006aba52c8eebe7d842e59166fe4
+Commit: 14dbdd95e686eafbe556c154c9e0bd76fe1d2d1a
 
 Description:
 Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/libvpx_srcs.gni b/third_party/libvpx/libvpx_srcs.gni
index 3aa57fb..cc0da46 100644
--- a/third_party/libvpx/libvpx_srcs.gni
+++ b/third_party/libvpx/libvpx_srcs.gni
@@ -332,6 +332,7 @@
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_sse2.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_ssse3.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/mem_sse2.h",
+  "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_x86.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/txfm_common_sse2.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_asm_stubs.c",
@@ -799,6 +800,7 @@
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_sse2.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/inv_txfm_ssse3.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/mem_sse2.h",
+  "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_x86.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/transpose_sse2.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/txfm_common_sse2.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/x86/vpx_asm_stubs.c",
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h
index 245bbc2..eb88e42 100644
--- a/third_party/libvpx/source/config/vpx_version.h
+++ b/third_party/libvpx/source/config/vpx_version.h
@@ -1,7 +1,7 @@
 #define VERSION_MAJOR  1
 #define VERSION_MINOR  6
 #define VERSION_PATCH  1
-#define VERSION_EXTRA  "1403-gcbe62b9c2"
+#define VERSION_EXTRA  "1441-g14dbdd95e"
 #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH))
-#define VERSION_STRING_NOSP "v1.6.1-1403-gcbe62b9c2"
-#define VERSION_STRING      " v1.6.1-1403-gcbe62b9c2"
+#define VERSION_STRING_NOSP "v1.6.1-1441-g14dbdd95e"
+#define VERSION_STRING      " v1.6.1-1441-g14dbdd95e"
diff --git a/third_party/libwebp/README.chromium b/third_party/libwebp/README.chromium
index b3f1d64d..7e8dafa 100644
--- a/third_party/libwebp/README.chromium
+++ b/third_party/libwebp/README.chromium
@@ -24,3 +24,4 @@
 Cherry-picks:
   Revert patch f7fc4bc: dec/webp.c: don't wait for data before reporting w/h
   296c7dc4 fix lossless decoding w/WEBP_REDUCE_SIZE
+  05f6fe24 upsampling: rm asserts w/REDUCE_CSP+OMIT_C_CODE
diff --git a/third_party/libwebp/src/dsp/upsampling.c b/third_party/libwebp/src/dsp/upsampling.c
index e72626a8..7a99e4e 100644
--- a/third_party/libwebp/src/dsp/upsampling.c
+++ b/third_party/libwebp/src/dsp/upsampling.c
@@ -310,6 +310,7 @@
   assert(WebPUpsamplers[MODE_BGRA] != NULL);
   assert(WebPUpsamplers[MODE_rgbA] != NULL);
   assert(WebPUpsamplers[MODE_bgrA] != NULL);
+#if !defined(WEBP_REDUCE_CSP) || !WEBP_NEON_OMIT_C_CODE
   assert(WebPUpsamplers[MODE_RGB] != NULL);
   assert(WebPUpsamplers[MODE_BGR] != NULL);
   assert(WebPUpsamplers[MODE_ARGB] != NULL);
@@ -317,6 +318,7 @@
   assert(WebPUpsamplers[MODE_RGB_565] != NULL);
   assert(WebPUpsamplers[MODE_Argb] != NULL);
   assert(WebPUpsamplers[MODE_rgbA_4444] != NULL);
+#endif
 
 #endif  // FANCY_UPSAMPLING
   upsampling_last_cpuinfo_used2 = VP8GetCPUInfo;
diff --git a/third_party/qunit/OWNERS b/third_party/qunit/OWNERS
index ffaee23..1eac0a3 100644
--- a/third_party/qunit/OWNERS
+++ b/third_party/qunit/OWNERS
@@ -1,2 +1 @@
-kelvinp@chromium.org
 jamiewalch@chromium.org
diff --git a/third_party/sinonjs/OWNERS b/third_party/sinonjs/OWNERS
index ffaee23..1eac0a3 100644
--- a/third_party/sinonjs/OWNERS
+++ b/third_party/sinonjs/OWNERS
@@ -1,2 +1 @@
-kelvinp@chromium.org
 jamiewalch@chromium.org
diff --git a/third_party/webrtc_overrides/rtc_base/event.cc b/third_party/webrtc_overrides/rtc_base/event.cc
index e213e2de..165d3124 100644
--- a/third_party/webrtc_overrides/rtc_base/event.cc
+++ b/third_party/webrtc_overrides/rtc_base/event.cc
@@ -1,136 +1,38 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
+// 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 "third_party/webrtc_overrides/rtc_base/event.h"
 
-#if defined(WEBRTC_WIN)
-#include <windows.h>
-#elif defined(WEBRTC_POSIX)
-#include <pthread.h>
-#include <sys/time.h>
-#include <time.h>
-#else
-#error "Must define either WEBRTC_WIN or WEBRTC_POSIX."
-#endif
-
-#include "third_party/webrtc/rtc_base/checks.h"
+#include "base/time/time.h"
 
 namespace rtc {
 
-#if defined(WEBRTC_WIN)
-
-Event::Event(bool manual_reset, bool initially_signaled) {
-  event_handle_ = ::CreateEvent(nullptr,  // Security attributes.
-                                manual_reset, initially_signaled,
-                                nullptr);  // Name.
-  RTC_CHECK(event_handle_);
-}
-
-Event::~Event() {
-  CloseHandle(event_handle_);
-}
-
-void Event::Set() {
-  SetEvent(event_handle_);
-}
-
-void Event::Reset() {
-  ResetEvent(event_handle_);
-}
-
-bool Event::Wait(int milliseconds) {
-  DWORD ms = (milliseconds == kForever) ? INFINITE : milliseconds;
-  return (WaitForSingleObject(event_handle_, ms) == WAIT_OBJECT_0);
-}
-
-#elif defined(WEBRTC_POSIX)
+using base::WaitableEvent;
 
 Event::Event(bool manual_reset, bool initially_signaled)
-    : is_manual_reset_(manual_reset),
-      event_status_(initially_signaled) {
-  RTC_CHECK(pthread_mutex_init(&event_mutex_, nullptr) == 0);
-  RTC_CHECK(pthread_cond_init(&event_cond_, nullptr) == 0);
-}
+    : event_(manual_reset ? WaitableEvent::ResetPolicy::MANUAL
+                          : WaitableEvent::ResetPolicy::AUTOMATIC,
+             initially_signaled ? WaitableEvent::InitialState::SIGNALED
+                                : WaitableEvent::InitialState::NOT_SIGNALED) {}
 
-Event::~Event() {
-  pthread_mutex_destroy(&event_mutex_);
-  pthread_cond_destroy(&event_cond_);
-}
+Event::~Event() {}
 
 void Event::Set() {
-  pthread_mutex_lock(&event_mutex_);
-  event_status_ = true;
-  pthread_cond_broadcast(&event_cond_);
-  pthread_mutex_unlock(&event_mutex_);
+  event_.Signal();
 }
 
 void Event::Reset() {
-  pthread_mutex_lock(&event_mutex_);
-  event_status_ = false;
-  pthread_mutex_unlock(&event_mutex_);
+  event_.Reset();
 }
 
 bool Event::Wait(int milliseconds) {
-  int error = 0;
-
-  struct timespec ts;
-  if (milliseconds != kForever) {
-    // Converting from seconds and microseconds (1e-6) plus
-    // milliseconds (1e-3) to seconds and nanoseconds (1e-9).
-
-#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
-    // Use relative time version, which tends to be more efficient for
-    // pthread implementations where provided (like on Android).
-    ts.tv_sec = milliseconds / 1000;
-    ts.tv_nsec = (milliseconds % 1000) * 1000000;
-#else
-    struct timeval tv;
-    gettimeofday(&tv, nullptr);
-
-    ts.tv_sec = tv.tv_sec + (milliseconds / 1000);
-    ts.tv_nsec = tv.tv_usec * 1000 + (milliseconds % 1000) * 1000000;
-
-    // Handle overflow.
-    if (ts.tv_nsec >= 1000000000) {
-      ts.tv_sec++;
-      ts.tv_nsec -= 1000000000;
-    }
-#endif
+  if (milliseconds == kForever) {
+    event_.Wait();
+    return true;
   }
 
-  pthread_mutex_lock(&event_mutex_);
-  if (milliseconds != kForever) {
-    while (!event_status_ && error == 0) {
-#ifdef HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
-      error = pthread_cond_timedwait_relative_np(
-          &event_cond_, &event_mutex_, &ts);
-#else
-      error = pthread_cond_timedwait(&event_cond_, &event_mutex_, &ts);
-#endif
-    }
-  } else {
-    while (!event_status_ && error == 0)
-      error = pthread_cond_wait(&event_cond_, &event_mutex_);
-  }
-
-  // NOTE(liulk): Exactly one thread will auto-reset this event. All
-  // the other threads will think it's unsignaled.  This seems to be
-  // consistent with auto-reset events in WEBRTC_WIN
-  if (error == 0 && !is_manual_reset_)
-    event_status_ = false;
-
-  pthread_mutex_unlock(&event_mutex_);
-
-  return (error == 0);
+  return event_.TimedWait(base::TimeDelta::FromMilliseconds(milliseconds));
 }
 
-#endif
-
 }  // namespace rtc
diff --git a/third_party/webrtc_overrides/rtc_base/event.h b/third_party/webrtc_overrides/rtc_base/event.h
index aa8ec80..c474bcda 100644
--- a/third_party/webrtc_overrides/rtc_base/event.h
+++ b/third_party/webrtc_overrides/rtc_base/event.h
@@ -1,27 +1,16 @@
-/*
- *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
+// 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 RTC_BASE_EVENT_H_
-#define RTC_BASE_EVENT_H_
+#ifndef THIRD_PARTY_WEBRTC_OVERRIDES_RTC_BASE_EVENT_H_
+#define THIRD_PARTY_WEBRTC_OVERRIDES_RTC_BASE_EVENT_H_
 
-#include "third_party/webrtc/rtc_base/constructormagic.h"
-#if defined(WEBRTC_WIN)
-#include "third_party/webrtc/rtc_base/win32.h"  // NOLINT: system header.
-#elif defined(WEBRTC_POSIX)
-#include <pthread.h>
-#else
-#error "Must define either WEBRTC_WIN or WEBRTC_POSIX."
-#endif
+#include "base/macros.h"
+#include "base/synchronization/waitable_event.h"
 
 namespace rtc {
 
+// Overrides WebRTC's internal event implementation to use Chromium's.
 class Event {
  public:
   static const int kForever = -1;
@@ -37,18 +26,10 @@
   bool Wait(int milliseconds);
 
  private:
-#if defined(WEBRTC_WIN)
-  HANDLE event_handle_;
-#elif defined(WEBRTC_POSIX)
-  pthread_mutex_t event_mutex_;
-  pthread_cond_t event_cond_;
-  const bool is_manual_reset_;
-  bool event_status_;
-#endif
-
-  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Event);
+  base::WaitableEvent event_;
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Event);
 };
 
 }  // namespace rtc
 
-#endif  // RTC_BASE_EVENT_H_
+#endif  // THIRD_PARTY_WEBRTC_OVERRIDES_RTC_BASE_EVENT_H_
diff --git a/third_party/webrtc_overrides/rtc_base/gtest_prod_util.h b/third_party/webrtc_overrides/rtc_base/gtest_prod_util.h
new file mode 100644
index 0000000..d57937a
--- /dev/null
+++ b/third_party/webrtc_overrides/rtc_base/gtest_prod_util.h
@@ -0,0 +1,10 @@
+// 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 THIRD_PARTY_WEBRTC_OVERRIDES_RTC_BASE_GTEST_PROD_UTIL_H_
+#define THIRD_PARTY_WEBRTC_OVERRIDES_RTC_BASE_GTEST_PROD_UTIL_H_
+
+#include "base/gtest_prod_util.h"
+
+#endif  // THIRD_PARTY_WEBRTC_OVERRIDES_RTC_BASE_GTEST_PROD_UTIL_H_
diff --git a/third_party/widevine/cdm/BUILD.gn b/third_party/widevine/cdm/BUILD.gn
index f35d818..0ab3bb6 100644
--- a/third_party/widevine/cdm/BUILD.gn
+++ b/third_party/widevine/cdm/BUILD.gn
@@ -113,6 +113,10 @@
     if (is_posix && !is_mac) {
       cflags = [ "-fvisibility=hidden" ]
     }
+
+    if (is_mac) {
+      ldflags = [ "-Wl,-install_name,@loader_path/libwidevinecdm.dylib" ]
+    }
   }
 } else {
   group("widevinecdm") {
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn
index 2f19a8fe..65d4dda1 100644
--- a/third_party/zlib/BUILD.gn
+++ b/third_party/zlib/BUILD.gn
@@ -10,11 +10,6 @@
 
 config("zlib_config") {
   include_dirs = [ "." ]
-  if (current_cpu == "arm" || current_cpu == "arm64") {
-    if (arm_use_neon) {
-      include_dirs += [ "contrib/optimizations/arm" ]
-    }
-  }
 }
 
 config("zlib_adler32_simd_config") {
@@ -64,6 +59,57 @@
   public_configs = [ ":zlib_adler32_simd_config" ]
 }
 
+config("zlib_inflate_chunk_simd_config") {
+  if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    defines = [ "INFLATE_CHUNK_SIMD_SSE2" ]
+  }
+
+  if (current_cpu == "arm" || current_cpu == "arm64") {
+    if (arm_use_neon) {
+      defines = [ "INFLATE_CHUNK_SIMD_NEON" ]
+    }
+  }
+}
+
+source_set("zlib_inflate_chunk_simd") {
+  visibility = [ ":*" ]
+
+  if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    include_dirs = [ "." ]
+
+    sources = [
+      "contrib/optimizations/chunkcopy.h",
+      "contrib/optimizations/inffast_chunk.c",
+      "contrib/optimizations/inffast_chunk.h",
+      "contrib/optimizations/inflate.c",
+    ]
+  }
+
+  if (current_cpu == "arm" || current_cpu == "arm64") {
+    if (arm_use_neon) {
+      include_dirs = [ "." ]
+
+      sources = [
+        "contrib/optimizations/chunkcopy.h",
+        "contrib/optimizations/inffast_chunk.c",
+        "contrib/optimizations/inffast_chunk.h",
+        "contrib/optimizations/inflate.c",
+      ]
+
+      if (!is_debug) {
+        # Use optimize_speed (-O3) to output the _smallest_ code.
+        configs -= [ "//build/config/compiler:default_optimization" ]
+        configs += [ "//build/config/compiler:optimize_speed" ]
+      }
+    }
+  }
+
+  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs += [ "//build/config/compiler:no_chromium_code" ]
+
+  public_configs = [ ":zlib_inflate_chunk_simd_config" ]
+}
+
 static_library("zlib_x86_simd") {
   if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
     sources = [
@@ -129,31 +175,23 @@
     "zutil.h",
   ]
 
-  if (current_cpu == "arm" || current_cpu == "arm64") {
-    if (arm_use_neon) {
-      sources -= [ "inflate.c" ]
-      sources += [
-        "contrib/optimizations/arm/chunkcopy_arm.h",
-        "contrib/optimizations/chunkcopy.h",
-        "contrib/optimizations/inffast_chunky.c",
-        "contrib/optimizations/inffast_chunky.h",
-        "contrib/optimizations/inflate.c",
-      ]
-    }
-  }
-
   defines = []
   deps = []
 
   if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    deps += [ ":zlib_adler32_simd" ]
     sources += [ "x86.c" ]
 
-    deps += [ ":zlib_adler32_simd" ]
+    deps += [ ":zlib_inflate_chunk_simd" ]
+    sources -= [ "inflate.c" ]
   }
 
   if (current_cpu == "arm" || current_cpu == "arm64") {
     if (arm_use_neon) {
       deps += [ ":zlib_adler32_simd" ]
+
+      deps += [ ":zlib_inflate_chunk_simd" ]
+      sources -= [ "inflate.c" ]
     }
   }
 
diff --git a/third_party/zlib/contrib/optimizations/arm/chunkcopy_arm.h b/third_party/zlib/contrib/optimizations/arm/chunkcopy_arm.h
deleted file mode 100644
index 41474c8a..0000000
--- a/third_party/zlib/contrib/optimizations/arm/chunkcopy_arm.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* chunkcopy_arm.h -- fast copies and sets
- * Copyright (C) 2017 ARM, Inc.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#ifndef CHUNKCOPY_ARM_H
-#define CHUNKCOPY_ARM_H
-
-#include <arm_neon.h>
-#include "zutil.h"
-
-#if __STDC_VERSION__ >= 199901L
-#define Z_RESTRICT restrict
-#else
-#define Z_RESTRICT
-#endif
-
-/* A port to a new arch only requires to implement 2 functions
-  (vld_dup and chunkset_core) and the chunk type.
-*/
-
-typedef uint8x16_t chunkcopy_chunk_t;
-#define CHUNKCOPY_CHUNK_SIZE sizeof(chunkcopy_chunk_t)
-
-/* Forward declarations. */
-static inline unsigned char FAR* chunkunroll_relaxed(unsigned char FAR* out,
-                                                     unsigned FAR* dist,
-                                                     unsigned FAR* len);
-
-static inline unsigned char FAR* chunkcopy_core(unsigned char FAR* out,
-                                                const unsigned char FAR* from,
-                                                unsigned len);
-
-/* Architecture specific code starts here. */
-static inline uint8x16_t chunkset_vld1q_dup_u8x8(
-    const unsigned char FAR* Z_RESTRICT from) {
-#if defined(__clang__) || defined(__aarch64__)
-  return vreinterpretq_u8_u64(vld1q_dup_u64((void*)from));
-#else
-  /* 32-bit GCC uses an alignment hint for vld1q_dup_u64, even when given a
-   * void pointer, so here's an alternate implementation.
-   */
-  uint8x8_t h = vld1_u8(from);
-  return vcombine_u8(h, h);
-#endif
-}
-
-/*
-   Perform an overlapping copy which behaves as a memset() operation, but
-   supporting periods other than one, and assume that length is non-zero and
-   that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE*3 bytes of output
-   even if the length is shorter than this.
-   TODO(cavalcantii): maybe rename vreinterpretq and chunkset_vld to make it
-                      generic and move this code to chunkcopy.h (plus we
-                      won't need the forward declarations).
- */
-static inline unsigned char FAR* chunkset_core(unsigned char FAR* out,
-                                               unsigned period,
-                                               unsigned len) {
-  uint8x16_t f;
-  int bump = ((len - 1) % sizeof(f)) + 1;
-
-  switch (period) {
-    case 1:
-      f = vld1q_dup_u8(out - 1);
-      vst1q_u8(out, f);
-      out += bump;
-      len -= bump;
-      while (len > 0) {
-        vst1q_u8(out, f);
-        out += sizeof(f);
-        len -= sizeof(f);
-      }
-      return out;
-    case 2:
-      f = vreinterpretq_u8_u16(vld1q_dup_u16((void*)(out - 2)));
-      vst1q_u8(out, f);
-      out += bump;
-      len -= bump;
-      if (len > 0) {
-        f = vreinterpretq_u8_u16(vld1q_dup_u16((void*)(out - 2)));
-        do {
-          vst1q_u8(out, f);
-          out += sizeof(f);
-          len -= sizeof(f);
-        } while (len > 0);
-      }
-      return out;
-    case 4:
-      f = vreinterpretq_u8_u32(vld1q_dup_u32((void*)(out - 4)));
-      vst1q_u8(out, f);
-      out += bump;
-      len -= bump;
-      if (len > 0) {
-        f = vreinterpretq_u8_u32(vld1q_dup_u32((void*)(out - 4)));
-        do {
-          vst1q_u8(out, f);
-          out += sizeof(f);
-          len -= sizeof(f);
-        } while (len > 0);
-      }
-      return out;
-    case 8:
-      f = chunkset_vld1q_dup_u8x8(out - 8);
-      vst1q_u8(out, f);
-      out += bump;
-      len -= bump;
-      if (len > 0) {
-        f = chunkset_vld1q_dup_u8x8(out - 8);
-        do {
-          vst1q_u8(out, f);
-          out += sizeof(f);
-          len -= sizeof(f);
-        } while (len > 0);
-      }
-      return out;
-  }
-  out = chunkunroll_relaxed(out, &period, &len);
-  return chunkcopy_core(out, out - period, len);
-}
-
-#endif /* CHUNKCOPY_ARM_H */
diff --git a/third_party/zlib/contrib/optimizations/chunkcopy.h b/third_party/zlib/contrib/optimizations/chunkcopy.h
index 2080643..2988fb0 100644
--- a/third_party/zlib/contrib/optimizations/chunkcopy.h
+++ b/third_party/zlib/contrib/optimizations/chunkcopy.h
@@ -1,50 +1,90 @@
-/* chunkcopy.h -- fast copies and sets
+/* chunkcopy.h -- fast chunk copy and set operations
  * Copyright (C) 2017 ARM, Inc.
+ * 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 Chromium source repository LICENSE file.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 #ifndef CHUNKCOPY_H
 #define CHUNKCOPY_H
 
-// TODO(cavalcantii): add the Intel code next.
-#include "chunkcopy_arm.h"
+#include <stdint.h>
+#include "zutil.h"
+
+#define Z_STATIC_ASSERT(name, assert) typedef char name[(assert) ? 1 : -1]
+
+#if __STDC_VERSION__ >= 199901L
+#define Z_RESTRICT restrict
+#else
+#define Z_RESTRICT
+#endif
+
+#if defined(__clang__) || defined(__GNUC__) || defined(__llvm__)
+#define Z_BUILTIN_MEMCPY __builtin_memcpy
+#else
+#define Z_BUILTIN_MEMCPY zmemcpy
+#endif
+
+#if defined(INFLATE_CHUNK_SIMD_NEON)
+#include <arm_neon.h>
+typedef uint8x16_t z_vec128i_t;
+#elif defined(INFLATE_CHUNK_SIMD_SSE2)
+#include <emmintrin.h>
+typedef __m128i z_vec128i_t;
+#else
+#error chunkcopy.h inflate chunk SIMD is not defined for your build target
+#endif
 
 /*
-   Ask the compiler to perform a wide, unaligned load with an machine
-   instruction appropriate for the chunkcopy_chunk_t type.
+ * chunk copy type: the z_vec128i_t type size should be exactly 128-bits
+ * and equal to CHUNKCOPY_CHUNK_SIZE.
  */
-static inline chunkcopy_chunk_t loadchunk(const unsigned char FAR* s) {
-  chunkcopy_chunk_t c;
-  __builtin_memcpy(&c, s, sizeof(c));
-  return c;
+#define CHUNKCOPY_CHUNK_SIZE sizeof(z_vec128i_t)
+
+Z_STATIC_ASSERT(vector_128_bits_wide,
+                CHUNKCOPY_CHUNK_SIZE == sizeof(int8_t) * 16);
+
+/*
+ * Ask the compiler to perform a wide, unaligned load with a machine
+ * instruction appropriate for the z_vec128i_t type.
+ */
+static inline z_vec128i_t loadchunk(
+    const unsigned char FAR* s) {
+  z_vec128i_t v;
+  Z_BUILTIN_MEMCPY(&v, s, sizeof(v));
+  return v;
 }
 
 /*
-   Ask the compiler to perform a wide, unaligned store with an machine
-   instruction appropriate for the chunkcopy_chunk_t type.
+ * Ask the compiler to perform a wide, unaligned store with a machine
+ * instruction appropriate for the z_vec128i_t type.
  */
-static inline void storechunk(unsigned char FAR* d, chunkcopy_chunk_t c) {
-  __builtin_memcpy(d, &c, sizeof(c));
+static inline void storechunk(
+    unsigned char FAR* d,
+    const z_vec128i_t v) {
+  Z_BUILTIN_MEMCPY(d, &v, sizeof(v));
 }
 
 /*
-   Perform a memcpy-like operation, but assume that length is non-zero and that
-   it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if
-   the length is shorter than this.
-
-   It also guarantees that it will properly unroll the data if the distance
-   between `out` and `from` is at least CHUNKCOPY_CHUNK_SIZE, which we rely on
-   in chunkcopy_relaxed().
-
-   Aside from better memory bus utilisation, this means that short copies
-   (CHUNKCOPY_CHUNK_SIZE bytes or fewer) will fall straight through the loop
-   without iteration, which will hopefully make the branch prediction more
-   reliable.
+ * Perform a memcpy-like operation, assuming that length is non-zero and that
+ * it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if
+ * the length is shorter than this.
+ *
+ * It also guarantees that it will properly unroll the data if the distance
+ * between `out` and `from` is at least CHUNKCOPY_CHUNK_SIZE, which we rely on
+ * in chunkcopy_relaxed().
+ *
+ * Aside from better memory bus utilisation, this means that short copies
+ * (CHUNKCOPY_CHUNK_SIZE bytes or fewer) will fall straight through the loop
+ * without iteration, which will hopefully make the branch prediction more
+ * reliable.
  */
-static inline unsigned char FAR* chunkcopy_core(unsigned char FAR* out,
-                                                const unsigned char FAR* from,
-                                                unsigned len) {
-  int bump = (--len % CHUNKCOPY_CHUNK_SIZE) + 1;
+static inline unsigned char FAR* chunkcopy_core(
+    unsigned char FAR* out,
+    const unsigned char FAR* from,
+    unsigned len) {
+  const int bump = (--len % CHUNKCOPY_CHUNK_SIZE) + 1;
   storechunk(out, loadchunk(from));
   out += bump;
   from += bump;
@@ -58,12 +98,12 @@
 }
 
 /*
-   Like chunkcopy_core, but avoid writing beyond of legal output.
-
-   Accepts an additional pointer to the end of safe output.  A generic safe
-   copy would use (out + len), but it's normally the case that the end of the
-   output buffer is beyond the end of the current copy, and this can still be
-   exploited.
+ * Like chunkcopy_core(), but avoid writing beyond of legal output.
+ *
+ * Accepts an additional pointer to the end of safe output.  A generic safe
+ * copy would use (out + len), but it's normally the case that the end of the
+ * output buffer is beyond the end of the current copy, and this can still be
+ * exploited.
  */
 static inline unsigned char FAR* chunkcopy_core_safe(
     unsigned char FAR* out,
@@ -74,17 +114,17 @@
   if (limit - out < CHUNKCOPY_CHUNK_SIZE) {
     const unsigned char FAR* Z_RESTRICT rfrom = from;
     if (len & 8) {
-      __builtin_memcpy(out, rfrom, 8);
+      Z_BUILTIN_MEMCPY(out, rfrom, 8);
       out += 8;
       rfrom += 8;
     }
     if (len & 4) {
-      __builtin_memcpy(out, rfrom, 4);
+      Z_BUILTIN_MEMCPY(out, rfrom, 4);
       out += 4;
       rfrom += 4;
     }
     if (len & 2) {
-      __builtin_memcpy(out, rfrom, 2);
+      Z_BUILTIN_MEMCPY(out, rfrom, 2);
       out += 2;
       rfrom += 2;
     }
@@ -97,18 +137,19 @@
 }
 
 /*
-   Perform short copies until distance can be rewritten as being at least
-   CHUNKCOPY_CHUNK_SIZE.
-
-   This assumes that it's OK to overwrite at least the first
-   2*CHUNKCOPY_CHUNK_SIZE bytes of output even if the copy is shorter than
-   this.  This assumption holds within inflate_fast() which starts every
-   iteration with at least 258 bytes of output space available (258 being the
-   maximum length output from a single token; see inffast.c).
+ * Perform short copies until distance can be rewritten as being at least
+ * CHUNKCOPY_CHUNK_SIZE.
+ *
+ * Assumes it's OK to overwrite at least the first 2*CHUNKCOPY_CHUNK_SIZE
+ * bytes of output even if the copy is shorter than this.  This assumption
+ * holds within zlib inflate_fast(), which starts every iteration with at
+ * least 258 bytes of output space available (258 being the maximum length
+ * output from a single token; see inffast.c).
  */
-static inline unsigned char FAR* chunkunroll_relaxed(unsigned char FAR* out,
-                                                     unsigned FAR* dist,
-                                                     unsigned FAR* len) {
+static inline unsigned char FAR* chunkunroll_relaxed(
+    unsigned char FAR* out,
+    unsigned FAR* dist,
+    unsigned FAR* len) {
   const unsigned char FAR* from = out - *dist;
   while (*dist < *len && *dist < CHUNKCOPY_CHUNK_SIZE) {
     storechunk(out, loadchunk(from));
@@ -119,15 +160,180 @@
   return out;
 }
 
+#if defined(INFLATE_CHUNK_SIMD_NEON)
 /*
-   Perform a memcpy-like operation, but assume that length is non-zero and that
-   it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if
-   the length is shorter than this.
+ * v_load64_dup(): load *src as an unaligned 64-bit int and duplicate it in
+ * every 64-bit component of the 128-bit result (64-bit int splat).
+ */
+static inline z_vec128i_t v_load64_dup(const void* src) {
+  return vcombine_u8(vld1_u8(src), vld1_u8(src));
+}
 
-   Unlike chunkcopy_core() above, no guarantee is made regarding the behaviour
-   of overlapping buffers, regardless of the distance between the pointers.
-   This is reflected in the `restrict`-qualified pointers, allowing the
-   compiler to reorder loads and stores.
+/*
+ * v_load32_dup(): load *src as an unaligned 32-bit int and duplicate it in
+ * every 32-bit component of the 128-bit result (32-bit int splat).
+ */
+static inline z_vec128i_t v_load32_dup(const void* src) {
+  int32_t i32;
+  Z_BUILTIN_MEMCPY(&i32, src, sizeof(i32));
+  return vreinterpretq_u8_s32(vdupq_n_s32(i32));
+}
+
+/*
+ * v_load16_dup(): load *src as an unaligned 16-bit int and duplicate it in
+ * every 16-bit component of the 128-bit result (16-bit int splat).
+ */
+static inline z_vec128i_t v_load16_dup(const void* src) {
+  int16_t i16;
+  Z_BUILTIN_MEMCPY(&i16, src, sizeof(i16));
+  return vreinterpretq_u8_s16(vdupq_n_s16(i16));
+}
+
+/*
+ * v_load8_dup(): load the 8-bit int *src and duplicate it in every 8-bit
+ * component of the 128-bit result (8-bit int splat).
+ */
+static inline z_vec128i_t v_load8_dup(const void* src) {
+  return vld1q_dup_u8((const uint8_t*)src);
+}
+
+/*
+ * v_store_128(): store the 128-bit vec in a memory destination (that might
+ * not be 16-byte aligned) void* out.
+ */
+static inline void v_store_128(void* out, const z_vec128i_t vec) {
+  vst1q_u8(out, vec);
+}
+
+#elif defined(INFLATE_CHUNK_SIMD_SSE2)
+/*
+ * v_load64_dup(): load *src as an unaligned 64-bit int and duplicate it in
+ * every 64-bit component of the 128-bit result (64-bit int splat).
+ */
+static inline z_vec128i_t v_load64_dup(const void* src) {
+  int64_t i64;
+  Z_BUILTIN_MEMCPY(&i64, src, sizeof(i64));
+  return _mm_set1_epi64x(i64);
+}
+
+/*
+ * v_load32_dup(): load *src as an unaligned 32-bit int and duplicate it in
+ * every 32-bit component of the 128-bit result (32-bit int splat).
+ */
+static inline z_vec128i_t v_load32_dup(const void* src) {
+  int32_t i32;
+  Z_BUILTIN_MEMCPY(&i32, src, sizeof(i32));
+  return _mm_set1_epi32(i32);
+}
+
+/*
+ * v_load16_dup(): load *src as an unaligned 16-bit int and duplicate it in
+ * every 16-bit component of the 128-bit result (16-bit int splat).
+ */
+static inline z_vec128i_t v_load16_dup(const void* src) {
+  int16_t i16;
+  Z_BUILTIN_MEMCPY(&i16, src, sizeof(i16));
+  return _mm_set1_epi16(i16);
+}
+
+/*
+ * v_load8_dup(): load the 8-bit int *src and duplicate it in every 8-bit
+ * component of the 128-bit result (8-bit int splat).
+ */
+static inline z_vec128i_t v_load8_dup(const void* src) {
+  return _mm_set1_epi8(*(const char*)src);
+}
+
+/*
+ * v_store_128(): store the 128-bit vec in a memory destination (that might
+ * not be 16-byte aligned) void* out.
+ */
+static inline void v_store_128(void* out, const z_vec128i_t vec) {
+  _mm_storeu_si128((__m128i*)out, vec);
+}
+#endif
+
+/*
+ * Perform an overlapping copy which behaves as a memset() operation, but
+ * supporting periods other than one, and assume that length is non-zero and
+ * that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE*3 bytes of output
+ * even if the length is shorter than this.
+ */
+static inline unsigned char FAR* chunkset_core(
+    unsigned char FAR* out,
+    unsigned period,
+    unsigned len) {
+  z_vec128i_t v;
+  const int bump = ((len - 1) % sizeof(v)) + 1;
+
+  switch (period) {
+    case 1:
+      v = v_load8_dup(out - 1);
+      v_store_128(out, v);
+      out += bump;
+      len -= bump;
+      while (len > 0) {
+        v_store_128(out, v);
+        out += sizeof(v);
+        len -= sizeof(v);
+      }
+      return out;
+    case 2:
+      v = v_load16_dup(out - 2);
+      v_store_128(out, v);
+      out += bump;
+      len -= bump;
+      if (len > 0) {
+        v = v_load16_dup(out - 2);
+        do {
+          v_store_128(out, v);
+          out += sizeof(v);
+          len -= sizeof(v);
+        } while (len > 0);
+      }
+      return out;
+    case 4:
+      v = v_load32_dup(out - 4);
+      v_store_128(out, v);
+      out += bump;
+      len -= bump;
+      if (len > 0) {
+        v = v_load32_dup(out - 4);
+        do {
+          v_store_128(out, v);
+          out += sizeof(v);
+          len -= sizeof(v);
+        } while (len > 0);
+      }
+      return out;
+    case 8:
+      v = v_load64_dup(out - 8);
+      v_store_128(out, v);
+      out += bump;
+      len -= bump;
+      if (len > 0) {
+        v = v_load64_dup(out - 8);
+        do {
+          v_store_128(out, v);
+          out += sizeof(v);
+          len -= sizeof(v);
+        } while (len > 0);
+      }
+      return out;
+  }
+  out = chunkunroll_relaxed(out, &period, &len);
+  return chunkcopy_core(out, out - period, len);
+}
+
+/*
+ * Perform a memcpy-like operation, but assume that length is non-zero and that
+ * it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if
+ * the length is shorter than this.
+ *
+ * Unlike chunkcopy_core() above, no guarantee is made regarding the behaviour
+ * of overlapping buffers, regardless of the distance between the pointers.
+ * This is reflected in the `restrict`-qualified pointers, allowing the
+ * compiler to re-order loads and stores.
  */
 static inline unsigned char FAR* chunkcopy_relaxed(
     unsigned char FAR* Z_RESTRICT out,
@@ -137,17 +343,17 @@
 }
 
 /*
-   Like chunkcopy_relaxed, but avoid writing beyond of legal output.
-
-   Unlike chunkcopy_core_safe() above, no guarantee is made regarding the
-   behaviour of overlapping buffers, regardless of the distance between the
-   pointers.  This is reflected in the `restrict`-qualified pointers, allowing
-   the compiler to reorder loads and stores.
-
-   Accepts an additional pointer to the end of safe output.  A generic safe
-   copy would use (out + len), but it's normally the case that the end of the
-   output buffer is beyond the end of the current copy, and this can still be
-   exploited.
+ * Like chunkcopy_relaxed(), but avoid writing beyond of legal output.
+ *
+ * Unlike chunkcopy_core_safe() above, no guarantee is made regarding the
+ * behaviour of overlapping buffers, regardless of the distance between the
+ * pointers.  This is reflected in the `restrict`-qualified pointers, allowing
+ * the compiler to re-order loads and stores.
+ *
+ * Accepts an additional pointer to the end of safe output.  A generic safe
+ * copy would use (out + len), but it's normally the case that the end of the
+ * output buffer is beyond the end of the current copy, and this can still be
+ * exploited.
  */
 static inline unsigned char FAR* chunkcopy_safe(
     unsigned char FAR* out,
@@ -159,14 +365,16 @@
 }
 
 /*
-   Perform chunky copy within the same buffer, where the source and destination
-   may potentially overlap.
-
-   Assumes that len > 0 on entry, and that it's safe to write at least
-   CHUNKCOPY_CHUNK_SIZE*3 bytes to the output.
+ * Perform chunky copy within the same buffer, where the source and destination
+ * may potentially overlap.
+ *
+ * Assumes that len > 0 on entry, and that it's safe to write at least
+ * CHUNKCOPY_CHUNK_SIZE*3 bytes to the output.
  */
-static inline unsigned char FAR*
-chunkcopy_lapped_relaxed(unsigned char FAR* out, unsigned dist, unsigned len) {
+static inline unsigned char FAR* chunkcopy_lapped_relaxed(
+    unsigned char FAR* out,
+    unsigned dist,
+    unsigned len) {
   if (dist < len && dist < CHUNKCOPY_CHUNK_SIZE) {
     return chunkset_core(out, dist, len);
   }
@@ -174,13 +382,13 @@
 }
 
 /*
-   Behave like chunkcopy_lapped_relaxed, but avoid writing beyond of legal
-   output.
-
-   Accepts an additional pointer to the end of safe output.  A generic safe
-   copy would use (out + len), but it's normally the case that the end of the
-   output buffer is beyond the end of the current copy, and this can still be
-   exploited.
+ * Behave like chunkcopy_lapped_relaxed(), but avoid writing beyond of legal
+ * output.
+ *
+ * Accepts an additional pointer to the end of safe output.  A generic safe
+ * copy would use (out + len), but it's normally the case that the end of the
+ * output buffer is beyond the end of the current copy, and this can still be
+ * exploited.
  */
 static inline unsigned char FAR* chunkcopy_lapped_safe(
     unsigned char FAR* out,
@@ -199,6 +407,8 @@
   return chunkcopy_lapped_relaxed(out, dist, len);
 }
 
+#undef Z_STATIC_ASSERT
 #undef Z_RESTRICT
+#undef Z_BUILTIN_MEMCPY
 
 #endif /* CHUNKCOPY_H */
diff --git a/third_party/zlib/contrib/optimizations/inffast_chunky.c b/third_party/zlib/contrib/optimizations/inffast_chunk.c
similarity index 98%
rename from third_party/zlib/contrib/optimizations/inffast_chunky.c
rename to third_party/zlib/contrib/optimizations/inffast_chunk.c
index e2bc735..4829d0d 100644
--- a/third_party/zlib/contrib/optimizations/inffast_chunky.c
+++ b/third_party/zlib/contrib/optimizations/inffast_chunk.c
@@ -6,7 +6,7 @@
 #include "zutil.h"
 #include "inftrees.h"
 #include "inflate.h"
-#include "contrib/optimizations/inffast_chunky.h"
+#include "contrib/optimizations/inffast_chunk.h"
 #include "contrib/optimizations/chunkcopy.h"
 
 #ifdef ASMINF
@@ -52,7 +52,7 @@
       requires strm->avail_out >= 258 for each loop to avoid checking for
       output space.
  */
-void ZLIB_INTERNAL inflate_fast_chunky(strm, start)
+void ZLIB_INTERNAL inflate_fast_chunk_(strm, start)
 z_streamp strm;
 unsigned start;         /* inflate()'s starting value for strm->avail_out */
 {
diff --git a/third_party/zlib/contrib/optimizations/inffast_chunky.h b/third_party/zlib/contrib/optimizations/inffast_chunk.h
similarity index 65%
rename from third_party/zlib/contrib/optimizations/inffast_chunky.h
rename to third_party/zlib/contrib/optimizations/inffast_chunk.h
index 7f033f2c..80636e75 100644
--- a/third_party/zlib/contrib/optimizations/inffast_chunky.h
+++ b/third_party/zlib/contrib/optimizations/inffast_chunk.h
@@ -9,4 +9,7 @@
    subject to change. Applications should only use zlib.h.
  */
 
-void ZLIB_INTERNAL inflate_fast_chunky OF((z_streamp strm, unsigned start));
+// TODO(cblume): incorporate the patch done on crbug.com/764431 here and
+// in related files to define and use INFLATE_FAST_MIN_HAVE/_LEFT etc.
+
+void ZLIB_INTERNAL inflate_fast_chunk_ OF((z_streamp strm, unsigned start));
diff --git a/third_party/zlib/contrib/optimizations/inflate.c b/third_party/zlib/contrib/optimizations/inflate.c
index 152f1742..d6c5614c 100644
--- a/third_party/zlib/contrib/optimizations/inflate.c
+++ b/third_party/zlib/contrib/optimizations/inflate.c
@@ -83,8 +83,9 @@
 #include "zutil.h"
 #include "inftrees.h"
 #include "inflate.h"
-#include "contrib/optimizations/inffast_chunky.h"
+#include "contrib/optimizations/inffast_chunk.h"
 #include "contrib/optimizations/chunkcopy.h"
+#include "x86.h"
 
 #ifdef MAKEFIXED
 #  ifndef BUILDFIXED
@@ -202,6 +203,8 @@
     int ret;
     struct inflate_state FAR *state;
 
+    x86_check_features();
+
     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
         stream_size != (int)(sizeof(z_stream)))
         return Z_VERSION_ERROR;
@@ -419,7 +422,7 @@
            and is subsequently either overwritten or left deliberately
            undefined at the end of decode; so there's really no point.
          */
-        memset(state->window + wsize, 0, CHUNKCOPY_CHUNK_SIZE);
+        zmemzero(state->window + wsize, CHUNKCOPY_CHUNK_SIZE);
 #endif
     }
 
@@ -1056,7 +1059,7 @@
         case LEN:
             if (have >= 6 && left >= 258) {
                 RESTORE();
-                inflate_fast_chunky(strm, out);
+                inflate_fast_chunk_(strm, out);
                 LOAD();
                 if (state->mode == TYPE)
                     state->back = -1;
diff --git a/third_party/zlib/names.h b/third_party/zlib/names.h
index cd98ec9..c18b90f 100644
--- a/third_party/zlib/names.h
+++ b/third_party/zlib/names.h
@@ -171,4 +171,9 @@
 #define adler32_simd_ Cr_z_adler32_simd_
 #endif
 
+#if defined(INFLATE_CHUNK_SIMD_SSE2) || defined(INFLATE_CHUNK_SIMD_NEON)
+/* Symbols added by contrib/optimizations/inffast_chunk */
+#define inflate_fast_chunk_ Cr_z_inflate_fast_chunk_
+#endif
+
 #endif  /* THIRD_PARTY_ZLIB_NAMES_H_ */
diff --git a/tools/android/native_lib_memory/process_residency.py b/tools/android/native_lib_memory/process_residency.py
index 7c188fa..51d3d81 100755
--- a/tools/android/native_lib_memory/process_residency.py
+++ b/tools/android/native_lib_memory/process_residency.py
@@ -84,16 +84,19 @@
     data: (dict) As returned by ParseDump().
     output_filename: (str) Output filename.
   """
+  residency = data['residency']
+  max_percentage = max((100. * sum(d)) / len(d) for d in residency.values())
+  logging.info('Max residency = %.2f%%', max_percentage)
+
   start = data['start']
   end = data['end']
-  data = data['residency']
   fig, ax = plt.subplots(figsize=(20, 10))
-  timestamps = sorted(data.keys())
-  x_max = len(data.values()[0]) * 4096
+  timestamps = sorted(residency.keys())
+  x_max = len(residency.values()[0]) * 4096
   for t in timestamps:
     offset_ms = (t - timestamps[0]) / 1e6
-    incore = [i * 4096 for (i, x) in enumerate(data[t]) if x]
-    outcore = [i * 4096 for (i, x) in enumerate(data[t]) if not x]
+    incore = [i * 4096 for (i, x) in enumerate(residency[t]) if x]
+    outcore = [i * 4096 for (i, x) in enumerate(residency[t]) if not x]
     percentage = 100. * len(incore) / (len(incore) + len(outcore))
     plt.text(x_max, offset_ms, '%.1f%%' % percentage)
     for (d, color) in ((incore, (.2, .6, .05, 1)), (outcore, (1, 0, 0, 1))):
diff --git a/tools/chrome_proxy/webdriver/cross_origin_push.py b/tools/chrome_proxy/webdriver/cross_origin_push.py
index 8ac614d2..c36adb6 100644
--- a/tools/chrome_proxy/webdriver/cross_origin_push.py
+++ b/tools/chrome_proxy/webdriver/cross_origin_push.py
@@ -11,9 +11,8 @@
 
 class CrossOriginPush(IntegrationTest):
   # Ensure cross origin push from trusted proxy server is adopted by Chromium.
-  # Disabled on android because the net log is not copied yet. crbug.com/761507
   @ChromeVersionEqualOrAfterM(62)
-  def testClientConfigVariationsHeader(self):
+  def testCrossOriginPush(self):
     with TestDriver() as t:
       t.UseNetLog()
       t.AddChromeArg('--enable-spdy-proxy-auth')
diff --git a/tools/chrome_proxy/webdriver/lite_page.py b/tools/chrome_proxy/webdriver/lite_page.py
index 936789b..a39e158 100644
--- a/tools/chrome_proxy/webdriver/lite_page.py
+++ b/tools/chrome_proxy/webdriver/lite_page.py
@@ -184,6 +184,54 @@
         self.assertHasChromeProxyViaHeader(response)
         self.assertIn(response.status, [200, 204])
 
+  # Checks that a Nano Lite Page does not have an error when scrolling to the
+  # bottom of the page and is able to load all resources.
+  @ChromeVersionEqualOrAfterM(65)
+  def testLitePageBTFNano(self):
+    # If it was attempted to run with another experiment, skip this test.
+    if common.ParseFlags().browser_args and ('--data-reduction-proxy-experiment'
+        in common.ParseFlags().browser_args):
+      self.skipTest('This test cannot be run with other experiments.')
+    with TestDriver() as test_driver:
+      test_driver.AddChromeArg('--enable-spdy-proxy-auth')
+      # Need to force 2G speed to get lite-page response.
+      test_driver.AddChromeArg('--force-effective-connection-type=2G')
+      # Set exp=alt2 to force Nano response.
+      test_driver.AddChromeArg('--data-reduction-proxy-experiment=alt2')
+
+      # This page is long and has many media resources.
+      test_driver.LoadURL('http://check.googlezip.net/metrics/index.html')
+
+      # Verify that a Lite Page response for the main frame was seen.
+      lite_page_responses = 0
+      for response in test_driver.GetHTTPResponses():
+        # Check main frame for Lite Page response.
+        if response.url.endswith('html'):
+          if (self.checkLitePageResponse(response)):
+             lite_page_responses = lite_page_responses + 1
+      self.assertEqual(1, lite_page_responses)
+
+      # Scroll to the bottom of the window and ensure scrollHeight increases.
+      original_scroll_height = test_driver.ExecuteJavascriptStatement(
+        'document.body.scrollHeight')
+      test_driver.ExecuteJavascriptStatement(
+        'window.scrollTo(0,Math.max(document.body.scrollHeight));')
+      # Give some time for loading after scrolling.
+      time.sleep(2)
+      new_scroll_height = test_driver.ExecuteJavascriptStatement(
+        'document.body.scrollHeight')
+      self.assertGreater(new_scroll_height, original_scroll_height)
+
+      # Make sure there were more requests that were proxied.
+      responses = test_driver.GetHTTPResponses(override_has_logs=True)
+      self.assertNotEqual(0, len(responses))
+      for response in responses:
+        if 'content-type' in response.response_headers and ('video/mp4' in
+            response.response_headers['content-type']):
+          continue
+        self.assertHasChromeProxyViaHeader(response)
+        self.assertIn(response.status, [200, 204, 304])
+
   # Lo-Fi fallback is not supported without the
   # DataReductionProxyDecidesTransform feature. Check that no Lo-Fi response
   # is received if a Lite Page is not served.
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py
index 23124cb..3b97955 100755
--- a/tools/code_coverage/coverage.py
+++ b/tools/code_coverage/coverage.py
@@ -7,35 +7,38 @@
   It uses Clang Source-based Code Coverage -
   https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
 
-  In order to generate code coverage report, you need to first build the target
-  program with "use_clang_coverage=true" GN flag.
+  In order to generate code coverage report, you need to first add
+  "use_clang_coverage=true" GN flag to args.gn file in your build
+  output directory (e.g. out/coverage).
 
-  It is recommended to set "is_component_build=false" flag explicitly in GN
-  configuration because:
+  It is recommended to add "is_component_build=false" flag as well because:
   1. It is incompatible with other sanitizer flags (like "is_asan", "is_msan")
      and others like "optimize_for_fuzzing".
   2. If it is not set explicitly, "is_debug" overrides it to true.
 
   Example usage:
 
+  gn gen out/coverage --args='use_clang_coverage=true is_component_build=false'
+  gclient runhooks
   python tools/code_coverage/coverage.py crypto_unittests url_unittests \\
-    -b out/coverage -o out/report -c 'out/coverage/crypto_unittests' \\
-    -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \\
-    -f url/ -f crypto/
+      -b out/coverage -o out/report -c 'out/coverage/crypto_unittests' \\
+      -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \\
+      -f url/ -f crypto/
 
-  The command above generates code coverage report for crypto_unittests and
-  url_unittests with only files under url/ and crypto/ directories are included
-  in the report, and all generated artifacts are stored in out/report.
-  For url_unittests, it only runs the test URLParser.PathURL.
+  The command above builds crypto_unittests and url_unittests targets and then
+  runs them with specified command line arguments. For url_unittests, it only
+  runs the test URLParser.PathURL. The coverage report is filtered to include
+  only files and sub-directories under url/ and crypto/ directories.
 
   If you are building a fuzz target, you need to add "use_libfuzzer=true" GN
   flag as well.
 
   Sample workflow for a fuzz target (e.g. pdfium_fuzzer):
 
-  python tools/code_coverage/coverage.py \\
-    -b out/coverage -o out/report \\
-    -c 'out/coverage/pdfium_fuzzer -runs=<runs> <corpus_dir>'
+  python tools/code_coverage/coverage.py pdfium_fuzzer \\
+      -b out/coverage -o out/report \\
+      -c 'out/coverage/pdfium_fuzzer -runs=<runs> <corpus_dir>' \\
+      -f third_party/pdfium
 
   where:
     <corpus_dir> - directory containing samples files for this format.
@@ -151,7 +154,11 @@
   coverage_revision, coverage_sub_revision = _GetRevisionFromStampFile(
       coverage_revision_stamp_file, platform)
 
-  if (coverage_revision == clang_revision and
+  has_coverage_tools = (os.path.exists(LLVM_COV_PATH) and
+                        os.path.exists(LLVM_PROFDATA_PATH))
+
+  if (has_coverage_tools and
+      coverage_revision == clang_revision and
       coverage_sub_revision == clang_sub_revision):
     # LLVM coverage tools are up to date, bail out.
     return clang_revision
@@ -192,7 +199,8 @@
     profdata_file_path: A path to the profdata file.
     filters: A list of directories and files to get coverage for.
   """
-  print('Generating per file line by line code coverage in html')
+  print('Generating per file line-by-line code coverage in html '
+        '(this can take a while depending on size of target!)')
 
   # llvm-cov show [options] -instr-profile PROFILE BIN [-object BIN,...]
   # [[-object BIN]] [SOURCES]
@@ -353,6 +361,7 @@
   print('Creating the profile data file')
 
   profdata_file_path = os.path.join(OUTPUT_DIR, PROFDATA_FILE_NAME)
+
   try:
     subprocess_cmd = [
         LLVM_PROFDATA_PATH, 'merge', '-o', profdata_file_path, '-sparse=true'
@@ -399,17 +408,15 @@
   return target in GTEST_TARGET_NAMES
 
 
-def _ValidateCommandsAreRelativeToSrcRoot(commands):
+def _VerifyTargetExecutablesAreInBuildDirectory(commands):
+  """Verifies that the target executables specified in the commands are inside
+  the given build directory."""
   for command in commands:
     binary_path = _GetBinaryPath(command)
-    assert binary_path.startswith(BUILD_DIR), ('Target executable "%s" is '
-                                               'outside of the given build '
-                                               'directory: "%s". Please make '
-                                               'sure the command: "%s" is '
-                                               'relative to the root of the '
-                                               'checkout.' %
-                                               (binary_path, BUILD_DIR,
-                                                command))
+    binary_absolute_path = os.path.abspath(os.path.normpath(binary_path))
+    assert binary_absolute_path.startswith(os.path.abspath(BUILD_DIR)), (
+        'Target executable "%s" in command: "%s" is outside of '
+        'the given build directory: "%s".' % (binary_path, command, BUILD_DIR))
 
 
 def _ValidateBuildingWithClangCoverage():
@@ -448,15 +455,21 @@
   return build_args
 
 
-def _AssertPathsExist(paths):
-  """Asserts that the paths specified in |paths| exist.
+def _VerifyPathsAndReturnAbsolutes(paths):
+  """Verifies that the paths specified in |paths| exist and returns absolute
+  versions.
 
   Args:
     paths: A list of files or directories.
   """
+  absolute_paths = []
   for path in paths:
-    abspath = os.path.join(SRC_ROOT_PATH, path)
-    assert os.path.exists(abspath), ('Path: "%s" doesn\'t exist.' % path)
+    absolute_path = os.path.join(SRC_ROOT_PATH, path)
+    assert os.path.exists(absolute_path), ('Path: "%s" doesn\'t exist.' % path)
+
+    absolute_paths.append(absolute_path)
+
+  return absolute_paths
 
 
 def _ParseCommandArguments():
@@ -496,7 +509,7 @@
       '-f',
       '--filters',
       action='append',
-      required=True,
+      required=False,
       help='Directories or files to get code coverage for, and all files under '
       'the directories are included recursively.')
 
@@ -538,9 +551,11 @@
       'Build directory: {} doesn\'t exist. '
       'Please run "gn gen" to generate.').format(BUILD_DIR)
   _ValidateBuildingWithClangCoverage()
-  _ValidateCommandsAreRelativeToSrcRoot(args.command)
+  _VerifyTargetExecutablesAreInBuildDirectory(args.command)
+
+  absolute_filter_paths = []
   if args.filters:
-    _AssertPathsExist(args.filters)
+    absolute_filter_paths = _VerifyPathsAndReturnAbsolutes(args.filters)
 
   if not os.path.exists(OUTPUT_DIR):
     os.makedirs(OUTPUT_DIR)
@@ -550,11 +565,11 @@
 
   binary_paths = [_GetBinaryPath(command) for command in args.command]
   _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path,
-                                        args.filters)
+                                        absolute_filter_paths)
   html_index_file_path = 'file://' + os.path.abspath(
       os.path.join(OUTPUT_DIR, 'index.html'))
   print('\nCode coverage profile data is created as: %s' % profdata_file_path)
-  print('index file for html report is generated as: %s' % html_index_file_path)
+  print('Index file for html report is generated as: %s' % html_index_file_path)
 
 
 if __name__ == '__main__':
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py
index 23ddbdc..0a33f756 100755
--- a/tools/cygprofile/orderfile_generator_backend.py
+++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -14,10 +14,10 @@
     --target-arch=arm
 """
 
+import argparse
 import hashlib
 import json
 import logging
-import optparse
 import os
 import re
 import shutil
@@ -460,8 +460,22 @@
         self._BUILD_ROOT, self._options.arch + '_uninstrumented_out')
 
     if options.profile:
+      output_directory = os.path.join(self._instrumented_out_dir, 'Release')
+      host_cyglog_dir = os.path.join(output_directory, 'cyglog_data')
+      # Only override the defaults when using lightweight instrumentation,
+      # as the regular profiling code is likely too slow for these.
+      urls = [profile_android_startup.AndroidProfileTool.TEST_URL]
+      use_wpr = True
+      simulate_user = False
+      if options.simulate_user and not options.lightweight_instrumentation:
+        logging.error(
+            '--simulate-user required --lightweight-instrumentation, ignoring.')
+      if options.lightweight_instrumentation:
+        urls = options.urls
+        use_wpr = not options.no_wpr
+        simulate_user = options.simulate_user
       self._profiler = profile_android_startup.AndroidProfileTool(
-          os.path.join(self._instrumented_out_dir, 'Release'))
+          output_directory, host_cyglog_dir, use_wpr, urls, simulate_user)
 
     self._output_data = {}
     self._step_recorder = StepRecorder(options.buildbot)
@@ -742,47 +756,49 @@
     return self._output_data
 
 
-def CreateOptionParser():
-  parser = optparse.OptionParser()
-  parser.add_option(
+def CreateArgumentParser():
+  """Creates and returns the argument parser."""
+  parser = argparse.ArgumentParser()
+  parser.add_argument(
       '--lightweight-instrumentation', action='store_true', default=False,
       help='Use the lightweight instrumentation path')
-  parser.add_option(
+  parser.add_argument(
       '--buildbot', action='store_true',
       help='If true, the script expects to be run on a buildbot')
-  parser.add_option(
+  parser.add_argument(
       '--verify', action='store_true',
       help='If true, the script only verifies the current orderfile')
-  parser.add_option('--target-arch', action='store', dest='arch',
-                    default=cygprofile_utils.DetectArchitecture(),
-                    choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
-                    help='The target architecture for which to build')
-  parser.add_option('--output-json', action='store', dest='json_file',
-                    help='Location to save stats in json format')
-  parser.add_option(
+  parser.add_argument('--target-arch', action='store', dest='arch',
+                      default=cygprofile_utils.DetectArchitecture(),
+                      choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
+                      help='The target architecture for which to build')
+  parser.add_argument('--output-json', action='store', dest='json_file',
+                      help='Location to save stats in json format')
+  parser.add_argument(
       '--skip-profile', action='store_false', dest='profile', default=True,
       help='Don\'t generate a profile on the device. Only patch from the '
       'existing profile.')
-  parser.add_option(
+  parser.add_argument(
       '--skip-patch', action='store_false', dest='patch', default=True,
       help='Only generate the raw (unpatched) orderfile, don\'t patch it.')
-  parser.add_option(
+  parser.add_argument(
       '--netrc', action='store',
       help='A custom .netrc file to use for git checkin. Only used on bots.')
-  parser.add_option(
+  parser.add_argument(
       '--branch', action='store', default='master',
       help='When running on buildbot with a netrc, the branch orderfile '
       'hashes get checked into.')
   # Note: -j50 was causing issues on the bot.
-  parser.add_option(
+  parser.add_argument(
       '-j', '--jobs', action='store', default=20,
       help='Number of jobs to use for compilation.')
-  parser.add_option(
+  parser.add_argument(
       '-l', '--max-load', action='store', default=4, help='Max cpu load.')
-  parser.add_option('--goma-dir', help='GOMA directory.')
-  parser.add_option(
+  parser.add_argument('--goma-dir', help='GOMA directory.')
+  parser.add_argument(
       '--use-goma', action='store_true', help='Enable GOMA.', default=False)
-  parser.add_option('--adb-path', help='Path to the adb binary.')
+  parser.add_argument('--adb-path', help='Path to the adb binary.')
+  profile_android_startup.AddProfileCollectionArguments(parser)
   return parser
 
 
@@ -815,11 +831,11 @@
   return False
 
 
-def main(argv):
-  parser = CreateOptionParser()
-  options, _ = parser.parse_args(argv)
+def main():
+  parser = CreateArgumentParser()
+  options = parser.parse_args()
   return 0 if CreateOrderfile(options, OrderfileUpdater) else 1
 
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv))
+  sys.exit(main())
diff --git a/tools/cygprofile/profile_android_startup.py b/tools/cygprofile/profile_android_startup.py
index a9cbfe7b..ba96bce8 100755
--- a/tools/cygprofile/profile_android_startup.py
+++ b/tools/cygprofile/profile_android_startup.py
@@ -16,7 +16,6 @@
 import shutil
 import subprocess
 import sys
-import tempfile
 import time
 
 _SRC_PATH = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)
@@ -61,6 +60,21 @@
     raise Exception('Exception executing command %s' % ' '.join(cmd))
 
 
+def _SimulateSwipe(device, x1, y1, x2, y2):
+  """Simulates a swipe on a device from (x1, y1) to (x2, y2).
+
+  Coordinates are in (device dependent) pixels, and the origin is at the upper
+  left corner.
+  The simulated swipe will take 300ms.
+
+  Args:
+    device: (device_utils.DeviceUtils) device to run the command on.
+    x1, y1, x2, y2: (int) Coordinates.
+  """
+  args = [str(x) for x in (x1, y1, x2, y2)]
+  device.RunShellCommand(['input', 'swipe'] + args)
+
+
 class WprManager(object):
   """A utility to download a WPR archive, host it, and forward device ports to
   it.
@@ -109,7 +123,7 @@
     self._host_https_port = ports['https']
 
   def _StopWpr(self):
-    """ Stop the WPR and forwarder. """
+    """ Stop the WPR and forwarder."""
     print 'Stopping WPR on host...'
     if self._wpr_server:
       self._wpr_server.StopServer()
@@ -168,28 +182,35 @@
 
   _DEVICE_CYGLOG_DIR = '/data/local/tmp/chrome/cyglog'
 
-  # TEST_URL must be a url in the WPR_ARCHIVE.
-  _TEST_URL = 'https://www.google.com/#hl=en&q=science'
+  TEST_URL = 'https://www.google.com/#hl=en&q=science'
   _WPR_ARCHIVE = os.path.join(
       os.path.dirname(__file__), 'memory_top_10_mobile_000.wprgo')
 
-  # TODO(jbudorick): Make host_cyglog_dir mandatory after updating
-  # downstream clients. See crbug.com/639831 for context.
-  def __init__(self, output_directory, host_cyglog_dir=None):
+  def __init__(self, output_directory, host_cyglog_dir, use_wpr, urls,
+               simulate_user):
+    """Constructor.
+
+    Args:
+      output_directory: (str) Chrome build directory.
+      host_cyglog_dir: (str) Where to store the profiles.
+      use_wpr: (bool) Whether to use Web Page Replay.
+      urls: (str) URLs to load. Have to be contained in the WPR archive if
+                  use_wpr is True.
+      simulate_user: (bool) Whether to simulate a user.
+    """
     devices = device_utils.DeviceUtils.HealthyDevices()
     self._device = devices[0]
     self._cygprofile_tests = os.path.join(
         output_directory, 'cygprofile_unittests')
-    self._host_cyglog_dir = host_cyglog_dir or os.path.join(
-        output_directory, 'cyglog_data')
+    self._host_cyglog_dir = host_cyglog_dir
+    self._use_wpr = use_wpr
+    self._urls = urls
+    self._simulate_user = simulate_user
     self._SetUpDevice()
 
   def RunCygprofileTests(self):
     """Run the cygprofile unit tests suite on the device.
 
-    Args:
-      path_to_tests: The location on the host machine with the compiled
-                     cygprofile test binary.
     Returns:
       The exit code for the tests.
     """
@@ -223,18 +244,12 @@
     try:
       changer = self._SetChromeFlags(package_info)
       self._SetUpDeviceFolders()
-      # Start up chrome once with a blank page, just to get the one-off
-      # activities out of the way such as apk resource extraction and profile
-      # creation.
-      self._StartChrome(package_info, 'about:blank')
-      time.sleep(15)
-      self._KillChrome(package_info)
-      self._SetUpDeviceFolders()
-      with WprManager(self._WPR_ARCHIVE, self._device,
-                      package_info.cmdline_file, package_info.package):
-        self._StartChrome(package_info, self._TEST_URL)
-        time.sleep(90)
-        self._KillChrome(package_info)
+      if self._use_wpr:
+        with WprManager(self._WPR_ARCHIVE, self._device,
+                        package_info.cmdline_file, package_info.package):
+          self._RunProfileCollection(package_info, self._simulate_user)
+      else:
+        self._RunProfileCollection(package_info, self._simulate_user)
     finally:
       self._RestoreChromeFlags(changer)
 
@@ -242,6 +257,39 @@
     self._DeleteDeviceData()
     return data
 
+  def _RunProfileCollection(self, package_info, simulate_user):
+    """Runs the profile collection tasks.
+
+    If |simulate_user| is True, then try to simulate a real user, with swiping.
+    Also do a first load of the page instead of about:blank, in order to
+    exercise the cache. This is not desirable with a page that only contains
+    cachable resources, as in this instance the network code will not be called.
+
+    Args:
+      package_info: Which Chrome package to use.
+      simulate_user: (bool) Whether to try to simulate a user interacting with
+                     the browser.
+    """
+    initial_url = self._urls[0] if simulate_user else 'about:blank'
+    # Start up chrome once with a page, just to get the one-off
+    # activities out of the way such as apk resource extraction and profile
+    # creation.
+    self._StartChrome(package_info, initial_url)
+    time.sleep(15)
+    self._KillChrome(package_info)
+    self._SetUpDeviceFolders()
+    for url in self._urls:
+      self._StartChrome(package_info, url)
+      time.sleep(15)
+      if simulate_user:
+        # Down, down, up, up.
+        _SimulateSwipe(self._device, 200, 700, 200, 300)
+        _SimulateSwipe(self._device, 200, 700, 200, 300)
+        _SimulateSwipe(self._device, 200, 700, 200, 1000)
+        _SimulateSwipe(self._device, 200, 700, 200, 1000)
+      time.sleep(30)
+      self._KillChrome(package_info)
+
   def Cleanup(self):
     """Delete all local and device files left over from profiling. """
     self._DeleteDeviceData()
@@ -249,10 +297,9 @@
 
   def _Install(self, apk):
     """Installs Chrome.apk on the device.
+
     Args:
       apk: The location of the chrome apk to profile.
-      package_info: A PackageInfo structure describing the chrome apk,
-                    as from pylib/constants.
     """
     print 'Installing apk...'
     self._device.Install(apk)
@@ -287,7 +334,7 @@
       changer.Restore()
 
   def _SetUpDeviceFolders(self):
-    """Creates folders on the device to store cyglog data. """
+    """Creates folders on the device to store cyglog data."""
     print 'Setting up device folders...'
     self._DeleteDeviceData()
     self._device.RunShellCommand(
@@ -349,7 +396,19 @@
     return [os.path.join(cyglog_dir, x) for x in files]
 
 
-def main():
+def AddProfileCollectionArguments(parser):
+  """Adds the profiling collection arguments to |parser|."""
+  parser.add_argument(
+      '--no-wpr', action='store_true', help='Don\'t use WPR.')
+  parser.add_argument('--urls', type=str, help='URLs to load.',
+                      default=[AndroidProfileTool.TEST_URL],
+                      nargs='+')
+  parser.add_argument(
+      '--simulate-user', action='store_true', help='More realistic collection.')
+
+
+def CreateArgumentParser():
+  """Creates and return the argument parser."""
   parser = argparse.ArgumentParser()
   parser.add_argument(
       '--adb-path', type=os.path.realpath,
@@ -364,7 +423,12 @@
       '--trace-directory', type=os.path.realpath,
       help='Directory in which cyglog traces will be stored. '
            'Defaults to <output-directory>/cyglog_data')
+  AddProfileCollectionArguments(parser)
+  return parser
 
+
+def main():
+  parser = CreateArgumentParser()
   args = parser.parse_args()
 
   devil_chromium.Initialize(
@@ -380,7 +444,8 @@
     raise Exception('Unable to determine package info for %s' % args.apk_path)
 
   profiler = AndroidProfileTool(
-      args.output_directory, host_cyglog_dir=args.trace_directory)
+      args.output_directory, host_cyglog_dir=args.trace_directory,
+      use_wpr=not args.no_wpr, urls=args.urls, simulate_user=args.simulate_user)
   profiler.CollectProfile(args.apk_path, package_info)
   return 0
 
diff --git a/tools/fuchsia/local-sdk.py b/tools/fuchsia/local-sdk.py
index 7b71338..731518e 100755
--- a/tools/fuchsia/local-sdk.py
+++ b/tools/fuchsia/local-sdk.py
@@ -32,8 +32,8 @@
 
 def BuildForArch(project, arch):
   Run('scripts/build-zircon.sh', '-p', project)
-  Run('packages/gn/gen.py', '--target_cpu=' + arch,
-      '--packages=packages/gn/sdk','--ignore-skia', '--release')
+  Run('build/gn/gen.py', '--target_cpu=' + arch,
+      '--packages=garnet/packages/sdk','--ignore-skia', '--release')
   Run('buildtools/ninja', '-C', 'out/release-' + arch)
 
 
@@ -49,8 +49,8 @@
   # Switch to the Fuchsia tree and build an SDK.
   os.chdir(fuchsia_root)
 
-  BuildForArch('zircon-pc-x86-64', 'x86-64')
-  BuildForArch('zircon-qemu-arm64', 'aarch64')
+  BuildForArch('x86', 'x86-64')
+  BuildForArch('arm64', 'aarch64')
 
   tempdir = tempfile.mkdtemp()
   sdk_tar = os.path.join(tempdir, 'fuchsia-sdk.tgz')
diff --git a/tools/grit/grit/format/rc.py b/tools/grit/grit/format/rc.py
index 5dfeb034..47ad5a03 100755
--- a/tools/grit/grit/format/rc.py
+++ b/tools/grit/grit/format/rc.py
@@ -413,8 +413,8 @@
     relative_path = item.attrs['relativepath'] == 'true'
   else:
     assert (isinstance(item, structure.StructureNode) and item.attrs['type'] in
-        ['admin_template', 'chrome_html', 'chrome_scaled_image', 'igoogle',
-         'muppet', 'tr_html', 'txt'])
+        ['admin_template', 'chrome_html', 'chrome_scaled_image',
+         'tr_html', 'txt'])
     filename_only = False
     relative_path = False
 
@@ -461,8 +461,6 @@
   'chrome_html'         : partial(FormatInclude, type='BINDATA',
                                                  process_html=True),
   'chrome_scaled_image' : partial(FormatInclude, type='BINDATA'),
-  'igoogle'             : partial(FormatInclude, type='XML'),
-  'muppet'              : partial(FormatInclude, type='XML'),
   'tr_html'             : partial(FormatInclude, type='HTML'),
   'txt'                 : partial(FormatInclude, type='TXT'),
   'policy_template_metafile': _DoNotFormat,
diff --git a/tools/grit/grit/gather/igoogle_strings.py b/tools/grit/grit/gather/igoogle_strings.py
deleted file mode 100755
index 79ed839..0000000
--- a/tools/grit/grit/gather/igoogle_strings.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-'''Support for ALL_ALL.xml format used by Igoogle plug-ins in Google Desktop.'''
-
-import StringIO
-import re
-import xml.sax
-import xml.sax.handler
-import xml.sax.saxutils
-
-from grit.gather import regexp
-from grit import util
-from grit import tclib
-
-# Placeholders can be defined in strings.xml files by putting the name of the
-# placeholder between [![ and ]!] e.g. <MSG>Hello [![USER]!] how are you<MSG>
-PLACEHOLDER_RE = re.compile('(\[!\[|\]!\])')
-
-
-class IgoogleStringsContentHandler(xml.sax.handler.ContentHandler):
-  '''A very dumb parser for splitting the strings.xml file into translateable
-  and nontranslateable chunks.'''
-
-  def __init__(self, parent):
-    self.curr_elem = ''
-    self.curr_text = ''
-    self.parent = parent
-    self.resource_name = ''
-    self.meaning = ''
-    self.translateable = True
-
-  def startElement(self, name, attrs):
-    if (name != 'messagebundle'):
-      self.curr_elem = name
-
-      attr_names = attrs.getQNames()
-      if 'name' in attr_names:
-        self.resource_name = attrs.getValueByQName('name')
-
-      att_text = []
-      for attr_name in attr_names:
-        att_text.append(' ')
-        att_text.append(attr_name)
-        att_text.append('=')
-        att_text.append(
-          xml.sax.saxutils.quoteattr(attrs.getValueByQName(attr_name)))
-
-      self.parent._AddNontranslateableChunk("<%s%s>" %
-                                            (name, ''.join(att_text)))
-
-  def characters(self, content):
-    if self.curr_elem != '':
-      self.curr_text += content
-
-  def endElement(self, name):
-    if name != 'messagebundle':
-      self.parent.AddMessage(self.curr_text, self.resource_name,
-                             self.meaning, self.translateable)
-      self.parent._AddNontranslateableChunk("</%s>\n" % name)
-      self.curr_elem = ''
-      self.curr_text = ''
-      self.resource_name = ''
-      self.meaning = ''
-      self.translateable = True
-
-  def ignorableWhitespace(self, whitespace):
-    pass
-
-
-class IgoogleStrings(regexp.RegexpGatherer):
-  '''Supports the ALL_ALL.xml format used by Igoogle gadgets.'''
-
-  def AddMessage(self, msgtext, description, meaning, translateable):
-    if msgtext == '':
-      return
-
-    msg = tclib.Message(description=description, meaning=meaning)
-
-    unescaped_text = self.UnEscape(msgtext)
-    parts = PLACEHOLDER_RE.split(unescaped_text)
-    in_placeholder = False
-    for part in parts:
-      if part == '':
-        continue
-      elif part == '[![':
-        in_placeholder = True
-      elif part == ']!]':
-        in_placeholder = False
-      else:
-        if in_placeholder:
-          msg.AppendPlaceholder(tclib.Placeholder(part, '[![%s]!]' % part,
-                                                  '(placeholder)'))
-        else:
-          msg.AppendText(part)
-
-    self.skeleton_.append(
-      self.uberclique.MakeClique(msg, translateable=translateable))
-
-    # if statement needed because this is supposed to be idempotent (so never
-    # set back to false)
-    if translateable:
-      self.translatable_chunk_ = True
-
-  # Although we use the RegexpGatherer base class, we do not use the
-  # _RegExpParse method of that class to implement Parse().  Instead, we
-  # parse using a SAX parser.
-  def Parse(self):
-    if self.have_parsed_:
-      return
-    self.have_parsed_ = True
-
-    self.text_ = self._LoadInputFile().strip()
-    self._AddNontranslateableChunk(u'<messagebundle>\n')
-    stream = StringIO.StringIO(self.text_)
-    handler = IgoogleStringsContentHandler(self)
-    xml.sax.parse(stream, handler)
-    self._AddNontranslateableChunk(u'</messagebundle>\n')
-
-  def Escape(self, text):
-    return util.EncodeCdata(text)
diff --git a/tools/grit/grit/gather/igoogle_strings_unittest.py b/tools/grit/grit/gather/igoogle_strings_unittest.py
deleted file mode 100755
index 3a4488c..0000000
--- a/tools/grit/grit/gather/igoogle_strings_unittest.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-'''Unit tests for grit.gather.igoogle_strings'''
-
-import os
-import sys
-if __name__ == '__main__':
-  sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
-
-import unittest
-import StringIO
-
-from grit.gather import igoogle_strings
-
-class IgoogleStringsUnittest(unittest.TestCase):
-  def testParsing(self):
-    original = '''<messagebundle><msg test="hello_world">Hello World</msg></messagebundle>'''
-    gatherer = igoogle_strings.IgoogleStrings(StringIO.StringIO(original))
-    gatherer.Parse()
-    print len(gatherer.GetCliques())
-    print gatherer.GetCliques()[0].GetMessage().GetRealContent()
-    self.failUnless(len(gatherer.GetCliques()) == 1)
-    self.failUnless(gatherer.Translate('en').replace('\n', '') == original)
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/tools/grit/grit/gather/muppet_strings.py b/tools/grit/grit/gather/muppet_strings.py
deleted file mode 100755
index ab2f08a3d..0000000
--- a/tools/grit/grit/gather/muppet_strings.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-'''Support for "strings.xml" format used by Muppet plug-ins in Google Desktop.'''
-
-import StringIO
-import xml.sax
-import xml.sax.handler
-import xml.sax.saxutils
-
-from grit import lazy_re
-from grit import tclib
-from grit import util
-from grit.gather import regexp
-
-
-# Placeholders can be defined in strings.xml files by putting the name of the
-# placeholder between [![ and ]!] e.g. <MSG>Hello [![USER]!] how are you<MSG>
-PLACEHOLDER_RE = lazy_re.compile('(\[!\[|\]!\])')
-
-
-class MuppetStringsContentHandler(xml.sax.handler.ContentHandler):
-  '''A very dumb parser for splitting the strings.xml file into translateable
-  and nontranslateable chunks.'''
-
-  def __init__(self, parent):
-    self.curr_elem = ''
-    self.curr_text = ''
-    self.parent = parent
-    self.description = ''
-    self.meaning = ''
-    self.translateable = True
-
-  def startElement(self, name, attrs):
-    if (name != 'strings'):
-      self.curr_elem = name
-
-      attr_names = attrs.getQNames()
-      if 'desc' in attr_names:
-        self.description = attrs.getValueByQName('desc')
-      if 'meaning' in attr_names:
-        self.meaning = attrs.getValueByQName('meaning')
-      if 'translateable' in attr_names:
-        value = attrs.getValueByQName('translateable')
-        if value.lower() not in ['true', 'yes']:
-          self.translateable = False
-
-      att_text = []
-      for attr_name in attr_names:
-        att_text.append(' ')
-        att_text.append(attr_name)
-        att_text.append('=')
-        att_text.append(
-          xml.sax.saxutils.quoteattr(attrs.getValueByQName(attr_name)))
-
-      self.parent._AddNontranslateableChunk("<%s%s>" %
-                                            (name, ''.join(att_text)))
-
-  def characters(self, content):
-    if self.curr_elem != '':
-      self.curr_text += content
-
-  def endElement(self, name):
-    if name != 'strings':
-      self.parent.AddMessage(self.curr_text, self.description,
-                             self.meaning, self.translateable)
-      self.parent._AddNontranslateableChunk("</%s>\n" % name)
-      self.curr_elem = ''
-      self.curr_text = ''
-      self.description = ''
-      self.meaning = ''
-      self.translateable = True
-
-  def ignorableWhitespace(self, whitespace):
-    pass
-
-class MuppetStrings(regexp.RegexpGatherer):
-  '''Supports the strings.xml format used by Muppet gadgets.'''
-
-  def AddMessage(self, msgtext, description, meaning, translateable):
-    if msgtext == '':
-      return
-
-    msg = tclib.Message(description=description, meaning=meaning)
-
-    unescaped_text = self.UnEscape(msgtext)
-    parts = PLACEHOLDER_RE.split(unescaped_text)
-    in_placeholder = False
-    for part in parts:
-      if part == '':
-        continue
-      elif part == '[![':
-        in_placeholder = True
-      elif part == ']!]':
-        in_placeholder = False
-      else:
-        if in_placeholder:
-          msg.AppendPlaceholder(tclib.Placeholder(part, '[![%s]!]' % part,
-                                                  '(placeholder)'))
-        else:
-          msg.AppendText(part)
-
-    self.skeleton_.append(
-      self.uberclique.MakeClique(msg, translateable=translateable))
-
-    # if statement needed because this is supposed to be idempotent (so never
-    # set back to false)
-    if translateable:
-      self.translatable_chunk_ = True
-
-  # Although we use the RegexpGatherer base class, we do not use the
-  # _RegExpParse method of that class to implement Parse().  Instead, we
-  # parse using a SAX parser.
-  def Parse(self):
-    if self.have_parsed_:
-      return
-    self.have_parsed_ = True
-
-    text = self._LoadInputFile().encode(self.encoding)
-    if util.IsExtraVerbose():
-      print text
-    self.text_ = text.strip()
-
-    self._AddNontranslateableChunk(u'<strings>\n')
-    stream = StringIO.StringIO(self.text_)
-    handler = MuppetStringsContentHandler(self)
-    xml.sax.parse(stream, handler)
-    self._AddNontranslateableChunk(u'</strings>\n')
-
-  def Escape(self, text):
-    return util.EncodeCdata(text)
diff --git a/tools/grit/grit/gather/muppet_strings_unittest.py b/tools/grit/grit/gather/muppet_strings_unittest.py
deleted file mode 100755
index adf66b65..0000000
--- a/tools/grit/grit/gather/muppet_strings_unittest.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-'''Unit tests for grit.gather.muppet_strings'''
-
-import os
-import sys
-if __name__ == '__main__':
-  sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
-
-import unittest
-import StringIO
-
-from grit.gather import muppet_strings
-
-class MuppetStringsUnittest(unittest.TestCase):
-  def testParsing(self):
-    original = '''<strings><BLA desc="Says hello">hello!</BLA><BINGO>YEEEESSS!!!</BINGO></strings>'''
-    gatherer = muppet_strings.MuppetStrings(StringIO.StringIO(original))
-    gatherer.Parse()
-    self.failUnless(len(gatherer.GetCliques()) == 2)
-    self.failUnless(gatherer.Translate('en').replace('\n', '') == original)
-
-  def testEscapingAndLinebreaks(self):
-    original = ('''\
-<strings>
-<LINEBREAK desc="Howdie">Hello
-there
-how
-are
-you?</LINEBREAK>   <ESCAPED meaning="bingo">4 &lt; 6</ESCAPED>
-</strings>''')
-    gatherer = muppet_strings.MuppetStrings(StringIO.StringIO(original))
-    gatherer.Parse()
-    self.failUnless(gatherer.GetCliques()[0].translateable)
-    self.failUnless(len(gatherer.GetCliques()) == 2)
-    self.failUnless(gatherer.GetCliques()[0].GetMessage().GetRealContent() ==
-                    'Hello\nthere\nhow\nare\nyou?')
-    self.failUnless(gatherer.GetCliques()[0].GetMessage().GetDescription() == 'Howdie')
-    self.failUnless(gatherer.GetCliques()[1].GetMessage().GetRealContent() ==
-                    '4 < 6')
-    self.failUnless(gatherer.GetCliques()[1].GetMessage().GetMeaning() == 'bingo')
-
-  def testPlaceholders(self):
-    original = "<strings><MESSAGE translateable='True'>Hello [![USER]!] how are you? [![HOUR]!]:[![MINUTE]!]</MESSAGE></strings>"
-    gatherer = muppet_strings.MuppetStrings(StringIO.StringIO(original))
-    gatherer.Parse()
-    self.failUnless(gatherer.GetCliques()[0].translateable)
-    msg = gatherer.GetCliques()[0].GetMessage()
-    self.failUnless(len(msg.GetPlaceholders()) == 3)
-    ph = msg.GetPlaceholders()[0]
-    self.failUnless(ph.GetOriginal() == '[![USER]!]')
-    self.failUnless(ph.GetPresentation() == 'USER')
-
-  def testTranslateable(self):
-    original = "<strings><BINGO translateable='false'>Yo yo hi there</BINGO></strings>"
-    gatherer = muppet_strings.MuppetStrings(StringIO.StringIO(original))
-    gatherer.Parse()
-    msg = gatherer.GetCliques()[0].GetMessage()
-    self.failUnless(msg.GetRealContent() == "Yo yo hi there")
-    self.failUnless(not gatherer.GetCliques()[0].translateable)
-
-if __name__ == '__main__':
-  unittest.main()
-
diff --git a/tools/grit/grit/node/structure.py b/tools/grit/grit/node/structure.py
index cf7c1c7..89d5202 100755
--- a/tools/grit/grit/node/structure.py
+++ b/tools/grit/grit/node/structure.py
@@ -18,8 +18,6 @@
 import grit.gather.admin_template
 import grit.gather.chrome_html
 import grit.gather.chrome_scaled_image
-import grit.gather.igoogle_strings
-import grit.gather.muppet_strings
 import grit.gather.policy_json
 import grit.gather.rc
 import grit.gather.tr_html
@@ -34,9 +32,7 @@
   'chrome_html'         : grit.gather.chrome_html.ChromeHtml,
   'chrome_scaled_image' : grit.gather.chrome_scaled_image.ChromeScaledImage,
   'dialog'              : grit.gather.rc.Dialog,
-  'igoogle'             : grit.gather.igoogle_strings.IgoogleStrings,
   'menu'                : grit.gather.rc.Menu,
-  'muppet'              : grit.gather.muppet_strings.MuppetStrings,
   'rcdata'              : grit.gather.rc.RCData,
   'tr_html'             : grit.gather.tr_html.TrHtml,
   'txt'                 : grit.gather.txt.TxtFile,
@@ -241,7 +237,7 @@
 
   def HasFileForLanguage(self):
     return self.attrs['type'] in ['tr_html', 'admin_template', 'txt',
-                                  'muppet', 'igoogle', 'chrome_scaled_image',
+                                  'chrome_scaled_image',
                                   'chrome_html']
 
   def ExpandVariables(self):
diff --git a/tools/grit/grit/test_suite_all.py b/tools/grit/grit/test_suite_all.py
index 4befd33..db66bb4 100755
--- a/tools/grit/grit/test_suite_all.py
+++ b/tools/grit/grit/test_suite_all.py
@@ -45,8 +45,6 @@
     import grit.gather.admin_template_unittest
     import grit.gather.chrome_html_unittest
     import grit.gather.chrome_scaled_image_unittest
-    import grit.gather.igoogle_strings_unittest
-    import grit.gather.muppet_strings_unittest
     import grit.gather.policy_json_unittest
     import grit.gather.rc_unittest
     import grit.gather.tr_html_unittest
@@ -91,8 +89,6 @@
         grit.gather.admin_template_unittest.AdmGathererUnittest,
         grit.gather.chrome_html_unittest.ChromeHtmlUnittest,
         grit.gather.chrome_scaled_image_unittest.ChromeScaledImageUnittest,
-        grit.gather.igoogle_strings_unittest.IgoogleStringsUnittest,
-        grit.gather.muppet_strings_unittest.MuppetStringsUnittest,
         grit.gather.policy_json_unittest.PolicyJsonUnittest,
         grit.gather.rc_unittest.RcUnittest,
         grit.gather.tr_html_unittest.ParserUnittest,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 7f333f9..57848a7 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -17378,11 +17378,18 @@
 <action name="SoftwareReporter.CleanupWebui_StartCleanup">
   <owner>alito@chromium.org</owner>
   <description>
-    The cleaner accepted the cleanup operation offered on the Chrome Cleaner
+    The cleaner started the cleanup operation offered on the Chrome Cleaner
     webui.
   </description>
 </action>
 
+<action name="SoftwareReporter.CleanupWebui_StartScanning">
+  <owner>ftirelo@chromium.org</owner>
+  <description>
+    The cleaner started the scan operation offered on the Chrome Cleaner webui.
+  </description>
+</action>
+
 <action name="SoftwareReporter.PromptDialog.LogsPermissionCheckbox_Disabled">
   <owner>alito@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/README.md b/tools/metrics/histograms/README.md
index a48e281..065c291d 100644
--- a/tools/metrics/histograms/README.md
+++ b/tools/metrics/histograms/README.md
@@ -240,11 +240,18 @@
 tools not to treat the partial base name as a distinct histogram. Note that
 suffixes can be applied recursively.
 
+### Enum labels
+
+_All_ histograms, including boolean and sparse histograms, may have enum labels
+provided via [enums.xml](./enums.xml). Using labels is encouraged whenever
+labels would be clearer than raw numeric values.
+
 ## When To Use Sparse Histograms
 
 Sparse histograms are well suited for recording counts of exact sample values
 that are sparsely distributed over a large range.  They can be used with enums
-as well as regular integer values.
+as well as regular integer values. It is often valuable to provide labels in
+[enums.xml](./enums.xml).
 
 The implementation uses a lock and a map, whereas other histogram types use a
 vector and no lock. It is thus more costly to add values to, and each value
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index e8833fac..59c9d12 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -1338,6 +1338,13 @@
   <int value="1" label="Chrome"/>
 </enum>
 
+<enum name="ArcNativeBridgeType">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="None"/>
+  <int value="2" label="Houdini"/>
+  <int value="3" label="Ndk-translation"/>
+</enum>
+
 <enum name="ArcOptInAction">
   <summary>Defines Arc OptIn actions</summary>
   <int value="0" label="Opted Out"/>
@@ -1795,6 +1802,14 @@
   <int value="2" label="Processing in WebRTC"/>
 </enum>
 
+<enum name="AuthenticatedLaunchUserEvent">
+  <int value="0" label="Local Reauth Dialog"/>
+  <int value="1" label="Gaia Reauth Dialog"/>
+  <int value="2" label="Supervised Profile Blocked Warning"/>
+  <int value="3" label="Used Profile Blocked Warning"/>
+  <int value="4" label="Forced Primary Signin Dialog"/>
+</enum>
+
 <enum name="AuthMethod">
   <int value="0" label="Password"/>
   <int value="1" label="PIN"/>
@@ -6357,6 +6372,24 @@
   <int value="5" label="DETECT_IMPORTANT_CONTENT"/>
 </enum>
 
+<enum name="ContentSettingImageType">
+  <int value="0" label="COOKIES"/>
+  <int value="1" label="IMAGES"/>
+  <int value="2" label="JAVASCRIPT"/>
+  <int value="3" label="PPAPI_BROKER"/>
+  <int value="4" label="PLUGINS"/>
+  <int value="5" label="POPUPS"/>
+  <int value="6" label="GEOLOCATION"/>
+  <int value="7" label="MIXEDSCRIPT"/>
+  <int value="8" label="PROTOCOL_HANDLERS"/>
+  <int value="9" label="MEDIASTREAM"/>
+  <int value="10" label="ADS"/>
+  <int value="11" label="AUTOMATIC_DOWNLOADS"/>
+  <int value="12" label="MIDI_SYSEX"/>
+  <int value="13" label="SOUND"/>
+  <int value="14" label="FRAMEBUST"/>
+</enum>
+
 <enum name="ContentSettingMixedScriptAction">
   <int value="0" label="Displayed shield"/>
   <int value="1" label="Displayed bubble"/>
@@ -7431,6 +7464,15 @@
   <int value="2" label="Finished with &quot;Keep Exploring&quot; button"/>
 </enum>
 
+<enum name="CrosSelectToSpeakSpeechRate">
+  <int value="50" label="0.5: Slowest"/>
+  <int value="75" label="0.75: Slow"/>
+  <int value="100" label="1.0: Normal"/>
+  <int value="125" label="1.25: Fast"/>
+  <int value="150" label="1.5: Faster"/>
+  <int value="200" label="2.0: Fastest"/>
+</enum>
+
 <enum name="CrosShelfClickTarget">
   <obsolete>
     Deprecated as of 12/2013. Default pinned apps trial is finished.
@@ -12057,7 +12099,8 @@
   <int value="400" label="UnsafelyTreatInsecureOriginAsSecure"/>
   <int value="401" label="DefaultDownloadDirectory"/>
   <int value="402" label="SecurityKeyPermitAttestation"/>
-  <int value="403" label="NetworkHostname"/>
+  <int value="403" label="DeviceHostnameTemplate"/>
+  <int value="404" label="AbusiveExperienceInterventionEnforce"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
@@ -13952,7 +13995,7 @@
   <int value="1000" label="DEVELOPERPRIVATE_GETPROFILECONFIGURATION"/>
   <int value="1001" label="DEVELOPERPRIVATE_UPDATEPROFILECONFIGURATION"/>
   <int value="1002" label="SOCKETS_UDP_SETBROADCAST"/>
-  <int value="1003" label="FILEMANAGERPRIVATE_GETPROVIDINGEXTENSIONS"/>
+  <int value="1003" label="FILEMANAGERPRIVATE_GETPROVIDERS"/>
   <int value="1004" label="WEBVIEWINTERNAL_ADDCONTENTSCRIPTS"/>
   <int value="1005" label="WEBVIEWINTERNAL_REMOVECONTENTSCRIPTS"/>
   <int value="1006" label="DEVELOPERPRIVATE_REPAIREXTENSION"/>
@@ -22469,6 +22512,8 @@
   <int value="0" label="Unknown error"/>
   <int value="1" label="Tethering timed out"/>
   <int value="2" label="Client connection error"/>
+  <int value="3" label="Tethering unsupported"/>
+  <int value="4" label="No cellular data"/>
 </enum>
 
 <enum name="InstantTethering_ConnectionToHostResult_Failure_ClientConnection">
@@ -24459,6 +24504,7 @@
   <int value="-2090484194" label="ContextualSearchUrlActions:disabled"/>
   <int value="-2083998415" label="VrLaunchIntent:enabled"/>
   <int value="-2083195884" label="enable-firewall-hole-punching"/>
+  <int value="-2082462043" label="ViewPasswords:disabled"/>
   <int value="-2082042818"
       label="AutofillCreditCardLastUsedDateDisplay:enabled"/>
   <int value="-2077268643" label="disable-device-enumeration"/>
@@ -24506,6 +24552,7 @@
   <int value="-1989747818" label="TabStripKeyboardFocus:disabled"/>
   <int value="-1985025593" label="file-manager-enable-new-gallery"/>
   <int value="-1980328793" label="trace-upload-url"/>
+  <int value="-1977496883" label="ViewPasswords:enabled"/>
   <int value="-1973722176" label="VoiceSearchOnLocalNtp:enabled"/>
   <int value="-1972383451" label="disable-pinch"/>
   <int value="-1972312724" label="OfflinePagesLoadSignalCollecting:enabled"/>
@@ -24972,6 +25019,7 @@
   <int value="-795600188" label="disable-async-dns"/>
   <int value="-793921836" label="ShowAllDialogsWithViewsToolkit:disabled"/>
   <int value="-790036192" label="overscroll-start-threshold"/>
+  <int value="-787426248" label="ChromeHomeSurvey:disabled"/>
   <int value="-780798969" label="disable-single-click-autofill"/>
   <int value="-776686417" label="SiteExplorationUi:disabled"/>
   <int value="-775321548" label="UseNewDoodleApi:disabled"/>
@@ -25255,6 +25303,7 @@
   <int value="10458238" label="disable-print-preview-simplify"/>
   <int value="11698808" label="enable-dom-distiller-button-animation"/>
   <int value="27507364" label="apps-keep-chrome-alive"/>
+  <int value="28272521" label="ash-enable-display-move-window-accels"/>
   <int value="31848187" label="ViewsTaskManager:disabled"/>
   <int value="33778663" label="OriginTrials:enabled"/>
   <int value="37024318" label="disable-affiliation-based-matching"/>
@@ -25465,6 +25514,7 @@
   <int value="635971109" label="PrintPdfAsImage:disabled"/>
   <int value="636425179" label="mhtml-generator-option"/>
   <int value="637396292" label="AllBookmarks:enabled"/>
+  <int value="637452937" label="ChromeHomeSurvey:enabled"/>
   <int value="643725031" label="disable-touch-feedback"/>
   <int value="644189071" label="PermissionsBlacklist:enabled"/>
   <int value="644674603" label="DataReductionProxySiteBreakdown:disabled"/>
@@ -25848,6 +25898,7 @@
   <int value="1665349789" label="spurious-power-button-window"/>
   <int value="1668611601" label="enable-encrypted-media"/>
   <int value="1670161209" label="ClickToOpenPDFPlaceholder:enabled"/>
+  <int value="1670799163" label="ChromeHomeShowGoogleGWhenUrlCleared:enabled"/>
   <int value="1672878289" label="PwaMinimalUi:disabled"/>
   <int value="1673427566" label="ChromeHomeExpandButton:disabled"/>
   <int value="1689123607" label="enable-app-link"/>
@@ -26007,6 +26058,7 @@
   <int value="2085186092" label="BulkPrinters:disabled"/>
   <int value="2085438501" label="ChromeHome:enabled"/>
   <int value="2089897928" label="enable-audio-focus"/>
+  <int value="2092605092" label="ChromeHomeShowGoogleGWhenUrlCleared:disabled"/>
   <int value="2093235103" label="default-tile-width"/>
   <int value="2097048479" label="disable-auto-hiding-toolbar-threshold"/>
   <int value="2098714203" label="enable-generic-sensors"/>
@@ -30921,10 +30973,16 @@
 </enum>
 
 <enum name="OfflinePagesStoreEvent">
-  <int value="0" label="Store opened for the first time"/>
-  <int value="1" label="Store reopened"/>
-  <int value="2" label="Store closed"/>
-  <int value="3" label="Store closing skipped"/>
+  <int value="0" label="Store opened first time">
+    Store was opened for this first time during this session.
+  </int>
+  <int value="1" label="Store reopened">
+    Store was opened after closing at least once during this session.
+  </int>
+  <int value="2" label="Store closed">Store was closed.</int>
+  <int value="3" label="Store closing skipped">
+    Store closing was skipped, because it was not opened at the time of closing.
+  </int>
 </enum>
 
 <enum name="OfflinePagesTabRestoreType">
@@ -34185,22 +34243,6 @@
   <int value="10" label="Login action added, Subframe, pw empty"/>
 </enum>
 
-<enum name="PresentationResult">
-  <int value="0" label="Requested"/>
-  <int value="1" label="Success"/>
-  <int value="2" label="SuccessAlreadyPresenting"/>
-  <int value="3" label="VRDisplayCannotPresent"/>
-  <int value="4" label="PresentationNotSupportedByDisplay"/>
-  <int value="5" label="VRDisplayNotFound"/>
-  <int value="6" label="NotInitiatedByUserGesture"/>
-  <int value="7" label="InvalidNumberOfLayers"/>
-  <int value="8" label="InvalidLayerSource"/>
-  <int value="9" label="LayerSourceMissingWebGLContext"/>
-  <int value="10" label="InvalidLayerBounds"/>
-  <int value="11" label="ServiceInactive"/>
-  <int value="12" label="RequestDenied"/>
-</enum>
-
 <enum name="PresentationUrlType">
   <int value="0" label="Other"/>
   <int value="1" label="Cast"/>
@@ -36075,6 +36117,9 @@
   <int value="9" label="Removed (max-age = 0)"/>
   <int value="10" label="Set rejected by delegate (max-age &gt; 0)"/>
   <int value="11" label="Set (max-age &gt; 0)"/>
+  <int value="12" label="Discarded: priority not an integer"/>
+  <int value="13" label="Discarded: weight not an integer"/>
+  <int value="14" label="Discarded: weight not positive"/>
 </enum>
 
 <enum name="ReportingHeaderOutcome">
@@ -41866,6 +41911,7 @@
   <int value="1" label="Recording disabled"/>
   <int value="2" label="Max hit"/>
   <int value="3" label="Not whitelisted"/>
+  <int value="4" label="Unsupported URL scheme"/>
 </enum>
 
 <enum name="UmaCleanExitConsistency">
@@ -43280,6 +43326,22 @@
   <int value="1" label="Component is not ready to use. Reason unknown."/>
 </enum>
 
+<enum name="VRPresentationResult">
+  <int value="0" label="Requested"/>
+  <int value="1" label="Success"/>
+  <int value="2" label="SuccessAlreadyPresenting"/>
+  <int value="3" label="VRDisplayCannotPresent"/>
+  <int value="4" label="PresentationNotSupportedByDisplay"/>
+  <int value="5" label="VRDisplayNotFound"/>
+  <int value="6" label="NotInitiatedByUserGesture"/>
+  <int value="7" label="InvalidNumberOfLayers"/>
+  <int value="8" label="InvalidLayerSource"/>
+  <int value="9" label="LayerSourceMissingWebGLContext"/>
+  <int value="10" label="InvalidLayerBounds"/>
+  <int value="11" label="ServiceInactive"/>
+  <int value="12" label="RequestDenied"/>
+</enum>
+
 <enum name="VRSuppressedElement">
   <int value="0" label="File chooser was suppressed in VR"/>
   <int value="1" label="Bluetooth picker was suppressed in VR"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 687e6c6..311f6b5 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -227,6 +227,24 @@
   </summary>
 </histogram>
 
+<histogram name="Accessibility.CrosSelectToSpeak.SpeechRate"
+    enum="CrosSelectToSpeakSpeechRate">
+  <owner>katie@chromium.org</owner>
+  <summary>
+    The speech rate setting when Select-to-Speak was activated. It is stored as
+    a sparse histogram with values (100 * speech_rate). For example, a speech
+    rate of 1.0 (default) will be seen as 100.
+  </summary>
+</histogram>
+
+<histogram name="Accessibility.CrosSelectToSpeak.WordHighlighting"
+    enum="BooleanEnabled">
+  <owner>katie@chromium.org</owner>
+  <summary>
+    Whether Select-to-Speak had per-word highlighting enabled when activated.
+  </summary>
+</histogram>
+
 <histogram name="Accessibility.CrosSpokenFeedback" enum="BooleanEnabled">
   <owner>dmazzoni@chromium.org</owner>
   <owner>kenjibaheux@google.com</owner>
@@ -2528,6 +2546,18 @@
   <summary>The elapsed time to last low memory kill event.</summary>
 </histogram>
 
+<histogram name="Arc.NativeBridge" enum="ArcNativeBridgeType">
+  <owner>elijahtaylor@google.com</owner>
+  <owner>levarum@google.com</owner>
+  <summary>
+    Native bridge used for ARC. Can be unknown and none. This is collected along
+    with Arc.State during every metrics recording interval, so it is in every
+    record uploaded to the server. This is required because this value is used
+    to categorize all other data in the dashboard as collected with specific
+    native bridge in use.
+  </summary>
+</histogram>
+
 <histogram name="Arc.OOMKills.Count" units="kills">
   <owner>elijahtaylor@google.com</owner>
   <owner>shihuis@google.com</owner>
@@ -6907,7 +6937,7 @@
   </summary>
 </histogram>
 
-<histogram name="Blink.ResourceLoadScheduler.RequestCounts"
+<histogram name="Blink.ResourceLoadScheduler.RequestCount"
     enum="ResourceLoadSchedulerCircumstance">
   <owner>toyoshim@chromium.org</owner>
   <summary>
@@ -10114,7 +10144,7 @@
     Tilings are used for decomposition of the layer's entire contents at a
     picture screenspace resolution to do threaded rasterization.
 
-    Team: threaded-rendering-dev@chromium.org.
+    Team: animations-dev@chromium.org.
   </summary>
 </histogram>
 
@@ -10131,7 +10161,7 @@
 
 <histogram base="true" name="Compositing.Browser.LayersUpdateTime"
     units="microseconds">
-  <owner>threaded-rendering-dev@chromium.org</owner>
+  <owner>animations-dev@chromium.org</owner>
   <summary>
     Time spent updating layers, in microseconds. Recorded when layers are
     updated (in a browser process).
@@ -10481,7 +10511,7 @@
     Tilings are used for decomposition of the layer's entire contents at a
     picture screenspace resolution to do threaded rasterization.
 
-    Team: threaded-rendering-dev@chromium.org.
+    Team: animations-dev@chromium.org.
   </summary>
 </histogram>
 
@@ -10498,7 +10528,7 @@
 
 <histogram base="true" name="Compositing.Renderer.LayersUpdateTime"
     units="microseconds">
-  <owner>threaded-rendering-dev@chromium.org</owner>
+  <owner>animations-dev@chromium.org</owner>
   <summary>
     Time spent updating layers, in microseconds. Recorded when layers are
     updated (in a renderer process).
@@ -11022,6 +11052,13 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSettings.ImagePressed" enum="ContentSettingImageType">
+  <owner>calamity@chromium.org</owner>
+  <summary>
+    Counts which content setting buttons are pressed by the user.
+  </summary>
+</histogram>
+
 <histogram name="ContentSettings.LastSettingParsed" enum="LastSettingParsed">
   <obsolete>
     Deprecated 2015-10-05 in Issue 433475. Histogram was used temorarily for
@@ -21226,7 +21263,7 @@
     the other two metrics which measure the size of scrollers on scroll, we may
     have a better idea of not compositing small scrollers.
 
-    Team: input-dev@chromium.org, threaded-rendering-dev@chromium.org.
+    Team: input-dev@chromium.org, animations-dev@chromium.org.
   </summary>
 </histogram>
 
@@ -21241,7 +21278,7 @@
     For those small scrollers that users may rarely scroll, there is no need to
     composite them even if we are able to do so.
 
-    Team: input-dev@chromium.org, threaded-rendering-dev@chromium.org.
+    Team: input-dev@chromium.org, animations-dev@chromium.org.
   </summary>
 </histogram>
 
@@ -28512,6 +28549,15 @@
   </summary>
 </histogram>
 
+<histogram name="HostedAppFrame.ContentSettings.ImagePressed"
+    enum="ContentSettingImageType">
+  <owner>calamity@chromium.org</owner>
+  <summary>
+    Counts which content setting buttons in the hosted app frame are pressed by
+    the user.
+  </summary>
+</histogram>
+
 <histogram name="HostedAppFrame.WrenchMenu.MenuAction" enum="WrenchMenuAction">
   <owner>calamity@chromium.org</owner>
   <summary>
@@ -30147,7 +30193,7 @@
 
     An &quot;unknown error&quot; is caused by the host returning an
     &quot;unknown error&quot; response code. Tethering timing out and client
-    connection error and 3) are both broken down further in
+    connection error are both broken down further in
     InstantTethering.ConnectionToHostResult.Failure.TetheringTimeout and
     InstantTethering.ConnectionToHostResult.Failure.ClientConnection,
     respectively.
@@ -39335,6 +39381,9 @@
 </histogram>
 
 <histogram name="Navigation.Intercept.WillStart" units="microseconds">
+  <obsolete>
+    Deprecated in favor of mainframe/subframe breakouts
+  </obsolete>
   <owner>csharrison@chromium.org</owner>
   <summary>
     The microseconds it takes for the InterceptNavigationThrottle to determine
@@ -39342,6 +39391,23 @@
   </summary>
 </histogram>
 
+<histogram name="Navigation.Intercept.WillStart.Mainframe" units="microseconds">
+  <owner>csharrison@chromium.org</owner>
+  <summary>
+    The microseconds it takes for the InterceptNavigationThrottle to determine
+    if the navigation should be ignored, at WillStartRequest time for main
+    frames.
+  </summary>
+</histogram>
+
+<histogram name="Navigation.Intercept.WillStart.Subframe" units="microseconds">
+  <owner>csharrison@chromium.org</owner>
+  <summary>
+    The microseconds it takes for the InterceptNavigationThrottle to determine
+    if the navigation should be ignored, at WillStartRequest time for subframes.
+  </summary>
+</histogram>
+
 <histogram name="Navigation.IOSWKWebViewSlowFastBackForward"
     enum="BackForwardNavigationType">
   <owner>eugenebut@chromium.org</owner>
@@ -54553,6 +54619,25 @@
   </summary>
 </histogram>
 
+<histogram name="OfflinePages.PrefetchStore.StoreEvent"
+    enum="OfflinePagesStoreEvent">
+  <owner>fgorski@chromium.org</owner>
+  <summary>
+    Counts when the offline pages prefetch store is opened or closed.
+  </summary>
+</histogram>
+
+<histogram name="OfflinePages.PrefetchStore.TimeFromCloseToOpen" units="ms">
+  <owner>fgorski@chromium.org</owner>
+  <summary>
+    Tracks the time between store closing and reopening again within a session.
+    The store is meant to close itself after a period of inactivity. We are
+    trying to assess how much time the store is unloaded from memory vs. time it
+    is loaded and not used. This event will be reported when the store is opened
+    after being closed within the same lifetime of Chrome.
+  </summary>
+</histogram>
+
 <histogram name="OfflinePages.PrefetchUsage" enum="OfflinePagesPrefetchUsage">
   <owner>dimich@chromium.org</owner>
   <summary>
@@ -69606,13 +69691,28 @@
   </summary>
 </histogram>
 
+<histogram base="true"
+    name="RendererScheduler.ExpectedQueueingTimeByFrameStatus"
+    units="microseconds">
+  <owner>npm@chromium.org</owner>
+  <owner>tdresser@chromium.org</owner>
+  <summary>
+    Expected queueing time split by tasks according to their frame status, in
+    microseconds. The sum of the split values will be equal to the total,
+    reported on RendererScheduler.ExpectedTaskQueueingDuration2. This is
+    equivalent to RendererScheduler.ExpectedQueueingTimeByFrameType, just with
+    different units. Recorded for each 1000 ms window.
+  </summary>
+</histogram>
+
 <histogram base="true" name="RendererScheduler.ExpectedQueueingTimeByFrameType"
     units="ms">
   <owner>npm@chromium.org</owner>
   <summary>
     Expected queueing time split by tasks according to their frame type. The sum
     of the split values should be equal to the total, reported on
-    RendererScheduler.ExpectedQueueingTimeWhenQueueingTime.
+    RendererScheduler.ExpectedTaskQueueingDuration. Recorded for each 1000 ms
+    window.
   </summary>
 </histogram>
 
@@ -69622,7 +69722,8 @@
   <summary>
     Expected queueing time split by tasks according to the type of their task
     queue. The sum of the split values should be equal to the total, reported on
-    RendererScheduler.ExpectedQueueingTimeWhenQueueingTime.
+    RendererScheduler.ExpectedTaskQueueingDuration. Recorded for each 1000 ms
+    window.
   </summary>
 </histogram>
 
@@ -69647,6 +69748,17 @@
   </summary>
 </histogram>
 
+<histogram name="RendererScheduler.ExpectedTaskQueueingDuration2"
+    units="microseconds">
+  <owner>tdresser@chromium.org</owner>
+  <owner>npm@chromium.org</owner>
+  <summary>
+    The estimated queueing duration which would be observed for additional high
+    priority tasks posted to the RendererScheduler, in microseconds. Recorded
+    for each 1000 ms window.
+  </summary>
+</histogram>
+
 <histogram name="RendererScheduler.ForegroundRendererMainThreadLoad" units="%">
   <obsolete>
     Replaced with RendererScheduler.ForegroundRendererMainThreadLoad2 as of May
@@ -80009,6 +80121,16 @@
   <summary>Track how a user interfacts with the android signin promo.</summary>
 </histogram>
 
+<histogram name="Signin.AuthenticatedLaunchUserEvent"
+    enum="AuthenticatedLaunchUserEvent">
+  <owner>zmin@chromium.org</owner>
+  <summary>
+    Records the UI event when user clicks a locked profile on UserManager.
+    Please note that if the local reauth failed, UserManager might show Gaia
+    Reauth dialog.
+  </summary>
+</histogram>
+
 <histogram name="Signin.AuthError" enum="GoogleServiceAuthError">
   <owner>mlerman@chromium.org</owner>
   <summary>
@@ -93551,7 +93673,7 @@
   </summary>
 </histogram>
 
-<histogram name="VRDisplayPresentResult" enum="PresentationResult">
+<histogram name="VRDisplayPresentResult" enum="VRPresentationResult">
   <owner>billorr@chromium.org</owner>
   <summary>
     The result of calls to VRDisplay::requestPresent().  Reported twice per
@@ -95341,6 +95463,9 @@
 
 <histogram name="WebCore.ScriptedIdleTaskController.IdleCallbackDeadline"
     units="ms">
+  <obsolete>
+    Deprecated November 2017.
+  </obsolete>
   <owner>rmcilroy@chromium.org</owner>
   <summary>
     The amount of time allotted to a requestIdleCallback callback, i.e., the
@@ -107811,6 +107936,8 @@
   <suffix name="Other"
       label="Expected Queueing Time from events with detached or nonexistent
              frames."/>
+  <affected-histogram
+      name="RendererScheduler.ExpectedQueueingTimeByFrameStatus"/>
   <affected-histogram name="RendererScheduler.ExpectedQueueingTimeByFrameType"/>
 </histogram_suffixes>
 
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index a8102049..abc68bf 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -2073,11 +2073,23 @@
       metrics::TabEvent::ContentType.
     </summary>
   </metric>
+  <metric name="HasBeforeUnloadHandler">
+    <summary>
+      Boolean value indicating whether the page has a beforeunload JavaScript
+      event handler.
+    </summary>
+  </metric>
   <metric name="HasFormEntry">
     <summary>
       Boolean value indicating whether the page has any user-input text.
     </summary>
   </metric>
+  <metric name="IsExtensionProtected">
+    <summary>
+      True if an extension has marked this tab as non-discardable via the
+      chrome.tabs.update() extension API.
+    </summary>
+  </metric>
   <metric name="IsPinned">
     <summary>
       Boolean value indicating whether the tab is pinned in the tabstrip.
diff --git a/tools/perf/benchmarks/blink_perf_unittest.py b/tools/perf/benchmarks/blink_perf_unittest.py
index eef36b3..0136f58 100644
--- a/tools/perf/benchmarks/blink_perf_unittest.py
+++ b/tools/perf/benchmarks/blink_perf_unittest.py
@@ -5,6 +5,7 @@
 import unittest
 
 from telemetry import story
+from telemetry import decorators
 from telemetry.page import page as page_module
 from telemetry.testing import options_for_unittests
 from telemetry.testing import page_test_test_case
@@ -38,6 +39,7 @@
     story_set.AddStory(page)
     return story_set
 
+  @decorators.Disabled('android')  # crbug.com/793063
   def testBlinkPerfTracingMetricsForMeasureTime(self):
     results = self.RunMeasurement(measurement=self._measurement,
         ps=self._CreateStorySetForTestFile('append-child-measure-time.html'),
@@ -60,6 +62,7 @@
 
     self.assertGreater(update_layout_trees[0].GetRepresentativeNumber(), 0.001)
 
+  @decorators.Disabled('android')  # crbug.com/793063
   def testBlinkPerfTracingMetricsForMeasureFrameTime(self):
     results = self.RunMeasurement(measurement=self._measurement,
         ps=self._CreateStorySetForTestFile(
@@ -84,6 +87,7 @@
     self.assertGreater(frame_view_painttrees[0].GetRepresentativeNumber(),
         0.001)
 
+  @decorators.Disabled('android')  # crbug.com/793063
   def testBlinkPerfTracingMetricsForMeasurePageLoadTime(self):
     results = self.RunMeasurement(measurement=self._measurement,
         ps=self._CreateStorySetForTestFile(
diff --git a/tools/perf/benchmarks/v8_browsing.py b/tools/perf/benchmarks/v8_browsing.py
index 7303239..221abae 100644
--- a/tools/perf/benchmarks/v8_browsing.py
+++ b/tools/perf/benchmarks/v8_browsing.py
@@ -224,8 +224,8 @@
 
   def SetExtraBrowserOptions(self, options):
     options.AppendExtraBrowserArgs(
-      '--enable-blink-features=BlinkRuntimeCallStats '
-      '--enable-features=V8VmFuture')
+      '--enable-blink-features=BlinkRuntimeCallStats')
+    options.AppendExtraBrowserArgs('--enable-features=V8VmFuture')
 
   @classmethod
   def Name(cls):
@@ -240,7 +240,8 @@
 
   def SetExtraBrowserOptions(self, options):
     options.AppendExtraBrowserArgs(
-      '--enable-blink-features=BlinkRuntimeCallStats '
+      '--enable-blink-features=BlinkRuntimeCallStats')
+    options.AppendExtraBrowserArgs(
       '--enable-features=V8VmFuture')
 
   def GetExpectations(self):
diff --git a/tools/perf/chrome_telemetry_build/chromium_config.py b/tools/perf/chrome_telemetry_build/chromium_config.py
index 77887a63..fa5de39 100644
--- a/tools/perf/chrome_telemetry_build/chromium_config.py
+++ b/tools/perf/chrome_telemetry_build/chromium_config.py
@@ -17,7 +17,8 @@
 class ChromiumConfig(project_config.ProjectConfig):
 
   def __init__(self, top_level_dir=None, benchmark_dirs=None,
-               client_configs=None, default_chrome_root=None):
+               client_configs=None, default_chrome_root=None,
+               expectations_file=None):
     if client_configs is None:
       client_configs = [CLIENT_CONFIG_PATH]
     if default_chrome_root is None:
@@ -25,4 +26,5 @@
 
     super(ChromiumConfig, self).__init__(
         top_level_dir=top_level_dir, benchmark_dirs=benchmark_dirs,
-        client_configs=client_configs, default_chrome_root=default_chrome_root)
+        client_configs=client_configs, default_chrome_root=default_chrome_root,
+        expectations_file=expectations_file)
diff --git a/tools/traffic_annotation/auditor/instance.cc b/tools/traffic_annotation/auditor/instance.cc
index 119eae5..ba7699b 100644
--- a/tools/traffic_annotation/auditor/instance.cc
+++ b/tools/traffic_annotation/auditor/instance.cc
@@ -128,6 +128,13 @@
     return AuditorResult(AuditorResult::Type::ERROR_MISSING_TAG_USED, "",
                          file_path, line_number);
 
+  // TODO(crbug.com/656607): Remove this test.
+  // Process temporary tag.
+  if (unique_id_hash_code ==
+      NO_TRAFFIC_ANNOTATION_BUG_656607.unique_id_hash_code) {
+    return AuditorResult(AuditorResult::Type::RESULT_IGNORE);
+  }
+
   // Decode serialized proto.
   std::string annotation_text = "";
   while (start_line < end_line) {
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
index e176016..65ea72a3 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -37,7 +37,7 @@
     {PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code, "test_partial"},
     {NO_TRAFFIC_ANNOTATION_YET.unique_id_hash_code, "undefined"},
     {MISSING_TRAFFIC_ANNOTATION.unique_id_hash_code, "missing"},
-};
+    {NO_TRAFFIC_ANNOTATION_BUG_656607.unique_id_hash_code, "undefined-656607"}};
 
 struct AnnotationID {
   // Two ids can be the same in the following cases:
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
index b686af9..63ab3969 100644
--- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
+++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
@@ -350,7 +350,8 @@
       PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code,
       NO_TRAFFIC_ANNOTATION_YET.unique_id_hash_code,
       NO_PARTIAL_TRAFFIC_ANNOTATION_YET.unique_id_hash_code,
-      MISSING_TRAFFIC_ANNOTATION.unique_id_hash_code};
+      MISSING_TRAFFIC_ANNOTATION.unique_id_hash_code,
+      NO_TRAFFIC_ANNOTATION_BUG_656607.unique_id_hash_code};
 
   std::map<int, std::string> reserved_words =
       TrafficAnnotationAuditor::GetReservedUniqueIDs();
diff --git a/ui/accelerated_widget_mac/BUILD.gn b/ui/accelerated_widget_mac/BUILD.gn
index d75773655..de84377 100644
--- a/ui/accelerated_widget_mac/BUILD.gn
+++ b/ui/accelerated_widget_mac/BUILD.gn
@@ -10,6 +10,8 @@
     "accelerated_widget_mac.mm",
     "accelerated_widget_mac_export.h",
     "availability_macros.h",
+    "ca_layer_frame_sink.h",
+    "ca_layer_frame_sink.mm",
     "ca_layer_tree_coordinator.h",
     "ca_layer_tree_coordinator.mm",
     "ca_renderer_layer_tree.h",
diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.h b/ui/accelerated_widget_mac/accelerated_widget_mac.h
index cff0f38..ba03959 100644
--- a/ui/accelerated_widget_mac/accelerated_widget_mac.h
+++ b/ui/accelerated_widget_mac/accelerated_widget_mac.h
@@ -14,6 +14,7 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h"
+#include "ui/accelerated_widget_mac/ca_layer_frame_sink.h"
 #include "ui/base/cocoa/remote_layer_api.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
@@ -26,17 +27,29 @@
 // throughout its lifetime (one at a time, though).
 class AcceleratedWidgetMacNSView {
  public:
+  // The CALayer tree provided by the CALayerParams sent to the
+  // AcceleratedWidgetMac will be installed under the -[NSView layer] of this
+  // NSView.
   virtual NSView* AcceleratedWidgetGetNSView() const = 0;
+
+  // Retrieve the vsync parameters for the monitor on which the NSView currently
+  // is being displayed.
+  // TODO(ccameron): This is not the appropriate place for this function. A
+  // helper library to query monitor vsync parameters should be added.
   virtual void AcceleratedWidgetGetVSyncParameters(
     base::TimeTicks* timebase, base::TimeDelta* interval) const = 0;
+
+  // Called on swap completion. This is used to update background colors and to
+  // suppressing drawing of blank windows until content is available.
   virtual void AcceleratedWidgetSwapCompleted() = 0;
 };
 
 // AcceleratedWidgetMac owns a tree of CALayers. The widget may be passed
-// to a ui::Compositor, which will cause, through its output surface, calls to
-// GotAcceleratedFrame and GotSoftwareFrame. The CALayers may be installed
-// in an NSView by setting the AcceleratedWidgetMacNSView for the helper.
-class ACCELERATED_WIDGET_MAC_EXPORT AcceleratedWidgetMac {
+// to a ui::Compositor, which will, through its output surface, call the
+// CALayerFrameSink interface. The CALayers may be installed in an NSView
+// by setting the AcceleratedWidgetMacNSView for the helper.
+class ACCELERATED_WIDGET_MAC_EXPORT AcceleratedWidgetMac
+    : public CALayerFrameSink {
  public:
   AcceleratedWidgetMac();
   virtual ~AcceleratedWidgetMac();
@@ -49,17 +62,20 @@
   // Return true if the last frame swapped has a size in DIP of |dip_size|.
   bool HasFrameOfSize(const gfx::Size& dip_size) const;
 
-  // Populate the vsync parameters for the surface's display.
-  void GetVSyncParameters(
-      base::TimeTicks* timebase, base::TimeDelta* interval) const;
-
-  static AcceleratedWidgetMac* Get(gfx::AcceleratedWidget widget);
-
   // Translate from a gfx::AcceleratedWidget to the NSView in which it will
   // appear. This may return nil if |widget| is invalid or is not currently
   // attached to an NSView.
   static NSView* GetNSView(gfx::AcceleratedWidget widget);
 
+ private:
+  // For CALayerFrameSink::FromAcceleratedWidget to access Get.
+  friend class CALayerFrameSink;
+
+  // Translate from a gfx::AcceleratedWidget handle to the underlying
+  // AcceleratedWidgetMac (used by other gfx::AcceleratedWidget translation
+  // functions).
+  static AcceleratedWidgetMac* Get(gfx::AcceleratedWidget widget);
+
   void GotCALayerFrame(base::scoped_nsobject<CALayer> content_layer,
                        const gfx::Size& pixel_size,
                        float scale_factor);
@@ -67,12 +83,22 @@
                          const gfx::Size& pixel_size,
                          float scale_factor);
 
- private:
+  // gfx::CALayerFrameSink implementation:
+  void SetSuspended(bool suspended) override;
+  void UpdateCALayerTree(const gfx::CALayerParams& ca_layer_params) override;
+  void GetVSyncParameters(base::TimeTicks* timebase,
+                          base::TimeDelta* interval) const override;
+
   // The AcceleratedWidgetMacNSView that is using this as its internals.
-  AcceleratedWidgetMacNSView* view_;
+  AcceleratedWidgetMacNSView* view_ = nullptr;
 
   // A phony NSView handle used to identify this.
-  gfx::AcceleratedWidget native_widget_;
+  gfx::AcceleratedWidget native_widget_ = gfx::kNullAcceleratedWidget;
+
+  // If the output surface is suspended, then |remote_layer_| will be updated,
+  // but the NSView's layer hierarchy will remain unchanged.
+  bool is_suspended_ = false;
+  base::scoped_nsobject<CALayerHost> remote_layer_;
 
   // A flipped layer, which acts as the parent of the compositing and software
   // layers. This layer is flipped so that the we don't need to recompute the
diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.mm b/ui/accelerated_widget_mac/accelerated_widget_mac.mm
index 7f9d0b6..7ff59be 100644
--- a/ui/accelerated_widget_mac/accelerated_widget_mac.mm
+++ b/ui/accelerated_widget_mac/accelerated_widget_mac.mm
@@ -124,6 +124,43 @@
   return widget_mac->view_->AcceleratedWidgetGetNSView();
 }
 
+void AcceleratedWidgetMac::SetSuspended(bool is_suspended) {
+  is_suspended_ = is_suspended;
+}
+
+void AcceleratedWidgetMac::UpdateCALayerTree(
+    const gfx::CALayerParams& ca_layer_params) {
+  if (ca_layer_params.ca_context_id) {
+    if ([remote_layer_ contextId] != ca_layer_params.ca_context_id) {
+      remote_layer_.reset([[CALayerHost alloc] init]);
+      [remote_layer_ setContextId:ca_layer_params.ca_context_id];
+      [remote_layer_
+          setAutoresizingMask:kCALayerMaxXMargin | kCALayerMaxYMargin];
+    }
+  } else {
+    remote_layer_.reset();
+  }
+
+  if (is_suspended_)
+    return;
+
+  if (remote_layer_) {
+    GotCALayerFrame(base::scoped_nsobject<CALayer>(remote_layer_.get(),
+                                                   base::scoped_policy::RETAIN),
+                    ca_layer_params.pixel_size, ca_layer_params.scale_factor);
+  } else {
+    base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
+        IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
+    if (!io_surface) {
+      LOG(ERROR) << "Unable to open IOSurface for frame.";
+    }
+    GotIOSurfaceFrame(io_surface, ca_layer_params.pixel_size,
+                      ca_layer_params.scale_factor);
+  }
+  if (view_)
+    view_->AcceleratedWidgetSwapCompleted();
+}
+
 void AcceleratedWidgetMac::GotCALayerFrame(
     base::scoped_nsobject<CALayer> content_layer,
     const gfx::Size& pixel_size,
@@ -149,7 +186,6 @@
     [io_surface_layer_ removeFromSuperlayer];
     io_surface_layer_.reset();
   }
-  view_->AcceleratedWidgetSwapCompleted();
 }
 
 void AcceleratedWidgetMac::GotIOSurfaceFrame(
@@ -186,7 +222,6 @@
     [content_layer_ removeFromSuperlayer];
     content_layer_.reset();
   }
-  view_->AcceleratedWidgetSwapCompleted();
 }
 
 }  // namespace ui
diff --git a/ui/accelerated_widget_mac/ca_layer_frame_sink.h b/ui/accelerated_widget_mac/ca_layer_frame_sink.h
new file mode 100644
index 0000000..ed5e09e
--- /dev/null
+++ b/ui/accelerated_widget_mac/ca_layer_frame_sink.h
@@ -0,0 +1,38 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_H_
+#define UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_H_
+
+#include "base/time/time.h"
+#include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h"
+#include "ui/gfx/ca_layer_params.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace ui {
+
+// An interface to an NSView that will embed content described by CALayerParams
+// in its heirarchy.
+class ACCELERATED_WIDGET_MAC_EXPORT CALayerFrameSink {
+ public:
+  // Translate from a gfx::AcceleratedWidget to the gfx::CALayerFrameSink
+  // interface through which frames may be submitted. This may return nullptr.
+  static CALayerFrameSink* FromAcceleratedWidget(gfx::AcceleratedWidget widget);
+
+  // Update the embedder's CALayer tree to show the content described by
+  // |ca_layer_params|.
+  virtual void UpdateCALayerTree(const gfx::CALayerParams& ca_layer_params) = 0;
+
+  // Retrieve the vsync parameters for the monitor on which the embedder is
+  // currently displayed.
+  virtual void GetVSyncParameters(base::TimeTicks* timebase,
+                                  base::TimeDelta* interval) const = 0;
+
+  // If suspended, the embedder will ignore updates until un-supended.
+  virtual void SetSuspended(bool suspended) = 0;
+};
+
+}  // namespace ui
+
+#endif  // UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_H_
diff --git a/ui/accelerated_widget_mac/ca_layer_frame_sink.mm b/ui/accelerated_widget_mac/ca_layer_frame_sink.mm
new file mode 100644
index 0000000..b2a0edd
--- /dev/null
+++ b/ui/accelerated_widget_mac/ca_layer_frame_sink.mm
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/accelerated_widget_mac/ca_layer_frame_sink.h"
+
+#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
+
+namespace ui {
+
+// static
+CALayerFrameSink* CALayerFrameSink::FromAcceleratedWidget(
+    gfx::AcceleratedWidget widget) {
+  return AcceleratedWidgetMac::Get(widget);
+}
+
+}  // namespace ui
diff --git a/ui/accessibility/platform/ax_system_caret_win.cc b/ui/accessibility/platform/ax_system_caret_win.cc
index 82feb44..e533482d 100644
--- a/ui/accessibility/platform/ax_system_caret_win.cc
+++ b/ui/accessibility/platform/ax_system_caret_win.cc
@@ -18,31 +18,18 @@
 AXSystemCaretWin::AXSystemCaretWin(gfx::AcceleratedWidget event_target)
     : event_target_(event_target) {
   caret_ = static_cast<AXPlatformNodeWin*>(AXPlatformNodeWin::Create(this));
-  // The caret object is not part of the accessibility tree and so doesn't need
-  // a node ID. A globally unique ID is used when firing Win events, retrieved
-  // via |unique_id|.
-  data_.id = -1;
+  data_.id = GetNextAXPlatformNodeUniqueId();
   data_.role = AX_ROLE_CARET;
   // |get_accState| should return 0 which means that the caret is visible.
   data_.state = 0;
   // According to MSDN, "Edit" should be the name of the caret object.
   data_.SetName(L"Edit");
   data_.offset_container_id = -1;
-
-  if (event_target_) {
-    ::NotifyWinEvent(EVENT_OBJECT_CREATE, event_target_, OBJID_CARET,
-                     -caret_->unique_id());
-  }
 }
 
 AXSystemCaretWin::~AXSystemCaretWin() {
   caret_->Destroy();
-  // We shouldn't set |caret_| to nullptr because event clients might try to
-  // retrieve the destroyed object in this stack frame.
-  if (event_target_) {
-    ::NotifyWinEvent(EVENT_OBJECT_DESTROY, event_target_, OBJID_CARET,
-                     -caret_->unique_id());
-  }
+  caret_ = nullptr;
 }
 
 Microsoft::WRL::ComPtr<IAccessible> AXSystemCaretWin::GetCaret() const {
@@ -60,7 +47,7 @@
   data_.location = gfx::RectF(bounds);
   if (event_target_) {
     ::NotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, event_target_, OBJID_CARET,
-                     -caret_->unique_id());
+                     -data_.id);
   }
 }
 
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index d49fb02..66fd214 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -41,7 +41,6 @@
 import java.lang.ref.WeakReference;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 
 /**
  * The window base class that has the minimum functionality.
@@ -125,8 +124,8 @@
     public interface KeyboardVisibilityListener {
         public void keyboardVisibilityChanged(boolean isShowing);
     }
-    private LinkedList<KeyboardVisibilityListener> mKeyboardVisibilityListeners =
-            new LinkedList<>();
+    private ObserverList<KeyboardVisibilityListener> mKeyboardVisibilityListeners =
+            new ObserverList<>();
 
     /**
      * An interface to notify listeners that a context menu is closed.
@@ -641,14 +640,14 @@
         if (mKeyboardVisibilityListeners.isEmpty()) {
             registerKeyboardVisibilityCallbacks();
         }
-        mKeyboardVisibilityListeners.add(listener);
+        mKeyboardVisibilityListeners.addObserver(listener);
     }
 
     /**
      * @see #addKeyboardVisibilityListener(KeyboardVisibilityListener)
      */
     public void removeKeyboardVisibilityListener(KeyboardVisibilityListener listener) {
-        mKeyboardVisibilityListeners.remove(listener);
+        mKeyboardVisibilityListeners.removeObserver(listener);
         if (mKeyboardVisibilityListeners.isEmpty()) {
             unregisterKeyboardVisibilityCallbacks();
         }
@@ -689,10 +688,7 @@
         if (mIsKeyboardShowing == isShowing) return;
         mIsKeyboardShowing = isShowing;
 
-        // Clone the list in case a listener tries to remove itself during the callback.
-        LinkedList<KeyboardVisibilityListener> listeners =
-                new LinkedList<>(mKeyboardVisibilityListeners);
-        for (KeyboardVisibilityListener listener : listeners) {
+        for (KeyboardVisibilityListener listener : mKeyboardVisibilityListeners) {
             listener.keyboardVisibilityChanged(isShowing);
         }
     }
diff --git a/ui/app_list/views/search_result_view.cc b/ui/app_list/views/search_result_view.cc
index 32f515a..4fd2a7d 100644
--- a/ui/app_list/views/search_result_view.cc
+++ b/ui/app_list/views/search_result_view.cc
@@ -154,8 +154,7 @@
 }
 
 void SearchResultView::CreateTitleRenderText() {
-  std::unique_ptr<gfx::RenderText> render_text(
-      gfx::RenderText::CreateInstance());
+  auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
   render_text->SetText(result_->title());
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   render_text->SetFontList(
@@ -184,8 +183,7 @@
     details_text_.reset();
     return;
   }
-  std::unique_ptr<gfx::RenderText> render_text(
-      gfx::RenderText::CreateInstance());
+  auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
   render_text->SetText(result_->details());
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   render_text->SetFontList(rb.GetFontList(ui::ResourceBundle::BaseFont));
diff --git a/ui/aura/local/window_port_local.cc b/ui/aura/local/window_port_local.cc
index 2216747..d19d879 100644
--- a/ui/aura/local/window_port_local.cc
+++ b/ui/aura/local/window_port_local.cc
@@ -71,7 +71,7 @@
   if (last_device_scale_factor_ != new_device_scale_factor &&
       local_surface_id_.is_valid()) {
     last_device_scale_factor_ = new_device_scale_factor;
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
     if (frame_sink_)
       frame_sink_->SetLocalSurfaceId(local_surface_id_);
   }
@@ -96,7 +96,7 @@
                                         const gfx::Rect& new_bounds) {
   if (last_size_ != new_bounds.size() && local_surface_id_.is_valid()) {
     last_size_ = new_bounds.size();
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
     if (frame_sink_)
       frame_sink_->SetLocalSurfaceId(local_surface_id_);
   }
@@ -141,7 +141,7 @@
 void WindowPortLocal::AllocateLocalSurfaceId() {
   last_device_scale_factor_ = ui::GetScaleFactorForNativeView(window_);
   last_size_ = window_->bounds().size();
-  local_surface_id_ = local_surface_id_allocator_.GenerateId();
+  local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
   if (frame_sink_)
     frame_sink_->SetLocalSurfaceId(local_surface_id_);
 }
diff --git a/ui/aura/local/window_port_local.h b/ui/aura/local/window_port_local.h
index ca00602..be24ab4f 100644
--- a/ui/aura/local/window_port_local.h
+++ b/ui/aura/local/window_port_local.h
@@ -8,7 +8,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "ui/aura/local/layer_tree_frame_sink_local.h"
 #include "ui/aura/window_port.h"
 #include "ui/base/property_data.h"
@@ -63,7 +63,7 @@
   gfx::Size last_size_;
   float last_device_scale_factor_ = 1.0f;
   viz::LocalSurfaceId local_surface_id_;
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
   base::WeakPtr<aura::LayerTreeFrameSinkLocal> frame_sink_;
 
   base::WeakPtrFactory<WindowPortLocal> weak_factory_;
diff --git a/ui/aura/mus/mus_context_factory.cc b/ui/aura/mus/mus_context_factory.cc
index 8d8103c..9526517 100644
--- a/ui/aura/mus/mus_context_factory.cc
+++ b/ui/aura/mus/mus_context_factory.cc
@@ -64,7 +64,7 @@
 MusContextFactory::SharedMainThreadContextProvider() {
   if (!shared_main_thread_context_provider_) {
     scoped_refptr<gpu::GpuChannelHost> gpu_channel =
-        gpu_->EstablishGpuChannelSync(nullptr);
+        gpu_->EstablishGpuChannelSync();
     shared_main_thread_context_provider_ =
         gpu_->CreateContextProvider(std::move(gpu_channel));
     if (shared_main_thread_context_provider_->BindToCurrentThread() !=
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc
index 8e70381..e520a16 100644
--- a/ui/aura/mus/window_port_mus.cc
+++ b/ui/aura/mus/window_port_mus.cc
@@ -307,7 +307,7 @@
     return local_surface_id_;
   }
 
-  local_surface_id_ = local_surface_id_allocator_.GenerateId();
+  local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
   last_surface_size_in_pixels_ = surface_size_in_pixels;
 
   // If the FrameSinkId is available, then immediately embed the SurfaceId.
@@ -398,7 +398,7 @@
 }
 
 void WindowPortMus::AllocateLocalSurfaceId() {
-  local_surface_id_ = local_surface_id_allocator_.GenerateId();
+  local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
 }
 
 const viz::LocalSurfaceId& WindowPortMus::GetLocalSurfaceId() {
@@ -457,7 +457,7 @@
 void WindowPortMus::OnDeviceScaleFactorChanged(float old_device_scale_factor,
                                                float new_device_scale_factor) {
   if (local_surface_id_.is_valid() && local_layer_tree_frame_sink_) {
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
     local_layer_tree_frame_sink_->SetLocalSurfaceId(local_surface_id_);
   }
   window_tree_client_->OnWindowMusDeviceScaleFactorChanged(
diff --git a/ui/aura/mus/window_port_mus.h b/ui/aura/mus/window_port_mus.h
index 6ded27f..2421d91 100644
--- a/ui/aura/mus/window_port_mus.h
+++ b/ui/aura/mus/window_port_mus.h
@@ -294,7 +294,7 @@
   viz::SurfaceInfo fallback_surface_info_;
 
   viz::LocalSurfaceId local_surface_id_;
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
+  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
   gfx::Size last_surface_size_in_pixels_;
 
   ui::CursorData cursor_;
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h
index 0aacfd4..1906821 100644
--- a/ui/aura/mus/window_tree_client.h
+++ b/ui/aura/mus/window_tree_client.h
@@ -19,7 +19,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/single_thread_task_runner.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "services/ui/public/interfaces/remote_event_dispatcher.mojom.h"
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index beab73d..04840b9f 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -34,7 +34,7 @@
 #include "components/viz/common/gpu/context_provider.h"
 #include "components/viz/common/resources/resource_format.h"
 #include "components/viz/common/resources/resource_settings.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/host/host_frame_sink_manager.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -651,6 +651,11 @@
   return lock;
 }
 
+void Compositor::RequestPresentationTimeForNextFrame(
+    PresentationTimeCallback callback) {
+  host_->RequestPresentationTimeForNextFrame(std::move(callback));
+}
+
 void Compositor::RemoveCompositorLock(CompositorLock* lock) {
   base::Erase(active_locks_, lock);
   if (active_locks_.empty()) {
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 00885cb..981727c5 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <string>
 
+#include "base/callback_forward.h"
 #include "base/containers/hash_tables.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -355,17 +356,14 @@
       base::TimeDelta timeout =
           base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
 
-  // Internal functions, called back by command-buffer contexts on swap buffer
-  // events.
-
-  // Signals swap has been posted.
-  void OnSwapBuffersPosted();
-
-  // Signals swap has completed.
-  void OnSwapBuffersComplete();
-
-  // Signals swap has aborted (e.g. lost context).
-  void OnSwapBuffersAborted();
+  // Registers a callback that is run when the next frame successfully makes it
+  // to the screen (it's entirely possible some frames may be dropped between
+  // the time this is called and the callback is run).
+  // See ui/gfx/presentation_feedback.h for details on the args (TimeTicks is
+  // always non-zero).
+  using PresentationTimeCallback =
+      base::OnceCallback<void(base::TimeTicks, base::TimeDelta, uint32_t)>;
+  void RequestPresentationTimeForNextFrame(PresentationTimeCallback callback);
 
   // LayerTreeHostClient implementation.
   void WillBeginMainFrame() override {}
diff --git a/ui/compositor/compositor_unittest.cc b/ui/compositor/compositor_unittest.cc
index 873001c..08ce8b9 100644
--- a/ui/compositor/compositor_unittest.cc
+++ b/ui/compositor/compositor_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/surfaces/surface_manager.h"
 #include "components/viz/test/begin_frame_args_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index 7aef1ee..b6cd30de 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -16,7 +16,7 @@
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/frame_sinks/delay_based_time_source.h"
 #include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/common/surfaces/local_surface_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/host/host_frame_sink_manager.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/display/display_scheduler.h"
diff --git a/ui/display/display_change_notifier_unittest.cc b/ui/display/display_change_notifier_unittest.cc
index 69e82b4d..af69515 100644
--- a/ui/display/display_change_notifier_unittest.cc
+++ b/ui/display/display_change_notifier_unittest.cc
@@ -364,7 +364,7 @@
 
     change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
     EXPECT_EQ(1, observer.display_changed());
-    EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_BOUNDS,
+    EXPECT_EQ(static_cast<uint32_t>(DisplayObserver::DISPLAY_METRIC_BOUNDS),
               observer.latest_metrics_change());
 
     change_notifier.RemoveObserver(&observer);
@@ -384,7 +384,7 @@
 
   change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
   EXPECT_EQ(1, observer.display_changed());
-  EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_ROTATION,
+  EXPECT_EQ(static_cast<uint32_t>(DisplayObserver::DISPLAY_METRIC_ROTATION),
             observer.latest_metrics_change());
 }
 
@@ -401,7 +401,7 @@
 
   change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
   EXPECT_EQ(1, observer.display_changed());
-  EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_WORK_AREA,
+  EXPECT_EQ(static_cast<uint32_t>(DisplayObserver::DISPLAY_METRIC_WORK_AREA),
             observer.latest_metrics_change());
 }
 
@@ -418,7 +418,8 @@
 
   change_notifier.NotifyDisplaysChanged(old_displays, new_displays);
   EXPECT_EQ(1, observer.display_changed());
-  EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR,
+  EXPECT_EQ(static_cast<uint32_t>(
+                DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR),
             observer.latest_metrics_change());
 }
 
diff --git a/ui/file_manager/externs/volume_info.js b/ui/file_manager/externs/volume_info.js
index 5e2017e..26a6d8b 100644
--- a/ui/file_manager/externs/volume_info.js
+++ b/ui/file_manager/externs/volume_info.js
@@ -74,7 +74,13 @@
 VolumeInfo.prototype.label;
 
 /**
- * ID of an extennsion providing this volume.
+ * ID of a provider for this volume.
+ * @type {(string|undefined)}
+ */
+VolumeInfo.prototype.providerId;
+
+/**
+ * ID of a providing extension for this volume.
  * @type {(string|undefined)}
  */
 VolumeInfo.prototype.extensionId;
diff --git a/ui/file_manager/file_manager/background/js/mock_volume_manager.js b/ui/file_manager/file_manager/background/js/mock_volume_manager.js
index d6e747ca..35ec9157 100644
--- a/ui/file_manager/file_manager/background/js/mock_volume_manager.js
+++ b/ui/file_manager/file_manager/background/js/mock_volume_manager.js
@@ -129,19 +129,18 @@
   fileSystem.entries['/'] = new MockDirectoryEntry(fileSystem, '');
 
   var volumeInfo = new VolumeInfoImpl(
-      type,
-      volumeId,
-      fileSystem,
-      '',      // error
-      '',      // deviceType
-      '',      // devicePath
-      false,   // isReadOnly
-      false,   // isReadOnlyRemovableDevice
+      type, volumeId, fileSystem,
+      '',                                         // error
+      '',                                         // deviceType
+      '',                                         // devicePath
+      false,                                      // isReadOnly
+      false,                                      // isReadOnlyRemovableDevice
       {isCurrentProfile: true, displayName: ''},  // profile
-      label,   // label
-      '',      // extensionId
-      false,   // hasMedia
-      false);  // configurable
+      label,                                      // label
+      undefined,                                  // providerId
+      undefined,                                  // extensionId
+      false,                                      // hasMedia
+      false);                                     // configurable
 
   return volumeInfo;
 };
@@ -273,17 +272,16 @@
   var fileSystem = new MockFileSystem(volumeId, 'filesystem:' + volumeId);
   fileSystem.entries['/'] = new MockDirectoryEntry(fileSystem, '');
   var volumeInfo = new VolumeInfoImpl(
-      type,
-      volumeId,
-      fileSystem,
-      '',     // error
-      '',     // deviceType
-      '',     // devicePath
-      false,  // isReadonly
-      false,  // isReadOnlyRemovableDevice
+      type, volumeId, fileSystem,
+      '',                                         // error
+      '',                                         // deviceType
+      '',                                         // devicePath
+      false,                                      // isReadonly
+      false,                                      // isReadOnlyRemovableDevice
       {isCurrentProfile: true, displayName: ''},  // profile
-      label,  // label
-      '',     // extensionId
-      false); // hasMedia
+      label,                                      // label
+      undefined,                                  // providerId
+      undefined,                                  // extensionId
+      false);                                     // hasMedia
   return volumeInfo;
 };
diff --git a/ui/file_manager/file_manager/background/js/volume_info_impl.js b/ui/file_manager/file_manager/background/js/volume_info_impl.js
index fcb9e40..0aafaa5 100644
--- a/ui/file_manager/file_manager/background/js/volume_info_impl.js
+++ b/ui/file_manager/file_manager/background/js/volume_info_impl.js
@@ -25,8 +25,10 @@
  * @param {!{displayName:string, isCurrentProfile:boolean}} profile Profile
  *     information.
  * @param {string} label Label of the volume.
- * @param {(string|undefined)} extensionId Id of the extension providing this
- *     volume. Empty for native volumes.
+ * @param {(string|undefined)} providerId Id of the provider for this volume.
+ *     Undefined for non-FSP volumes.
+ * @param {(string|undefined)} extensionId Id of the providing extension, if
+ *     the provider for this volume is an extension. Otherwise undefined.
  * @param {boolean} hasMedia When true the volume has been identified
  *     as containing media such as photos or videos.
  * @param {boolean} configurable When true, then the volume can be configured.
@@ -36,8 +38,8 @@
  */
 function VolumeInfoImpl(
     volumeType, volumeId, fileSystem, error, deviceType, devicePath, isReadOnly,
-    isReadOnlyRemovableDevice, profile, label, extensionId, hasMedia,
-    configurable, watchable, source, diskFileSystemType) {
+    isReadOnlyRemovableDevice, profile, label, providerId, extensionId,
+    hasMedia, configurable, watchable, source, diskFileSystemType) {
   this.volumeType_ = volumeType;
   this.volumeId_ = volumeId;
   this.fileSystem_ = fileSystem;
@@ -81,6 +83,7 @@
   this.isReadOnly_ = isReadOnly;
   this.isReadOnlyRemovableDevice_ = isReadOnlyRemovableDevice;
   this.profile_ = Object.freeze(profile);
+  this.providerId_ = providerId;
   this.extensionId_ = extensionId;
   this.hasMedia_ = hasMedia;
   this.configurable_ = configurable;
@@ -172,7 +175,13 @@
     return this.label_;
   },
   /**
-   * @return {(string|undefined)} Id of an extennsion providing this volume.
+   * @return {(string|undefined)} Id of a provider for this volume.
+   */
+  get providerId() {
+    return this.providerId_;
+  },
+  /**
+   * @return {(string|undefined)} Id of a providing extension for this volume.
    */
   get extensionId() {
     return this.extensionId_;
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_util.js b/ui/file_manager/file_manager/background/js/volume_manager_util.js
index af1503f..7aa264a9 100644
--- a/ui/file_manager/file_manager/background/js/volume_manager_util.js
+++ b/ui/file_manager/file_manager/background/js/volume_manager_util.js
@@ -155,7 +155,8 @@
             volumeMetadata.mountCondition, volumeMetadata.deviceType,
             volumeMetadata.devicePath, volumeMetadata.isReadOnly,
             volumeMetadata.isReadOnlyRemovableDevice, volumeMetadata.profile,
-            localizedLabel, volumeMetadata.extensionId, volumeMetadata.hasMedia,
+            localizedLabel, volumeMetadata.providerId,
+            volumeMetadata.extensionId, volumeMetadata.hasMedia,
             volumeMetadata.configurable, volumeMetadata.watchable,
             /** @type {VolumeManagerCommon.Source} */
             (volumeMetadata.source),
@@ -179,7 +180,8 @@
             volumeMetadata.mountCondition, volumeMetadata.deviceType,
             volumeMetadata.devicePath, volumeMetadata.isReadOnly,
             volumeMetadata.isReadOnlyRemovableDevice, volumeMetadata.profile,
-            localizedLabel, volumeMetadata.extensionId, volumeMetadata.hasMedia,
+            localizedLabel, volumeMetadata.providerId,
+            volumeMetadata.extensionId, volumeMetadata.hasMedia,
             volumeMetadata.configurable, volumeMetadata.watchable,
             /** @type {VolumeManagerCommon.Source} */
             (volumeMetadata.source),
@@ -212,8 +214,8 @@
   }
   var volumeType = volumeMetadata.volumeType;
   if (volumeMetadata.volumeType === VolumeManagerCommon.VolumeType.PROVIDED) {
-    volumeType += ':' + metrics.getFileSystemProviderName(
-        volumeMetadata.extensionId);
+    volumeType +=
+        ':' + metrics.getFileSystemProviderName(volumeMetadata.providerId);
   }
   var description = 'mount ' + errorType + ' ' + volumeType;
   var fatal =
diff --git a/ui/file_manager/file_manager/common/js/metrics_events.js b/ui/file_manager/file_manager/common/js/metrics_events.js
index 8ad1430..09126809 100644
--- a/ui/file_manager/file_manager/common/js/metrics_events.js
+++ b/ui/file_manager/file_manager/common/js/metrics_events.js
@@ -34,15 +34,18 @@
 };
 
 /**
- * Enumeration of known FSPs used to qualify "provided" extensions
+ * Enumeration of known FSPs used to qualify "providers"
  * "screens" on analytics. All FSPs NOT present in this list
  * will be reported to analytics as 'provided-unknown'.
  *
  * NOTE: When an unknown provider is encountered, a separate event will be
  * sent to analytics with the id. Consulation of that event will provided
- * an indication when an extension is popular enough to be added to the
+ * an indication when a provider is popular enough to be added to the
  * whitelist.
  *
+ * These look like extension ids, but are actually provider ids which may
+ * but don't have to be extension ids.
+ *
  * @enum {string}
  */
 metrics.FileSystemProviders = {
@@ -66,11 +69,11 @@
 /**
  * Returns a new "screen" name for a provided file system type. Returns
  * 'unknown' for unknown providers.
- * @param {string|undefined} extensionId The FSP provider extension ID.
+ * @param {string|undefined} providerId The FSP provider ID.
  * @return {string} Name or 'unknown' if extension is unrecognized.
  */
-metrics.getFileSystemProviderName = function(extensionId) {
-  return metrics.FileSystemProviders[extensionId] || 'unknown';
+metrics.getFileSystemProviderName = function(providerId) {
+  return metrics.FileSystemProviders[providerId] || 'unknown';
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js
index 29d6402..c4dabc1 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -1019,18 +1019,17 @@
                               volumeInfo.volumeType;
                         });
               case VolumeManagerCommon.VolumeType.PROVIDED:
-                var extensionId = volumeInfo.extensionId;
-                var extensionName =
-                    metrics.getFileSystemProviderName(extensionId);
-                // Make note of an unrecognized extension id. When we see
+                var providerId = volumeInfo.providerId;
+                var name = metrics.getFileSystemProviderName(providerId);
+                // Make note of an unrecognized provider id. When we see
                 // high counts for a particular id, we should add it to the
                 // whitelist in metrics_events.js.
-                if (extensionId && extensionName == 'unknown') {
+                if (providerId && name == 'unknown') {
                   this.tracker_.send(
-                      metrics.Internals.UNRECOGNIZED_FILE_SYSTEM_PROVIDER
-                          .label(extensionId));
+                      metrics.Internals.UNRECOGNIZED_FILE_SYSTEM_PROVIDER.label(
+                          providerId));
                 }
-                return volumeInfo.volumeType + ':' + extensionName;
+                return volumeInfo.volumeType + ':' + name;
               default:
                 return volumeInfo.volumeType;
             }
@@ -1250,14 +1249,14 @@
  */
 DirectoryModel.prototype.getLastSearchQuery = function() {
   return this.lastSearchQuery_;
-}
+};
 
 /**
  * Clears the last search query with the empty string.
  */
 DirectoryModel.prototype.clearLastSearchQuery = function() {
   this.lastSearchQuery_ = '';
-}
+};
 
 /**
  * Performs search and displays results. The search type is dependent on the
diff --git a/ui/file_manager/file_manager/foreground/js/providers_model.js b/ui/file_manager/file_manager/foreground/js/providers_model.js
index 9e72a6c..cd772417 100644
--- a/ui/file_manager/file_manager/foreground/js/providers_model.js
+++ b/ui/file_manager/file_manager/foreground/js/providers_model.js
@@ -6,8 +6,9 @@
 /**
  * An item in the model. Represents a single providing extension.
  *
- * @param {string} extensionId
- * @param {string} extensionName
+ * @param {string} providerId
+ * @param {string|undefined} extensionId
+ * @param {string} name
  * @param {boolean} configurable
  * @param {boolean} watchable
  * @param {boolean} multipleMounts
@@ -16,19 +17,25 @@
  * @struct
  */
 function ProvidersModelItem(
-    extensionId, extensionName, configurable, watchable, multipleMounts,
+    providerId, extensionId, name, configurable, watchable, multipleMounts,
     source) {
   /**
    * @private {string}
    * @const
    */
+  this.providerId_ = providerId;
+
+  /**
+   * @private {string|undefined}
+   * @const
+   */
   this.extensionId_ = extensionId;
 
   /**
    * @private {string}
    * @const
    */
-  this.extensionName_ = extensionName;
+  this.name_ = name;
 
   /**
    * @private {boolean}
@@ -59,32 +66,51 @@
   /**
    * @return {string}
    */
-  get extensionId() { return this.extensionId_; },
+  get providerId() {
+    return this.providerId_;
+  },
+
+  /**
+   * @return {string|undefined}
+   */
+  get extensionId() {
+    return this.extensionId_;
+  },
 
   /**
    * @return {string}
    */
-  get extensionName() { return this.extensionName_; },
+  get name() {
+    return this.name_;
+  },
 
   /**
    * @return {boolean}
    */
-  get configurable() { return this.configurable_; },
+  get configurable() {
+    return this.configurable_;
+  },
 
   /**
    * @return {boolean}
    */
-  get watchable() { return this.watchable_; },
+  get watchable() {
+    return this.watchable_;
+  },
 
   /**
    * @return {boolean}
    */
-  get multipleMounts() { return this.multipleMounts_; },
+  get multipleMounts() {
+    return this.multipleMounts_;
+  },
 
   /**
    * @return {string}
    */
-  get source() { return this.source_; }
+  get source() {
+    return this.source_;
+  }
 };
 
 /**
@@ -108,57 +134,52 @@
  * @return {!Promise<Array<ProvidersModelItem>>}
  */
 ProvidersModel.prototype.getInstalledProviders = function() {
-  return new Promise(
-      function(fulfill, reject) {
-        chrome.fileManagerPrivate.getProvidingExtensions(function(extensions) {
-          if (chrome.runtime.lastError) {
-            reject(chrome.runtime.lastError.message);
-            return;
-          }
-          var results = [];
-          extensions.forEach(function(extension) {
-            results.push(new ProvidersModelItem(
-                extension.extensionId,
-                extension.name,
-                extension.configurable,
-                extension.watchable,
-                extension.multipleMounts,
-                extension.source));
-          });
-          fulfill(results);
-        });
+  return new Promise(function(fulfill, reject) {
+    chrome.fileManagerPrivate.getProviders(function(providers) {
+      if (chrome.runtime.lastError) {
+        reject(chrome.runtime.lastError.message);
+        return;
+      }
+      var results = [];
+      providers.forEach(function(provider) {
+        results.push(new ProvidersModelItem(
+            provider.providerId, provider.extensionId, provider.name,
+            provider.configurable, provider.watchable, provider.multipleMounts,
+            provider.source));
       });
+      fulfill(results);
+    });
+  });
 };
 
 /**
  * @return {!Promise<Array<ProvidersModelItem>>}
  */
 ProvidersModel.prototype.getMountableProviders = function() {
-  return this.getInstalledProviders().then(function(extensions) {
+  return this.getInstalledProviders().then(function(providers) {
     var mountedProviders = {};
     for (var i = 0; i < this.volumeManager_.volumeInfoList.length; i++) {
       var volumeInfo = this.volumeManager_.volumeInfoList.item(i);
       if (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.PROVIDED)
-        mountedProviders[volumeInfo.extensionId] = true;
+        mountedProviders[volumeInfo.providerId] = true;
     }
-    return extensions.filter(function(item) {
+    return providers.filter(function(item) {
       // File systems handling files are mounted via file handlers. Device
       // handlers are mounted when a device is inserted. Only network file
       // systems are mounted manually by user via a menu.
       return item.source === 'network' &&
-          (!mountedProviders[item.extensionId] || item.multipleMounts);
+          (!mountedProviders[item.providerId] || item.multipleMounts);
     });
   }.bind(this));
 };
 
 /**
- * @param {string} extensionId
+ * @param {string} providerId
  */
-ProvidersModel.prototype.requestMount = function(extensionId) {
+ProvidersModel.prototype.requestMount = function(providerId) {
   chrome.fileManagerPrivate.addProvidedFileSystem(
-      assert(extensionId),
-      function() {
+      assert(providerId), function() {
         if (chrome.runtime.lastError)
-            console.error(chrome.runtime.lastError.message);
+          console.error(chrome.runtime.lastError.message);
       });
 };
diff --git a/ui/file_manager/file_manager/foreground/js/providers_model_unittest.js b/ui/file_manager/file_manager/foreground/js/providers_model_unittest.js
index ed468e53..98eac142 100644
--- a/ui/file_manager/file_manager/foreground/js/providers_model_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/providers_model_unittest.js
@@ -11,6 +11,7 @@
 // A providing extension which has mounted a file system, and doesn't support
 // multiple mounts.
 var MOUNTED_SINGLE_PROVIDING_EXTENSION = {
+  providerId: 'mounted-single-provider-id',
   extensionId: 'mounted-single-extension-id',
   name: 'mounted-single-extension-name',
   configurable: false,
@@ -22,6 +23,7 @@
 // A providing extension which has not mounted a file system, and doesn't
 // support  multiple mounts.
 var NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION = {
+  providerId: 'not-mounted-single-provider-id',
   extensionId: 'not-mounted-single-extension-id',
   name: 'not-mounted-single-extension-name',
   configurable: false,
@@ -32,6 +34,7 @@
 // A providing extension which has not mounted a file system, and doesn't
 // support  multiple mounts.
 var NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION = {
+  providerId: 'not-mounted-single-provider-id',
   extensionId: 'not-mounted-single-extension-id',
   name: 'not-mounted-single-extension-name',
   configurable: false,
@@ -43,6 +46,7 @@
 // A providing extension which has mounted a file system and supports mounting
 // more.
 var MOUNTED_MULTIPLE_PROVIDING_EXTENSION = {
+  providerId: 'mounted-multiple-provider-id',
   extensionId: 'mounted-multiple-extension-id',
   name: 'mounted-multiple-extension-name',
   configurable: true,
@@ -52,8 +56,9 @@
 };
 
 // A providing extension which has not mounted a file system but it's of "file"
-// source. Such extensions do mounting via file handlers.
+// source. Such providers do mounting via file handlers.
 var NOT_MOUNTED_FILE_PROVIDING_EXTENSION = {
+  providerId: 'file-provider-id',
   extensionId: 'file-extension-id',
   name: 'file-extension-name',
   configurable: false,
@@ -63,9 +68,10 @@
 };
 
 // A providing extension which has not mounted a file system but it's of
-// "device" source. Such extensions are not mounted by user, but automatically
+// "device" source. Such providers are not mounted by user, but automatically
 // when the device is attached.
 var NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION = {
+  providerId: 'device-provider-id',
   extensionId: 'device-extension-id',
   name: 'device-extension-name',
   configurable: false,
@@ -76,31 +82,30 @@
 
 var volumeManager = null;
 
-function addProvidedVolume(volumeManager, extensionId, volumeId) {
+function addProvidedVolume(volumeManager, providerId, volumeId) {
   var fileSystem = new MockFileSystem(volumeId, 'filesystem:' + volumeId);
   fileSystem.entries['/'] = new MockDirectoryEntry(fileSystem, '');
 
   var volumeInfo = new VolumeInfoImpl(
-      VolumeManagerCommon.VolumeType.PROVIDED,
-      volumeId,
-      fileSystem,
-      '',           // error
-      '',           // deviceType
-      '',           // devicePath
-      false,        // isReadonly
-      false,        // isReadonlyRemovableDevice
+      VolumeManagerCommon.VolumeType.PROVIDED, volumeId, fileSystem,
+      '',                                         // error
+      '',                                         // deviceType
+      '',                                         // devicePath
+      false,                                      // isReadonly
+      false,                                      // isReadonlyRemovableDevice
       {isCurrentProfile: true, displayName: ''},  // profile
-      '',           // label
-      extensionId,  // extensionId
-      false);       // hasMedia
+      '',                                         // label
+      providerId,                                 // providerId
+      false);                                     // hasMedia
 
   volumeManager.volumeInfoList.push(volumeInfo);
 }
 
 function setUp() {
-  // Create a dummy API for fetching a list of providing extensions.
+  // Create a dummy API for fetching a list of providers.
+  // TODO(mtomasz): Add some native (non-extension) providers.
   chrome.fileManagerPrivate = {
-    getProvidingExtensions: function(callback) {
+    getProviders: function(callback) {
       callback([MOUNTED_SINGLE_PROVIDING_EXTENSION,
                 NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION,
                 MOUNTED_MULTIPLE_PROVIDING_EXTENSION,
@@ -113,49 +118,78 @@
 
   // Create a dummy volume manager.
   volumeManager = new MockVolumeManagerWrapper();
-  addProvidedVolume(volumeManager,
-      MOUNTED_SINGLE_PROVIDING_EXTENSION.extensionId, 'volume-1');
-  addProvidedVolume(volumeManager,
-      MOUNTED_MULTIPLE_PROVIDING_EXTENSION.extensionId, 'volume-2');
+  addProvidedVolume(
+      volumeManager, MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId, 'volume-1');
+  addProvidedVolume(
+      volumeManager, MOUNTED_MULTIPLE_PROVIDING_EXTENSION.providerId,
+      'volume-2');
 }
 
 function testGetInstalledProviders(callback) {
   var model = new ProvidersModel(volumeManager);
-  reportPromise(model.getInstalledProviders().then(
-      function(extensions) {
-        assertEquals(5, extensions.length);
-        assertEquals(MOUNTED_SINGLE_PROVIDING_EXTENSION.extensionId,
-            extensions[0].extensionId);
-        assertEquals(MOUNTED_SINGLE_PROVIDING_EXTENSION.name,
-            extensions[0].extensionName);
-        assertEquals(MOUNTED_SINGLE_PROVIDING_EXTENSION.configurable,
-            extensions[0].configurable);
-        assertEquals(MOUNTED_SINGLE_PROVIDING_EXTENSION.watchable,
-            extensions[0].watchable);
-        assertEquals(MOUNTED_SINGLE_PROVIDING_EXTENSION.multipleMounts,
-            extensions[0].multipleMounts);
-        assertEquals(MOUNTED_SINGLE_PROVIDING_EXTENSION.source,
-            extensions[0].source);
+  reportPromise(
+      model.getInstalledProviders().then(function(providers) {
+        assertEquals(5, providers.length);
+        assertEquals(
+            MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId,
+            providers[0].providerId);
+        assertEquals(
+            MOUNTED_SINGLE_PROVIDING_EXTENSION.extensionId,
+            providers[0].extensionId);
+        assertEquals(
+            MOUNTED_SINGLE_PROVIDING_EXTENSION.name, providers[0].name);
+        assertEquals(
+            MOUNTED_SINGLE_PROVIDING_EXTENSION.configurable,
+            providers[0].configurable);
+        assertEquals(
+            MOUNTED_SINGLE_PROVIDING_EXTENSION.watchable,
+            providers[0].watchable);
+        assertEquals(
+            MOUNTED_SINGLE_PROVIDING_EXTENSION.multipleMounts,
+            providers[0].multipleMounts);
+        assertEquals(
+            MOUNTED_SINGLE_PROVIDING_EXTENSION.source, providers[0].source);
 
-        assertEquals(NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.extensionId,
-            extensions[1].extensionId);
-        assertEquals(MOUNTED_MULTIPLE_PROVIDING_EXTENSION.extensionId,
-            extensions[2].extensionId);
-        assertEquals(NOT_MOUNTED_FILE_PROVIDING_EXTENSION.extensionId,
-            extensions[3].extensionId);
-        assertEquals(NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION.extensionId,
-            extensions[4].extensionId);
- }), callback);
+        assertEquals(
+            NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId,
+            providers[1].providerId);
+        assertEquals(
+            MOUNTED_MULTIPLE_PROVIDING_EXTENSION.providerId,
+            providers[2].providerId);
+        assertEquals(
+            NOT_MOUNTED_FILE_PROVIDING_EXTENSION.providerId,
+            providers[3].providerId);
+        assertEquals(
+            NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION.providerId,
+            providers[4].providerId);
+
+        assertEquals(
+            NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.extensionId,
+            providers[1].extensionId);
+        assertEquals(
+            MOUNTED_MULTIPLE_PROVIDING_EXTENSION.extensionId,
+            providers[2].extensionId);
+        assertEquals(
+            NOT_MOUNTED_FILE_PROVIDING_EXTENSION.extensionId,
+            providers[3].extensionId);
+        assertEquals(
+            NOT_MOUNTED_DEVICE_PROVIDING_EXTENSION.extensionId,
+            providers[4].extensionId);
+      }),
+      callback);
 }
 
 function testGetMountableProviders(callback) {
   var model = new ProvidersModel(volumeManager);
-  reportPromise(model.getMountableProviders().then(
-      function(extensions) {
-        assertEquals(2, extensions.length);
-        assertEquals(NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.extensionId,
-            extensions[0].extensionId);
-        assertEquals(MOUNTED_MULTIPLE_PROVIDING_EXTENSION.extensionId,
-            extensions[1].extensionId);
-  }), callback);
+  reportPromise(
+      model.getMountableProviders().then(function(providers) {
+        assertEquals(2, providers.length);
+        assertEquals(
+            NOT_MOUNTED_SINGLE_PROVIDING_EXTENSION.providerId,
+            providers[0].providerId);
+        assertEquals(
+            MOUNTED_MULTIPLE_PROVIDING_EXTENSION.providerId,
+            providers[1].providerId);
+      }),
+      callback);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/providers_menu.js b/ui/file_manager/file_manager/foreground/js/ui/providers_menu.js
index ea9ef1f..07d3812 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/providers_menu.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/providers_menu.js
@@ -40,7 +40,7 @@
 /**
  * @private
  */
-ProvidersMenu.prototype.clearExtensions_ = function() {
+ProvidersMenu.prototype.clearProviders_ = function() {
   var childNode = this.menu_.firstElementChild;
   while (childNode !== this.separator_) {
     var node = childNode;
@@ -60,21 +60,26 @@
 };
 
 /**
- * @param {string} extensionId
- * @param {string} extensionName
+ * @param {string} providerId ID of the provider.
+ * @param {string} extensionId ID of the extension if the provider is an
+ *     extension. Otherwise empty.
+ * @param {string} name Already localized name of the provider.
  * @private
  */
-ProvidersMenu.prototype.addExtension_ = function(extensionId, extensionName) {
+ProvidersMenu.prototype.addProvider_ = function(providerId, extensionId, name) {
   var item = this.addMenuItem_();
-  item.label = extensionName;
+  item.label = name;
 
-  var iconImage = '-webkit-image-set(' +
-      'url(chrome://extension-icon/' + extensionId + '/16/1) 1x, ' +
-      'url(chrome://extension-icon/' + extensionId + '/32/1) 2x);';
-  item.iconStartImage = iconImage;
+  // TODO(mtomasz): Add icon for native providers.
+  if (extensionId) {
+    var iconImage = '-webkit-image-set(' +
+        'url(chrome://extension-icon/' + extensionId + '/16/1) 1x, ' +
+        'url(chrome://extension-icon/' + extensionId + '/32/1) 2x);';
+    item.iconStartImage = iconImage;
+  }
 
   item.addEventListener(
-      'activate', this.onItemActivate_.bind(this, extensionId));
+      'activate', this.onItemActivate_.bind(this, providerId));
 
   // Move the element before the separator.
   this.menu_.insertBefore(item, this.separator_);
@@ -85,10 +90,11 @@
  * @private
  */
 ProvidersMenu.prototype.onUpdate_ = function(event) {
-  this.model_.getMountableProviders().then(function(extensions) {
-    this.clearExtensions_();
-    extensions.forEach(function(extension) {
-      this.addExtension_(extension.extensionId, extension.extensionName);
+  this.model_.getMountableProviders().then(function(providers) {
+    this.clearProviders_();
+    providers.forEach(function(provider) {
+      this.addProvider_(
+          provider.providerId, provider.extensionId, provider.name);
     }.bind(this));
 
     // Reposition the menu, so all items are always visible.
@@ -98,10 +104,10 @@
 };
 
 /**
- * @param {string} extensionId
+ * @param {string} providerId
  * @param {!Event} event
  * @private
  */
-ProvidersMenu.prototype.onItemActivate_ = function(extensionId, event) {
-  this.model_.requestMount(extensionId);
+ProvidersMenu.prototype.onItemActivate_ = function(providerId, event) {
+  this.model_.requestMount(providerId);
 };
diff --git a/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js
index 1d80d81..04ca582a 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js
@@ -181,18 +181,20 @@
      *     argument is a list of installed item ids (null on error).
      */
     getInstalledItems: function(callback) {
-      // Return only installed providers. Returning other extensions/apps is
-      // redundant, as the suggest app for non-providers is executed only when
-      // there is no extension/app matching a file task. Hence, none of the
-      // suggested extensions/apps can be already installed.
-      this.providersModel_.getInstalledProviders().then(function(extensions) {
-        callback(extensions.map(function(extension) {
-          return extension.extensionId;
-        }));
-      }).catch(function(error) {
-        console.error(error.stack || error);
-        callback(null);
-      });
+      // Return only installed provided extensions. Returning other
+      // extensions/apps is redundant, as the suggest app for non-providers is
+      // executed only when there is no extension/app matching a file task.
+      // Hence, none of the suggested extensions/apps can be already installed.
+      this.providersModel_.getInstalledProviders()
+          .then(function(providers) {
+            callback(providers.map(function(provider) {
+              return provider.extensionId;
+            }));
+          })
+          .catch(function(error) {
+            console.error(error.stack || error);
+            callback(null);
+          });
     }.bind(this),
 
     /**
diff --git a/ui/gfx/canvas_skia.cc b/ui/gfx/canvas_skia.cc
index 916ff1c..8f24702b 100644
--- a/ui/gfx/canvas_skia.cc
+++ b/ui/gfx/canvas_skia.cc
@@ -8,6 +8,7 @@
 
 #include <memory>
 
+#include "build/build_config.h"
 #include "cc/paint/paint_canvas.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/insets.h"
@@ -113,7 +114,10 @@
     ElideRectangleText(text, font_list, *width, INT_MAX, wrap_behavior,
                        &strings);
     Rect rect(base::saturated_cast<int>(*width), INT_MAX);
-    std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
+
+    // This needs to match the instance used in ElideRectangleText.
+    auto render_text = RenderText::CreateInstanceDeprecated();
+
     UpdateRenderText(rect, base::string16(), font_list, flags, 0,
                      render_text.get());
 
@@ -131,7 +135,11 @@
     *width = w;
     *height = h;
   } else {
-    std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
+    // This is mostly used by calls from GetStringWidth(), which doesn't have
+    // the required drawing context. TODO(tapted): Ensure Cocoa UI never calls
+    // this method and change the next line to CreateHarfBuzzInstance().
+    auto render_text = RenderText::CreateInstanceDeprecated();
+
     Rect rect(base::saturated_cast<int>(*width),
               base::saturated_cast<int>(*height));
     base::string16 adjusted_text = text;
@@ -157,9 +165,15 @@
 
   Rect rect(text_bounds);
 
-  std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
+  auto render_text = gfx::RenderText::CreateInstanceDeprecated();
 
   if (flags & MULTI_LINE) {
+#if defined(OS_MACOSX)
+    // Currently not supported on Mac. ElideRectangleText() is not yet aware
+    // that the typesetting below is not being done by CoreText.
+    // See http://crbug.com/791391.
+    NOTREACHED();
+#endif
     WordWrapBehavior wrap_behavior = IGNORE_LONG_WORDS;
     if (flags & CHARACTER_BREAK)
       wrap_behavior = WRAP_LONG_WORDS;
@@ -244,7 +258,8 @@
     flags |= TEXT_ALIGN_TO_HEAD;
   flags |= NO_ELLIPSIS;
 
-  std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
+  // TODO(tapted): Remove Canvas::DrawFadedString() - it's unused.
+  auto render_text = RenderText::CreateInstanceDeprecated();
   Rect rect = display_rect;
   UpdateRenderText(rect, text, font_list, flags, color, render_text.get());
   render_text->SetElideBehavior(FADE_TAIL);
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index cb77d5b..58dc2d89 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -338,19 +338,25 @@
 }
 
 // static
-RenderText* RenderText::CreateInstance() {
-#if defined(OS_MACOSX)
-  const bool use_native = !base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kEnableHarfBuzzRenderText);
-  if (use_native)
-    return new RenderTextMac;
-#endif  // defined(OS_MACOSX)
-  return new RenderTextHarfBuzz;
+std::unique_ptr<RenderText> RenderText::CreateHarfBuzzInstance() {
+  return std::make_unique<RenderTextHarfBuzz>();
 }
 
 // static
-RenderText* RenderText::CreateInstanceForEditing() {
-  return new RenderTextHarfBuzz;
+std::unique_ptr<RenderText> RenderText::CreateInstanceForPlatformUI() {
+#if defined(OS_MACOSX)
+  static const bool use_native =
+      !base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableHarfBuzzRenderText);
+  if (use_native)
+    return std::make_unique<RenderTextMac>();
+#endif  // defined(OS_MACOSX)
+  return CreateHarfBuzzInstance();
+}
+
+// static
+std::unique_ptr<RenderText> RenderText::CreateInstanceDeprecated() {
+  return CreateInstanceForPlatformUI();
 }
 
 std::unique_ptr<RenderText> RenderText::CreateInstanceOfSameStyle(
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h
index 259f39b2..f56a11d 100644
--- a/ui/gfx/render_text.h
+++ b/ui/gfx/render_text.h
@@ -191,9 +191,19 @@
 
   virtual ~RenderText();
 
-  // Creates a platform-specific or cross-platform RenderText instance.
-  static RenderText* CreateInstance();
-  static RenderText* CreateInstanceForEditing();
+  // Creates an instance that renders using HarfBuzz.
+  static std::unique_ptr<RenderText> CreateHarfBuzzInstance();
+
+  // Creates an instance that renders text using the native platform typesetter.
+  // CoreText on Mac is the only supported native typesetter, so this should
+  // only be used by text that may be rendered using CoreText (AppKit) on Mac.
+  static std::unique_ptr<RenderText> CreateInstanceForPlatformUI();
+
+  // Returns CreateInstanceForPlatformUI(), but indicates a caller that does not
+  // know whether the text will eventually be drawn by the native typesetter or
+  // by a RenderText instance.
+  // TODO(tapted): Delete this.
+  static std::unique_ptr<RenderText> CreateInstanceDeprecated();
 
   // Creates another instance of the same concrete class.
   virtual std::unique_ptr<RenderText> CreateInstanceOfSameType() const = 0;
diff --git a/ui/gfx/text_elider.cc b/ui/gfx/text_elider.cc
index 2b22a57..a8a64de 100644
--- a/ui/gfx/text_elider.cc
+++ b/ui/gfx/text_elider.cc
@@ -198,7 +198,10 @@
                          ElideBehavior behavior) {
 #if !defined(OS_ANDROID) && !defined(OS_IOS)
   DCHECK_NE(behavior, FADE_TAIL);
-  std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
+  // TODO(tapted): Update callers of this that draw into Cocoa UI to use
+  // RenderText directly. See http://crbug.com/791391.
+  auto render_text = RenderText::CreateInstanceDeprecated();
+
   render_text->SetCursorEnabled(false);
   // TODO(bshe): 5000 is out dated. We should remove it. See crbug.com/551660.
   // Do not bother accurately sizing strings over 5000 characters here, for
diff --git a/ui/gfx/x/OWNERS b/ui/gfx/x/OWNERS
new file mode 100644
index 0000000..fd5ad4bf
--- /dev/null
+++ b/ui/gfx/x/OWNERS
@@ -0,0 +1,3 @@
+derat@chromium.org
+
+# COMPONENT: UI>GFX
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 6c35b7c..fc4b4fd44 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/buildflag_header.gni")
 import("//build/config/features.gni")
+import("//build/config/jumbo.gni")
 import("//build/config/ui.gni")
 import("//components/vector_icons/vector_icons.gni")
 import("//testing/test.gni")
@@ -38,7 +39,7 @@
       [ "ENABLE_NATIVE_WINDOW_NAV_BUTTONS=$enable_native_window_nav_buttons" ]
 }
 
-component("views") {
+jumbo_component("views") {
   all_dependent_configs = [ ":flags" ]
 
   public = [
@@ -711,7 +712,7 @@
   }
 }
 
-static_library("test_support_internal") {
+jumbo_source_set("test_support_internal") {
   testonly = true
   sources = [
     "animation/test/flood_fill_ink_drop_ripple_test_api.cc",
@@ -738,8 +739,6 @@
     "animation/test/test_ink_drop_ripple_observer.h",
     "controls/textfield/textfield_test_api.cc",
     "controls/textfield/textfield_test_api.h",
-    "corewm/test/tooltip_aura_test_api.cc",
-    "corewm/test/tooltip_aura_test_api.h",
     "test/capture_tracking_view.cc",
     "test/capture_tracking_view.h",
     "test/combobox_test_api.cc",
@@ -825,6 +824,8 @@
 
   if (use_aura) {
     sources += [
+      "corewm/test/tooltip_aura_test_api.cc",
+      "corewm/test/tooltip_aura_test_api.h",
       "corewm/tooltip_controller_test_helper.cc",
       "corewm/tooltip_controller_test_helper.h",
       "test/desktop_test_views_delegate_aura.cc",
@@ -865,7 +866,7 @@
   }
 }
 
-static_library("test_support") {
+jumbo_static_library("test_support") {
   testonly = true
   public_deps = [
     ":test_support_internal",
diff --git a/ui/views/bubble/bubble_dialog_delegate.cc b/ui/views/bubble/bubble_dialog_delegate.cc
index 6347c26..f38164ff 100644
--- a/ui/views/bubble/bubble_dialog_delegate.cc
+++ b/ui/views/bubble/bubble_dialog_delegate.cc
@@ -240,9 +240,13 @@
   // The argument rect has its origin at the bubble's arrow anchor point;
   // its size is the preferred size of the bubble's client view (this view).
   bool anchor_minimized = anchor_widget() && anchor_widget()->IsMinimized();
+  // If GetAnchorView() returns nullptr or GetAnchorRect() returns an empty rect
+  // at (0, 0), don't try and adjust arrow if off-screen.
+  gfx::Rect anchor_rect = GetAnchorRect();
+  bool has_anchor = GetAnchorView() || anchor_rect != gfx::Rect();
   return GetBubbleFrameView()->GetUpdatedWindowBounds(
-      GetAnchorRect(), GetWidget()->client_view()->GetPreferredSize(),
-      adjust_if_offscreen_ && !anchor_minimized);
+      anchor_rect, GetWidget()->client_view()->GetPreferredSize(),
+      adjust_if_offscreen_ && !anchor_minimized && has_anchor);
 }
 
 void BubbleDialogDelegateView::OnNativeThemeChanged(
diff --git a/ui/views/bubble/bubble_frame_view_unittest.cc b/ui/views/bubble/bubble_frame_view_unittest.cc
index 9b167ae..edabed53 100644
--- a/ui/views/bubble/bubble_frame_view_unittest.cc
+++ b/ui/views/bubble/bubble_frame_view_unittest.cc
@@ -849,12 +849,15 @@
   // The title/bubble should now be bigger than in multiline tail-eliding mode.
   EXPECT_LT(empty_bubble_width, title_label->size().width());
   EXPECT_LT(empty_bubble_width, bubble->GetClientAreaBoundsInScreen().width());
-  // Make sure the bubble is wide enough to fit the title's full size.
+
+  // Make sure the bubble is wide enough to fit the title's full size. Frame
+  // sizing is done off the title label's minimum size. But since that label is
+  // set to NO_ELIDE, the minimum size should match the preferred size.
   EXPECT_GE(bubble->GetClientAreaBoundsInScreen().width(),
             title_label->GetPreferredSize().width());
-  // Make sure the title's actual size has enough room for all its text.
-  EXPECT_EQ(gfx::GetStringWidth(title, title_label->font_list()),
+  EXPECT_LE(title_label->GetPreferredSize().width(),
             title_label->size().width());
+  EXPECT_EQ(title, title_label->GetDisplayTextForTesting());
 }
 
 }  // namespace views
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc
index df6851e..5fb2a866 100644
--- a/ui/views/controls/label.cc
+++ b/ui/views/controls/label.cc
@@ -76,7 +76,7 @@
 
 void Label::SetFontList(const gfx::FontList& font_list) {
   is_first_paint_text_ = true;
-  render_text_->SetFontList(font_list);
+  full_text_->SetFontList(font_list);
   ResetLayout();
 }
 
@@ -84,7 +84,7 @@
   if (new_text == text())
     return;
   is_first_paint_text_ = true;
-  render_text_->SetText(new_text);
+  full_text_->SetText(new_text);
   ResetLayout();
   stored_selection_range_ = gfx::Range::InvalidRange();
 }
@@ -134,10 +134,10 @@
 }
 
 void Label::SetShadows(const gfx::ShadowValues& shadows) {
-  if (render_text_->shadows() == shadows)
+  if (full_text_->shadows() == shadows)
     return;
   is_first_paint_text_ = true;
-  render_text_->set_shadows(shadows);
+  full_text_->set_shadows(shadows);
   ResetLayout();
 }
 
@@ -159,7 +159,7 @@
   if (horizontal_alignment() == alignment)
     return;
   is_first_paint_text_ = true;
-  render_text_->SetHorizontalAlignment(alignment);
+  full_text_->SetHorizontalAlignment(alignment);
   ResetLayout();
 }
 
@@ -167,7 +167,7 @@
   if (line_height() == height)
     return;
   is_first_paint_text_ = true;
-  render_text_->SetMinLineHeight(height);
+  full_text_->SetMinLineHeight(height);
   ResetLayout();
 }
 
@@ -178,9 +178,8 @@
     return;
   is_first_paint_text_ = true;
   multi_line_ = multi_line;
-  if (render_text_->MultilineSupported())
-    render_text_->SetMultiline(multi_line);
-  render_text_->SetReplaceNewlineCharsWithSymbols(!multi_line);
+  full_text_->SetMultiline(multi_line);
+  full_text_->SetReplaceNewlineCharsWithSymbols(!multi_line);
   ResetLayout();
 }
 
@@ -196,7 +195,7 @@
   if (this->obscured() == obscured)
     return;
   is_first_paint_text_ = true;
-  render_text_->SetObscured(obscured);
+  full_text_->SetObscured(obscured);
   if (obscured)
     SetSelectable(false);
   ResetLayout();
@@ -205,9 +204,9 @@
 void Label::SetAllowCharacterBreak(bool allow_character_break) {
   const gfx::WordWrapBehavior behavior =
       allow_character_break ? gfx::WRAP_LONG_WORDS : gfx::TRUNCATE_LONG_WORDS;
-  if (render_text_->word_wrap_behavior() == behavior)
+  if (full_text_->word_wrap_behavior() == behavior)
     return;
-  render_text_->SetWordWrapBehavior(behavior);
+  full_text_->SetWordWrapBehavior(behavior);
   if (multi_line()) {
     is_first_paint_text_ = true;
     ResetLayout();
@@ -248,21 +247,13 @@
 }
 
 base::string16 Label::GetDisplayTextForTesting() {
-  ClearRenderTextLines();
-  MaybeBuildRenderTextLines();
-  base::string16 result;
-  if (lines_.empty())
-    return result;
-  result.append(lines_[0]->GetDisplayText());
-  for (size_t i = 1; i < lines_.size(); ++i) {
-    result.append(1, '\n');
-    result.append(lines_[i]->GetDisplayText());
-  }
-  return result;
+  ClearDisplayText();
+  MaybeBuildDisplayText();
+  return display_text_ ? display_text_->GetDisplayText() : base::string16();
 }
 
 bool Label::IsSelectionSupported() const {
-  return !obscured() && render_text_->IsSelectionSupported();
+  return !obscured() && full_text_->IsSelectionSupported();
 }
 
 bool Label::SetSelectable(bool value) {
@@ -375,30 +366,27 @@
   int base_line_height = std::max(line_height(), font_list().GetHeight());
   if (!multi_line() || text().empty() || w <= 0) {
     height = base_line_height;
-  } else if (render_text_->MultilineSupported()) {
+  } else {
     // SetDisplayRect() has a side effect for later calls of GetStringSize().
-    // Be careful to invoke |render_text_->SetDisplayRect(gfx::Rect())| to
+    // Be careful to invoke |full_text_->SetDisplayRect(gfx::Rect())| to
     // cancel this effect before the next time GetStringSize() is called.
     // It would be beneficial not to cancel here, considering that some layout
     // managers invoke GetHeightForWidth() for the same width multiple times
-    // and |render_text_| can cache the height.
-    render_text_->SetDisplayRect(gfx::Rect(0, 0, w, 0));
-    int string_height = render_text_->GetStringSize().height();
+    // and |full_text_| can cache the height.
+    full_text_->SetDisplayRect(gfx::Rect(0, 0, w, 0));
+    int string_height = full_text_->GetStringSize().height();
     // Cap the number of lines to |max_lines()| if multi-line and non-zero
     // |max_lines()|.
     height = multi_line() && max_lines() > 0
                  ? std::min(max_lines() * base_line_height, string_height)
                  : string_height;
-  } else {
-    std::vector<base::string16> lines = GetLinesForWidth(w);
-    height = lines.size() * std::max(line_height(), font_list().GetHeight());
   }
-  height -= gfx::ShadowValue::GetMargin(render_text_->shadows()).height();
+  height -= gfx::ShadowValue::GetMargin(full_text_->shadows()).height();
   return height + GetInsets().height();
 }
 
 void Label::Layout() {
-  ClearRenderTextLines();
+  ClearDisplayText();
 }
 
 const char* Label::GetClassName() const {
@@ -423,8 +411,7 @@
 
 void Label::GetAccessibleNodeData(ui::AXNodeData* node_data) {
   node_data->role = ui::AX_ROLE_STATIC_TEXT;
-  // Note that |render_text_| is never elided (see the comment in Init() too).
-  node_data->SetName(render_text_->GetDisplayText());
+  node_data->SetName(full_text_->GetDisplayText());
 }
 
 bool Label::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const {
@@ -437,30 +424,41 @@
   }
 
   if (ShouldShowDefaultTooltip()) {
-    // Note that |render_text_| is never elided (see the comment in Init() too).
-    tooltip->assign(render_text_->GetDisplayText());
+    tooltip->assign(full_text_->GetDisplayText());
     return true;
   }
 
   return false;
 }
 
-std::unique_ptr<gfx::RenderText> Label::CreateRenderText(
-    const base::string16& text,
-    gfx::HorizontalAlignment alignment,
-    gfx::DirectionalityMode directionality,
-    gfx::ElideBehavior elide_behavior) const {
-  std::unique_ptr<gfx::RenderText> render_text(
-      render_text_->CreateInstanceOfSameType());
-  render_text->SetHorizontalAlignment(alignment);
-  render_text->SetDirectionalityMode(directionality);
+std::unique_ptr<gfx::RenderText> Label::CreateRenderText() const {
+  // Multi-line labels only support NO_ELIDE and ELIDE_TAIL for now.
+  // TODO(warx): Investigate more elide text support.
+  gfx::ElideBehavior elide_behavior =
+      multi_line() && (elide_behavior_ != gfx::NO_ELIDE) ? gfx::ELIDE_TAIL
+                                                         : elide_behavior_;
+
+  auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
+  render_text->SetHorizontalAlignment(horizontal_alignment());
+  render_text->SetDirectionalityMode(full_text_->directionality_mode());
   render_text->SetElideBehavior(elide_behavior);
   render_text->SetObscured(obscured());
   render_text->SetMinLineHeight(line_height());
   render_text->SetFontList(font_list());
   render_text->set_shadows(shadows());
   render_text->SetCursorEnabled(false);
-  render_text->SetText(text);
+  render_text->SetText(text());
+  render_text->SetMultiline(multi_line());
+  render_text->SetMaxLines(multi_line() ? max_lines() : 0);
+  render_text->SetWordWrapBehavior(full_text_->word_wrap_behavior());
+
+  // Setup render text for selection controller.
+  if (selectable()) {
+    render_text->set_focused(HasFocus());
+    if (stored_selection_range_.IsValid())
+      render_text->SelectRange(stored_selection_range_);
+  }
+
   return render_text;
 }
 
@@ -469,17 +467,14 @@
 }
 
 gfx::Rect Label::GetFocusRingBounds() const {
-  MaybeBuildRenderTextLines();
+  MaybeBuildDisplayText();
 
   gfx::Rect focus_bounds;
-  if (lines_.empty()) {
+  if (!display_text_) {
     focus_bounds = gfx::Rect(GetTextSize());
   } else {
-    for (size_t i = 0; i < lines_.size(); ++i) {
-      gfx::Point origin;
-      origin += lines_[i]->GetLineOffset(0);
-      focus_bounds.Union(gfx::Rect(origin, lines_[i]->GetStringSize()));
-    }
+    focus_bounds = gfx::Rect(gfx::Point() + display_text_->GetLineOffset(0),
+                             display_text_->GetStringSize());
   }
 
   focus_bounds.Inset(-NonBorderInsets(*this));
@@ -488,16 +483,16 @@
 }
 
 void Label::PaintText(gfx::Canvas* canvas) {
-  MaybeBuildRenderTextLines();
+  MaybeBuildDisplayText();
 
-  for (size_t i = 0; i < lines_.size(); ++i)
-    lines_[i]->Draw(canvas);
+  if (display_text_)
+    display_text_->Draw(canvas);
 
 #if DCHECK_IS_ON()
   // Attempt to ensure that if we're using subpixel rendering, we're painting
   // to an opaque background. What we don't want to find is an ancestor in the
   // hierarchy that paints to a non-opaque layer.
-  if (lines_.empty() || lines_[0]->subpixel_rendering_suppressed())
+  if (!display_text_ || display_text_->subpixel_rendering_suppressed())
     return;
 
   for (View* view = this; view; view = view->parent()) {
@@ -675,7 +670,7 @@
 
 void Label::VisibilityChanged(View* starting_from, bool is_visible) {
   if (!is_visible)
-    ClearRenderTextLines();
+    ClearDisplayText();
 }
 
 void Label::ShowContextMenuForView(View* source,
@@ -810,26 +805,23 @@
 const gfx::RenderText* Label::GetRenderTextForSelectionController() const {
   if (!selectable())
     return nullptr;
-  MaybeBuildRenderTextLines();
+  MaybeBuildDisplayText();
 
-  // This may happen when the content bounds of the view are empty.
-  if (lines_.empty())
-    return nullptr;
-
-  DCHECK_EQ(1u, lines_.size());
-  return lines_[0].get();
+  // This may be null when the content bounds of the view are empty.
+  return display_text_.get();
 }
 
 void Label::Init(const base::string16& text, const gfx::FontList& font_list) {
-  render_text_.reset(gfx::RenderText::CreateInstance());
-  render_text_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
-  render_text_->SetDirectionalityMode(gfx::DIRECTIONALITY_FROM_TEXT);
-  // NOTE: |render_text_| should not be elided at all. This is used to keep some
-  // properties and to compute the size of the string.
-  render_text_->SetElideBehavior(gfx::NO_ELIDE);
-  render_text_->SetFontList(font_list);
-  render_text_->SetCursorEnabled(false);
-  render_text_->SetWordWrapBehavior(gfx::TRUNCATE_LONG_WORDS);
+  full_text_ = gfx::RenderText::CreateHarfBuzzInstance();
+  DCHECK(full_text_->MultilineSupported());
+  full_text_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
+  full_text_->SetDirectionalityMode(gfx::DIRECTIONALITY_FROM_TEXT);
+  // NOTE: |full_text_| should not be elided at all. This is used to keep
+  // some properties and to compute the size of the string.
+  full_text_->SetElideBehavior(gfx::NO_ELIDE);
+  full_text_->SetFontList(font_list);
+  full_text_->SetCursorEnabled(false);
+  full_text_->SetWordWrapBehavior(gfx::TRUNCATE_LONG_WORDS);
 
   elide_behavior_ = gfx::ELIDE_TAIL;
   stored_selection_range_ = gfx::Range::InvalidRange();
@@ -861,11 +853,11 @@
   InvalidateLayout();
   PreferredSizeChanged();
   SchedulePaint();
-  ClearRenderTextLines();
+  ClearDisplayText();
 }
 
-void Label::MaybeBuildRenderTextLines() const {
-  if (!lines_.empty())
+void Label::MaybeBuildDisplayText() const {
+  if (display_text_)
     return;
 
   gfx::Rect rect = GetContentsBounds();
@@ -874,105 +866,25 @@
     return;
 
   rect.Inset(-gfx::ShadowValue::GetMargin(shadows()));
-
-  gfx::HorizontalAlignment alignment = horizontal_alignment();
-  gfx::DirectionalityMode directionality = render_text_->directionality_mode();
-  if (multi_line()) {
-    // Force the directionality and alignment of the first line on other lines.
-    bool rtl =
-        render_text_->GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT;
-    if (alignment == gfx::ALIGN_TO_HEAD)
-      alignment = rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
-    directionality =
-        rtl ? gfx::DIRECTIONALITY_FORCE_RTL : gfx::DIRECTIONALITY_FORCE_LTR;
-  }
-
-  // Multi-line labels only support NO_ELIDE and ELIDE_TAIL for now.
-  // TODO(warx): Investigate more elide text support.
-  gfx::ElideBehavior elide_behavior =
-      multi_line() && (elide_behavior_ != gfx::NO_ELIDE) ? gfx::ELIDE_TAIL
-                                                         : elide_behavior_;
-  if (!multi_line() || render_text_->MultilineSupported()) {
-    std::unique_ptr<gfx::RenderText> render_text =
-        CreateRenderText(text(), alignment, directionality, elide_behavior);
-    render_text->SetDisplayRect(rect);
-    render_text->SetMultiline(multi_line());
-    render_text->SetMaxLines(multi_line() ? max_lines() : 0);
-    render_text->SetWordWrapBehavior(render_text_->word_wrap_behavior());
-
-    // Setup render text for selection controller.
-    if (selectable()) {
-      render_text->set_focused(HasFocus());
-      if (stored_selection_range_.IsValid())
-        render_text->SelectRange(stored_selection_range_);
-    }
-
-    lines_.push_back(std::move(render_text));
-  } else {
-    // TODO(warx): Apply max_lines property when RenderText doesn't support
-    // multi-line (crbug.com/758720).
-    std::vector<base::string16> lines = GetLinesForWidth(rect.width());
-    if (lines.size() > 1)
-      rect.set_height(std::max(line_height(), font_list().GetHeight()));
-
-    const int bottom = GetContentsBounds().bottom();
-    for (size_t i = 0; i < lines.size() && rect.y() <= bottom; ++i) {
-      std::unique_ptr<gfx::RenderText> line =
-          CreateRenderText(lines[i], alignment, directionality, elide_behavior);
-      line->SetDisplayRect(rect);
-      lines_.push_back(std::move(line));
-      rect.set_y(rect.y() + rect.height());
-    }
-    // Append the remaining text to the last visible line.
-    for (size_t i = lines_.size(); i < lines.size(); ++i)
-      lines_.back()->SetText(lines_.back()->text() + lines[i]);
-  }
-
+  display_text_ = CreateRenderText();
+  display_text_->SetDisplayRect(rect);
   stored_selection_range_ = gfx::Range::InvalidRange();
   ApplyTextColors();
 }
 
-std::vector<base::string16> Label::GetLinesForWidth(int width) const {
-  std::vector<base::string16> lines;
-  // |width| can be 0 when getting the default text size, in that case
-  // the ideal lines (i.e. broken at newline characters) are wanted.
-  if (width <= 0) {
-    lines = base::SplitString(
-        render_text_->GetDisplayText(), base::string16(1, '\n'),
-        base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-  } else {
-    gfx::ElideRectangleText(render_text_->GetDisplayText(), font_list(), width,
-                            std::numeric_limits<int>::max(),
-                            render_text_->word_wrap_behavior(), &lines);
-  }
-  return lines;
-}
-
 gfx::Size Label::GetTextSize() const {
   gfx::Size size;
   if (text().empty()) {
     size = gfx::Size(0, std::max(line_height(), font_list().GetHeight()));
-  } else if (!multi_line() || render_text_->MultilineSupported()) {
-    // Cancel the display rect of |render_text_|. The display rect may be
+  } else {
+    // Cancel the display rect of |full_text_|. The display rect may be
     // specified in GetHeightForWidth(), and specifying empty Rect cancels
     // its effect. See also the comment in GetHeightForWidth().
     // TODO(mukai): use gfx::Rect() to compute the ideal size rather than
     // the current width(). See crbug.com/468494, crbug.com/467526, and
     // the comment for MultilinePreferredSizeTest in label_unittest.cc.
-    render_text_->SetDisplayRect(gfx::Rect(0, 0, width(), 0));
-    size = render_text_->GetStringSize();
-  } else {
-    // Get the natural text size, unelided and only wrapped on newlines.
-    std::vector<base::string16> lines = GetLinesForWidth(width());
-    std::unique_ptr<gfx::RenderText> render_text(
-        gfx::RenderText::CreateInstance());
-    render_text->SetFontList(font_list());
-    for (size_t i = 0; i < lines.size(); ++i) {
-      render_text->SetText(lines[i]);
-      const gfx::Size line = render_text->GetStringSize();
-      size.set_width(std::max(size.width(), line.width()));
-      size.set_height(std::max(line_height(), size.height() + line.height()));
-    }
+    full_text_->SetDisplayRect(gfx::Rect(0, 0, width(), 0));
+    size = full_text_->GetStringSize();
   }
   const gfx::Insets shadow_margin = -gfx::ShadowValue::GetMargin(shadows());
   size.Enlarge(shadow_margin.width(), shadow_margin.height());
@@ -995,16 +907,18 @@
 }
 
 void Label::ApplyTextColors() const {
+  if (!display_text_)
+    return;
+
   bool subpixel_rendering_suppressed =
       SkColorGetA(background_color_) != SK_AlphaOPAQUE ||
       !subpixel_rendering_enabled_;
-  for (size_t i = 0; i < lines_.size(); ++i) {
-    lines_[i]->SetColor(actual_enabled_color_);
-    lines_[i]->set_selection_color(actual_selection_text_color_);
-    lines_[i]->set_selection_background_focused_color(
-        selection_background_color_);
-    lines_[i]->set_subpixel_rendering_suppressed(subpixel_rendering_suppressed);
-  }
+  display_text_->SetColor(actual_enabled_color_);
+  display_text_->set_selection_color(actual_selection_text_color_);
+  display_text_->set_selection_background_focused_color(
+      selection_background_color_);
+  display_text_->set_subpixel_rendering_suppressed(
+      subpixel_rendering_suppressed);
 }
 
 void Label::UpdateColorsFromTheme(const ui::NativeTheme* theme) {
@@ -1034,10 +948,10 @@
                          (multi_line() && text_size.height() > size.height()));
 }
 
-void Label::ClearRenderTextLines() const {
-  // The HasSelection() call below will build |lines_| in case it is empty.
-  // Return early to avoid this.
-  if (lines_.empty())
+void Label::ClearDisplayText() const {
+  // The HasSelection() call below will build |display_text_| in case it is
+  // empty. Return early to avoid this.
+  if (!display_text_)
     return;
 
   // Persist the selection range if there is an active selection.
@@ -1045,7 +959,7 @@
     stored_selection_range_ =
         GetRenderTextForSelectionController()->selection();
   }
-  lines_.clear();
+  display_text_ = nullptr;
 }
 
 base::string16 Label::GetSelectedText() const {
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h
index ab6487ee..1cee727 100644
--- a/ui/views/controls/label.h
+++ b/ui/views/controls/label.h
@@ -64,13 +64,13 @@
   static const gfx::FontList& GetDefaultFontList();
 
   // Gets or sets the fonts used by this label.
-  const gfx::FontList& font_list() const { return render_text_->font_list(); }
+  const gfx::FontList& font_list() const { return full_text_->font_list(); }
 
   // TODO(tapted): Replace this with a private method, e.g., OnFontChanged().
   virtual void SetFontList(const gfx::FontList& font_list);
 
   // Get or set the label text.
-  const base::string16& text() const { return render_text_->text(); }
+  const base::string16& text() const { return full_text_->text(); }
   virtual void SetText(const base::string16& text);
 
   // Where the label appears in the UI. Passed in from the constructor. This is
@@ -108,7 +108,7 @@
 
   // Set drop shadows underneath the text.
   void SetShadows(const gfx::ShadowValues& shadows);
-  const gfx::ShadowValues& shadows() const { return render_text_->shadows(); }
+  const gfx::ShadowValues& shadows() const { return full_text_->shadows(); }
 
   // Sets whether subpixel rendering is used; the default is true, but this
   // feature also requires an opaque background color.
@@ -119,13 +119,13 @@
   // Sets the horizontal alignment; the argument value is mirrored in RTL UI.
   void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);
   gfx::HorizontalAlignment horizontal_alignment() const {
-    return render_text_->horizontal_alignment();
+    return full_text_->horizontal_alignment();
   }
 
   // Get or set the distance in pixels between baselines of multi-line text.
   // Default is 0, indicating the distance between lines should be the standard
   // one for the label's text, font list, and platform.
-  int line_height() const { return render_text_->min_line_height(); }
+  int line_height() const { return full_text_->min_line_height(); }
   void SetLineHeight(int height);
 
   // Get or set if the label text can wrap on multiple lines; default is false.
@@ -139,7 +139,7 @@
 
   // Get or set if the label text should be obscured before rendering (e.g.
   // should "Password!" display as "*********"); default is false.
-  bool obscured() const { return render_text_->obscured(); }
+  bool obscured() const { return full_text_->obscured(); }
   void SetObscured(bool obscured);
 
   // Sets whether multi-line text can wrap mid-word; the default is false.
@@ -225,11 +225,7 @@
 
  protected:
   // Create a single RenderText instance to actually be painted.
-  virtual std::unique_ptr<gfx::RenderText> CreateRenderText(
-      const base::string16& text,
-      gfx::HorizontalAlignment alignment,
-      gfx::DirectionalityMode directionality,
-      gfx::ElideBehavior elide_behavior) const;
+  virtual std::unique_ptr<gfx::RenderText> CreateRenderText() const;
 
   // Draw a focus ring. The default implementation does nothing.
   virtual void PaintFocusRing(gfx::Canvas* canvas) const;
@@ -301,11 +297,8 @@
 
   void ResetLayout();
 
-  // Set up |lines_| to actually be painted.
-  void MaybeBuildRenderTextLines() const;
-
-  // Get the text broken into lines as needed to fit the given |width|.
-  std::vector<base::string16> GetLinesForWidth(int width) const;
+  // Set up |display_text_| to actually be painted.
+  void MaybeBuildDisplayText() const;
 
   // Get the text size for the current layout.
   gfx::Size GetTextSize() const;
@@ -313,7 +306,7 @@
   // Updates text and selection colors from requested colors.
   void RecalculateColors();
 
-  // Applies the foreground color to |lines_|.
+  // Applies the foreground color to |display_text_|.
   void ApplyTextColors() const;
 
   // Updates any colors that have not been explicitly set from the theme.
@@ -321,8 +314,8 @@
 
   bool ShouldShowDefaultTooltip() const;
 
-  // Empties |lines_| and updates |stored_selection_range_|.
-  void ClearRenderTextLines() const;
+  // Clears |display_text_| and updates |stored_selection_range_|.
+  void ClearDisplayText() const;
 
   // Returns the currently selected text.
   base::string16 GetSelectedText() const;
@@ -336,14 +329,14 @@
   const int text_context_;
 
   // An un-elided and single-line RenderText object used for preferred sizing.
-  std::unique_ptr<gfx::RenderText> render_text_;
+  std::unique_ptr<gfx::RenderText> full_text_;
 
-  // The RenderText instances used to display elided and multi-line text.
-  mutable std::vector<std::unique_ptr<gfx::RenderText>> lines_;
+  // The RenderText instance used for drawing.
+  mutable std::unique_ptr<gfx::RenderText> display_text_;
 
   // Persists the current selection range between the calls to
-  // ClearRenderTextLines() and MaybeBuildRenderTextLines(). Holds an
-  // InvalidRange when not in use.
+  // ClearDisplayText() and MaybeBuildDisplayText(). Holds an InvalidRange when
+  // not in use.
   mutable gfx::Range stored_selection_range_;
 
   SkColor requested_enabled_color_ = SK_ColorRED;
diff --git a/ui/views/controls/label_unittest.cc b/ui/views/controls/label_unittest.cc
index 207820a..7e70ba3b 100644
--- a/ui/views/controls/label_unittest.cc
+++ b/ui/views/controls/label_unittest.cc
@@ -578,15 +578,15 @@
 
   gfx::Canvas canvas(gfx::Size(200, 200), 1.0f, true);
   label()->OnPaint(&canvas);
-  EXPECT_EQ(1u, label()->lines_.size());
-  EXPECT_EQ(ASCIIToUTF16("Example"), label()->lines_[0]->GetDisplayText());
+  EXPECT_TRUE(label()->display_text_);
+  EXPECT_EQ(ASCIIToUTF16("Example"), label()->display_text_->GetDisplayText());
 
   label()->SetText(ASCIIToUTF16("Altered"));
   // The altered text should be painted even though Layout() or SetBounds() are
   // not called.
   label()->OnPaint(&canvas);
-  EXPECT_EQ(1u, label()->lines_.size());
-  EXPECT_EQ(ASCIIToUTF16("Altered"), label()->lines_[0]->GetDisplayText());
+  EXPECT_TRUE(label()->display_text_);
+  EXPECT_EQ(ASCIIToUTF16("Altered"), label()->display_text_->GetDisplayText());
 }
 
 TEST_F(LabelTest, EmptyLabelSizing) {
@@ -849,46 +849,42 @@
   gfx::Size preferred_size = label()->GetPreferredSize();
 
   EXPECT_NE(gfx::Size(), preferred_size);
-  EXPECT_EQ(0u, label()->lines_.size());
+  EXPECT_FALSE(label()->display_text_);
 
   gfx::Canvas canvas(preferred_size, 1.0f, true);
   label()->OnPaint(&canvas);
-  EXPECT_EQ(1u, label()->lines_.size());
+  EXPECT_TRUE(label()->display_text_);
 
   // Label should recreate its RenderText object when it's invisible, to release
   // the layout structures and data.
   label()->SetVisible(false);
-  EXPECT_EQ(0u, label()->lines_.size());
+  EXPECT_FALSE(label()->display_text_);
 
   // Querying fields or size information should not recompute the layout
   // unnecessarily.
   EXPECT_EQ(ASCIIToUTF16("Example"), label()->text());
-  EXPECT_EQ(0u, label()->lines_.size());
+  EXPECT_FALSE(label()->display_text_);
 
   EXPECT_EQ(preferred_size, label()->GetPreferredSize());
-  EXPECT_EQ(0u, label()->lines_.size());
+  EXPECT_FALSE(label()->display_text_);
 
   // RenderText data should be back when it's necessary.
   label()->SetVisible(true);
-  EXPECT_EQ(0u, label()->lines_.size());
+  EXPECT_FALSE(label()->display_text_);
 
   label()->OnPaint(&canvas);
-  EXPECT_EQ(1u, label()->lines_.size());
+  EXPECT_TRUE(label()->display_text_);
 
-  // Changing layout just resets |lines_|. It'll recover next time it's drawn.
+  // Changing layout just resets |display_text_|. It'll recover next time it's
+  // drawn.
   label()->SetBounds(0, 0, 10, 10);
-  EXPECT_EQ(0u, label()->lines_.size());
+  EXPECT_FALSE(label()->display_text_);
 
   label()->OnPaint(&canvas);
-  EXPECT_EQ(1u, label()->lines_.size());
+  EXPECT_TRUE(label()->display_text_);
 }
 
-#if !defined(OS_MACOSX)
 TEST_F(LabelTest, MultilineSupportedRenderText) {
-  std::unique_ptr<gfx::RenderText> render_text(
-      gfx::RenderText::CreateInstance());
-  ASSERT_TRUE(render_text->MultilineSupported());
-
   label()->SetText(ASCIIToUTF16("Example of\nmultilined label"));
   label()->SetMultiLine(true);
   label()->SizeToPreferredSize();
@@ -896,10 +892,10 @@
   gfx::Canvas canvas(label()->GetPreferredSize(), 1.0f, true);
   label()->OnPaint(&canvas);
 
-  // There's only one 'line', RenderText itself supports multiple lines.
-  EXPECT_EQ(1u, label()->lines_.size());
+  // There's only RenderText instance, which should have multiple lines.
+  ASSERT_TRUE(label()->display_text_);
+  EXPECT_EQ(2u, label()->display_text_->GetNumLines());
 }
-#endif
 
 // Ensures SchedulePaint() calls are not made in OnPaint().
 TEST_F(LabelTest, NoSchedulePaintInOnPaint) {
diff --git a/ui/views/controls/styled_label_unittest.cc b/ui/views/controls/styled_label_unittest.cc
index de84d1d..991100b 100644
--- a/ui/views/controls/styled_label_unittest.cc
+++ b/ui/views/controls/styled_label_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/ui_base_features.h"
@@ -142,7 +143,13 @@
             static_cast<Label*>(styled()->child_at(1))->text());
 }
 
-TEST_F(StyledLabelTest, CorrectWrapAtNewline) {
+// https://crbug.com/793184
+#if defined(OS_MACOSX)

+#define MAYBE_CorrectWrapAtNewline DISABLED_CorrectWrapAtNewline

+#else

+#define MAYBE_CorrectWrapAtNewline CorrectWrapAtNewline

+#endif
+TEST_F(StyledLabelTest, MAYBE_CorrectWrapAtNewline) {
   const std::string first_line = "Line one";
   const std::string second_line = "  two";
   const std::string multiline_text(first_line + "\n" + second_line);
@@ -357,7 +364,13 @@
       static_cast<Label*>(styled()->child_at(1))->font_list().GetFontStyle());
 }
 
-TEST_F(StyledLabelTest, StyledRangeTextStyleBold) {
+// https://crbug.com/793184
+#if defined(OS_MACOSX)

+#define MAYBE_StyledRangeTextStyleBold DISABLED_StyledRangeTextStyleBold

+#else

+#define MAYBE_StyledRangeTextStyleBold StyledRangeTextStyleBold

+#endif
+TEST_F(StyledLabelTest, MAYBE_StyledRangeTextStyleBold) {
   test::TestLayoutProvider bold_provider;
   const std::string bold_text(
       "This is a block of text whose style will be set to BOLD in the test");
@@ -547,7 +560,13 @@
   EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip);
 }
 
-TEST_F(StyledLabelTest, SetTextContextAndDefaultStyle) {
+// https://crbug.com/793184
+#if defined(OS_MACOSX)

+#define MAYBE_SetTextContextAndDefaultStyle DISABLED_SetTextContextAndDefaultStyle

+#else

+#define MAYBE_SetTextContextAndDefaultStyle SetTextContextAndDefaultStyle

+#endif
+TEST_F(StyledLabelTest, MAYBE_SetTextContextAndDefaultStyle) {
   const std::string text("This is a test block of text.");
   InitStyledLabel(text);
   styled()->SetTextContext(style::CONTEXT_DIALOG_TITLE);
diff --git a/ui/views/controls/textfield/textfield_model.cc b/ui/views/controls/textfield/textfield_model.cc
index 680eb35..e06e12df 100644
--- a/ui/views/controls/textfield/textfield_model.cc
+++ b/ui/views/controls/textfield/textfield_model.cc
@@ -317,9 +317,8 @@
 
 TextfieldModel::TextfieldModel(Delegate* delegate)
     : delegate_(delegate),
-      render_text_(gfx::RenderText::CreateInstanceForEditing()),
-      current_edit_(edit_history_.end()) {
-}
+      render_text_(gfx::RenderText::CreateHarfBuzzInstance()),
+      current_edit_(edit_history_.end()) {}
 
 TextfieldModel::~TextfieldModel() {
   ClearEditHistory();
diff --git a/ui/views/corewm/tooltip_aura.cc b/ui/views/corewm/tooltip_aura.cc
index 949c322..80237a0a 100644
--- a/ui/views/corewm/tooltip_aura.cc
+++ b/ui/views/corewm/tooltip_aura.cc
@@ -68,8 +68,7 @@
 class TooltipAura::TooltipView : public views::View {
  public:
   TooltipView()
-      : render_text_(gfx::RenderText::CreateInstance()),
-        max_width_(0) {
+      : render_text_(gfx::RenderText::CreateHarfBuzzInstance()), max_width_(0) {
     const int kHorizontalPadding = 8;
     const int kVerticalPaddingTop = 4;
     const int kVerticalPaddingBottom = 5;
diff --git a/ui/views/examples/multiline_example.cc b/ui/views/examples/multiline_example.cc
index e4d2461..46da3ea 100644
--- a/ui/views/examples/multiline_example.cc
+++ b/ui/views/examples/multiline_example.cc
@@ -51,7 +51,7 @@
 // A simple View that hosts a RenderText object.
 class MultilineExample::RenderTextView : public View {
  public:
-  RenderTextView() : render_text_(gfx::RenderText::CreateInstanceForEditing()) {
+  RenderTextView() : render_text_(gfx::RenderText::CreateHarfBuzzInstance()) {
     render_text_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
     render_text_->SetColor(SK_ColorBLACK);
     render_text_->SetMultiline(true);
diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn
index f40dce1e..dc46a047 100644
--- a/ui/views/mus/BUILD.gn
+++ b/ui/views/mus/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/features.gni")
+import("//build/config/jumbo.gni")
 import("//build/config/ui.gni")
 import("//services/catalog/public/tools/catalog.gni")
 import("//services/service_manager/public/cpp/service.gni")
@@ -10,7 +11,7 @@
 import("//testing/test.gni")
 import("//tools/grit/repack.gni")
 
-component("mus") {
+jumbo_component("mus") {
   output_name = "ui_views_mus_lib"
 
   sources = [
@@ -107,7 +108,7 @@
   ]
 }
 
-static_library("test_support") {
+jumbo_static_library("test_support") {
   testonly = true
 
   sources = [
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm
index 57af1bb..b8e66d15 100644
--- a/ui/views/widget/native_widget_mac_unittest.mm
+++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -101,8 +101,14 @@
   // Simulate a frame swap from the compositor.
   void SimulateFrameSwap(const gfx::Size& size) {
     const float kScaleFactor = 1.0f;
-    bridge_->compositor_widget_->GotIOSurfaceFrame(
-        base::ScopedCFTypeRef<IOSurfaceRef>(), size, kScaleFactor);
+    ui::CALayerFrameSink* ca_layer_frame_sink =
+        ui::CALayerFrameSink::FromAcceleratedWidget(
+            bridge_->compositor_widget_->accelerated_widget());
+    gfx::CALayerParams ca_layer_params;
+    ca_layer_params.is_empty = false;
+    ca_layer_params.pixel_size = size;
+    ca_layer_params.scale_factor = kScaleFactor;
+    ca_layer_frame_sink->UpdateCALayerTree(ca_layer_params);
     bridge_->AcceleratedWidgetSwapCompleted();
   }