diff --git a/DEPS b/DEPS
index 51829dd42..182c770 100644
--- a/DEPS
+++ b/DEPS
@@ -78,11 +78,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': '7557bbbe19b0d56484fe039171e4d97b75f209b3',
+  'skia_revision': 'f91d57b5850f094fafde7621087de87ae2bdd0ef',
   # 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': 'f5b1d1d4f29b238ca2f0a13bf3a7b7067854592d',
+  'v8_revision': '7aa494eb480654a1ff73ce3bc4069f27473a4511',
   # 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.
@@ -142,7 +142,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-node-modules
   # and whatever else without interference from each other.
-  'devtools_node_modules_revision': '6226d6cd80aaf2e5295ed460cf73ef6a582e4d78',
+  'devtools_node_modules_revision': '2597f8672ac64e29173d3b9ec14a6fdfb73e2582',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -519,7 +519,7 @@
 
   # Minizip library. Used on Chrome OS.
   'src/third_party/minizip/src': {
-      'url': Var('chromium_git') + '/external/github.com/nmoinvaz/minizip' + '@' + 'e07e141475220196b55294c8172b274cc32d642d',
+      'url': Var('chromium_git') + '/external/github.com/nmoinvaz/minizip' + '@' + '53a657318af1fccc4bac7ed230729302b2391d1d',
       'condition': 'checkout_linux',
   },
 
@@ -643,7 +643,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'a102f0f112df264bc9554e271e8549b18d11eec4', # commit position 20628
+    Var('webrtc_git') + '/src.git' + '@' + '65fb17bc281c705bc27c257a7728b49f7b83f978', # commit position 20628
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
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 000273e..524ac6f4 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
@@ -90,10 +90,13 @@
         mContentsClient.waitForCustomViewHidden();
     }
 
-    @Test
+    /*
     @MediumTest
     @Feature({"AndroidWebView"})
     @DisableHardwareAccelerationForTest
+    */
+    @Test
+    @DisabledTest(message = "crbug.com/618749")
     public void testFullscreenForNonVideoElementIsSupportedInSoftwareMode() throws Throwable {
         // Fullscreen for non-video elements is supported and works as expected. Note that
         // this test is the same as testOnShowAndHideCustomViewWithCallback_videoInsideDiv below.
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc
index e04b6da..3c72eec 100644
--- a/ash/shelf/shelf_widget.cc
+++ b/ash/shelf/shelf_widget.cc
@@ -105,7 +105,7 @@
       focus_cycler_(nullptr),
       opaque_background_(ui::LAYER_SOLID_COLOR) {
   DCHECK(shelf_widget_);
-  SetLayoutManager(new views::FillLayout());
+  SetLayoutManager(std::make_unique<views::FillLayout>());
   set_allow_deactivate_on_esc(true);
   opaque_background_.SetBounds(GetLocalBounds());
 }
diff --git a/chrome/VERSION b/chrome/VERSION
index 3a076d3..24b8dfb 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=65
 MINOR=0
-BUILD=3304
+BUILD=3307
 PATCH=0
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 731df99a..23f7d399 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3481,6 +3481,11 @@
      FEATURE_VALUE_TYPE(features::kSysInternals)},
 #endif  // defined(OS_CHROMEOS)
 
+    {"enable-improved-language-settings",
+     flag_descriptions::kImprovedLanguageSettingsName,
+     flag_descriptions::kImprovedLanguageSettingsDescription, kOsAll,
+     FEATURE_VALUE_TYPE(translate::kImprovedLanguageSettings)},
+
     {"enable-module-scripts-dynamic-import",
      flag_descriptions::kModuleScriptsDynamicImportName,
      flag_descriptions::kModuleScriptsDynamicImportDescription, kOsAll,
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 aaffccad..056d6559 100644
--- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
+++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
@@ -19,6 +19,9 @@
 
 namespace {
 
+constexpr base::TimeDelta kRendererHighMemoryUsageDetectionWindow =
+    base::TimeDelta::FromSeconds(60);
+
 content::WebContents* g_last_visible_web_contents = nullptr;
 
 bool IsLastVisibleWebContents(content::WebContents* web_contents) {
@@ -73,12 +76,23 @@
     content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
       decider_(OomInterventionDecider::GetForBrowserContext(
-          web_contents->GetBrowserContext())) {
+          web_contents->GetBrowserContext())),
+      binding_(this),
+      weak_ptr_factory_(this) {
   OutOfMemoryReporter::FromWebContents(web_contents)->AddObserver(this);
 }
 
 OomInterventionTabHelper::~OomInterventionTabHelper() = default;
 
+void OomInterventionTabHelper::OnHighMemoryUsage(bool intervention_triggered) {
+  if (intervention_triggered) {
+    NearOomInfoBar::Show(web_contents(), this);
+    intervention_state_ = InterventionState::UI_SHOWN;
+  }
+  near_oom_detected_time_ = base::TimeTicks::Now();
+  renderer_detection_timer_.AbandonAndStop();
+}
+
 void OomInterventionTabHelper::AcceptIntervention() {
   RecordInterventionUserDecision(true);
   intervention_state_ = InterventionState::ACCEPTED;
@@ -217,6 +231,9 @@
   if (subscription_)
     return;
 
+  if (intervention_)
+    return;
+
   if (near_oom_detected_time_)
     return;
 
@@ -231,7 +248,6 @@
 void OomInterventionTabHelper::OnNearOomDetected() {
   DCHECK(web_contents()->IsVisible());
   DCHECK(!near_oom_detected_time_);
-  near_oom_detected_time_ = base::TimeTicks::Now();
   subscription_.reset();
 
   bool trigger_intervention = RendererPauseIsEnabled();
@@ -241,19 +257,33 @@
     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();
-    DCHECK(render_process_host);
-    content::BindInterface(render_process_host,
-                           mojo::MakeRequest(&intervention_));
-    NearOomInfoBar::Show(web_contents(), this);
-    intervention_state_ = InterventionState::UI_SHOWN;
-  }
+  content::RenderFrameHost* main_frame = web_contents()->GetMainFrame();
+  DCHECK(main_frame);
+  content::RenderProcessHost* render_process_host = main_frame->GetProcess();
+  DCHECK(render_process_host);
+  content::BindInterface(render_process_host,
+                         mojo::MakeRequest(&intervention_));
+  blink::mojom::OomInterventionHostPtr host;
+  binding_.Bind(mojo::MakeRequest(&host));
+  intervention_->StartDetection(std::move(host), trigger_intervention);
+
+  DCHECK(!renderer_detection_timer_.IsRunning());
+  renderer_detection_timer_.Start(
+      FROM_HERE, kRendererHighMemoryUsageDetectionWindow,
+      base::BindRepeating(&OomInterventionTabHelper::
+                              OnDetectionWindowElapsedWithoutHighMemoryUsage,
+                          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void OomInterventionTabHelper::
+    OnDetectionWindowElapsedWithoutHighMemoryUsage() {
+  ResetInterventionState();
+  intervention_.reset();
+  StartMonitoringIfNeeded();
 }
 
 void OomInterventionTabHelper::ResetInterventionState() {
   near_oom_detected_time_.reset();
   intervention_state_ = InterventionState::NOT_TRIGGERED;
+  renderer_detection_timer_.AbandonAndStop();
 }
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 b19d0b2..759a3e5 100644
--- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
+++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_TAB_HELPER_H_
 #define CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_TAB_HELPER_H_
 
+#include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/oom_intervention/near_oom_monitor.h"
@@ -12,6 +13,7 @@
 #include "chrome/browser/ui/interventions/intervention_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/WebKit/public/platform/oom_intervention.mojom.h"
 
@@ -28,12 +30,16 @@
     : public content::WebContentsObserver,
       public content::WebContentsUserData<OomInterventionTabHelper>,
       public OutOfMemoryReporter::Observer,
+      public blink::mojom::OomInterventionHost,
       public InterventionDelegate {
  public:
   static bool IsEnabled();
 
   ~OomInterventionTabHelper() override;
 
+  // blink::mojom::OomInterventionHost:
+  void OnHighMemoryUsage(bool intervention_triggered) override;
+
   // InterventionDelegate:
   void AcceptIntervention() override;
   void DeclineIntervention() override;
@@ -64,11 +70,16 @@
   // Called when NearOomMonitor detects near-OOM situation.
   void OnNearOomDetected();
 
+  // Called when we stop monitoring high memory usage in the foreground
+  // renderer.
+  void OnDetectionWindowElapsedWithoutHighMemoryUsage();
+
   void ResetInterventionState();
 
   bool navigation_started_ = false;
   base::Optional<base::TimeTicks> near_oom_detected_time_;
   std::unique_ptr<NearOomMonitor::Subscription> subscription_;
+  base::OneShotTimer renderer_detection_timer_;
 
   // Not owned. This will be nullptr in incognito mode.
   OomInterventionDecider* decider_;
@@ -87,6 +98,10 @@
   };
 
   InterventionState intervention_state_ = InterventionState::NOT_TRIGGERED;
+
+  mojo::Binding<blink::mojom::OomInterventionHost> binding_;
+
+  base::WeakPtrFactory<OomInterventionTabHelper> weak_ptr_factory_;
 };
 
 #endif  // CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_TAB_HELPER_H_
diff --git a/chrome/browser/android/voice_search_tab_helper.cc b/chrome/browser/android/voice_search_tab_helper.cc
index 7389c448..2ee429e 100644
--- a/chrome/browser/android/voice_search_tab_helper.cc
+++ b/chrome/browser/android/voice_search_tab_helper.cc
@@ -48,8 +48,9 @@
     // TODO(mlamouri): this is even more wrong because it makes assumptions with
     // regards to the default autoplay policy.
     prefs.autoplay_policy =
-        gesture_required ? content::AutoplayPolicy::kUserGestureRequired
-                         : content::AutoplayPolicy::kNoUserGestureRequired;
+        gesture_required
+            ? content::AutoplayPolicy::kDocumentUserActivationRequired
+            : content::AutoplayPolicy::kNoUserGestureRequired;
     host->UpdateWebkitPreferences(prefs);
   }
 }
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
index 06143aa10..f8c7ae0 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/task_scheduler/post_task.h"
 #include "chrome/browser/android/shortcut_helper.h"
+#include "chrome/browser/android/webapk/chrome_webapk_host.h"
 #include "chrome/browser/android/webapk/webapk_web_manifest_checker.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/installable/installable_manager.h"
@@ -42,21 +43,20 @@
       web_contents->GetVisibleURL());
 }
 
-InstallableParams ParamsToPerformManifestAndIconFetch(
-    bool check_webapk_compatibility) {
+InstallableParams ParamsToPerformManifestAndIconFetch() {
   InstallableParams params;
   params.valid_primary_icon = true;
-  params.valid_badge_icon = check_webapk_compatibility;
+  params.valid_badge_icon = true;
   params.wait_for_worker = true;
   return params;
 }
 
-InstallableParams ParamsToPerformInstallableCheck(
-    bool check_webapk_compatibility) {
+InstallableParams ParamsToPerformInstallableCheck() {
   InstallableParams params;
-  params.valid_manifest = check_webapk_compatibility;
-  params.has_worker = check_webapk_compatibility;
-  params.valid_primary_icon = check_webapk_compatibility;
+  params.check_eligibility = true;
+  params.valid_manifest = true;
+  params.has_worker = true;
+  params.valid_primary_icon = true;
   params.wait_for_worker = true;
   return params;
 }
@@ -103,14 +103,12 @@
 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher(
     content::WebContents* web_contents,
     int data_timeout_ms,
-    bool check_webapk_compatibility,
     Observer* observer)
     : content::WebContentsObserver(web_contents),
       installable_manager_(InstallableManager::FromWebContents(web_contents)),
       observer_(observer),
       shortcut_info_(GetShortcutUrl(web_contents)),
       data_timeout_ms_(base::TimeDelta::FromMilliseconds(data_timeout_ms)),
-      check_webapk_compatibility_(check_webapk_compatibility),
       is_waiting_for_manifest_(true),
       weak_ptr_factory_(this) {
   DCHECK(shortcut_info_.url.is_valid());
@@ -122,9 +120,9 @@
   // Bind the InterfacePtr into the callback so that it's kept alive
   // until there's either a connection error or a response.
   auto* web_app_info_proxy = chrome_render_frame.get();
-  web_app_info_proxy->GetWebApplicationInfo(
-      base::Bind(&AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo,
-                 base::Unretained(this), base::Passed(&chrome_render_frame)));
+  web_app_info_proxy->GetWebApplicationInfo(base::Bind(
+      &AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo,
+      weak_ptr_factory_.GetWeakPtr(), base::Passed(&chrome_render_frame)));
 }
 
 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() {}
@@ -179,7 +177,7 @@
   start_time_ = base::TimeTicks::Now();
 
   installable_manager_->GetData(
-      ParamsToPerformManifestAndIconFetch(check_webapk_compatibility_),
+      ParamsToPerformManifestAndIconFetch(),
       base::Bind(&AddToHomescreenDataFetcher::OnDidGetManifestAndIcons,
                  weak_ptr_factory_.GetWeakPtr()));
 }
@@ -201,10 +199,8 @@
   else
     installable_manager_->RecordAddToHomescreenInstallabilityTimeout();
 
-  if (check_webapk_compatibility_)
-    observer_->OnDidDetermineWebApkCompatibility(false);
-  observer_->OnUserTitleAvailable(shortcut_info_.user_title,
-                                  shortcut_info_.url);
+  observer_->OnUserTitleAvailable(shortcut_info_.user_title, shortcut_info_.url,
+                                  false);
 
   CreateLauncherIcon(raw_primary_icon_);
 }
@@ -225,10 +221,8 @@
   // Do this after updating from the manifest for the case where a site has
   // a manifest with name and standalone specified, but no icons.
   if (data.manifest->IsEmpty() || !data.primary_icon) {
-    if (check_webapk_compatibility_)
-      observer_->OnDidDetermineWebApkCompatibility(false);
     observer_->OnUserTitleAvailable(shortcut_info_.user_title,
-                                    shortcut_info_.url);
+                                    shortcut_info_.url, false);
     StopTimer();
     installable_manager_->RecordAddToHomescreenNoTimeout();
     FetchFavicon();
@@ -254,7 +248,7 @@
   }
 
   installable_manager_->GetData(
-      ParamsToPerformInstallableCheck(check_webapk_compatibility_),
+      ParamsToPerformInstallableCheck(),
       base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck,
                  weak_ptr_factory_.GetWeakPtr()));
 }
@@ -268,17 +262,13 @@
 
   installable_manager_->RecordAddToHomescreenNoTimeout();
 
-  bool webapk_compatible = false;
-  if (check_webapk_compatibility_) {
-    webapk_compatible =
-        (data.error_code == NO_ERROR_DETECTED && data.valid_manifest &&
-         data.has_worker && AreWebManifestUrlsWebApkCompatible(*data.manifest));
-    observer_->OnDidDetermineWebApkCompatibility(webapk_compatible);
-  }
-
+  bool webapk_compatible =
+      (data.error_code == NO_ERROR_DETECTED && data.valid_manifest &&
+       data.has_worker && AreWebManifestUrlsWebApkCompatible(*data.manifest) &&
+       ChromeWebApkHost::CanInstallWebApk());
   observer_->OnUserTitleAvailable(
       webapk_compatible ? shortcut_info_.name : shortcut_info_.user_title,
-      shortcut_info_.url);
+      shortcut_info_.url, webapk_compatible);
   if (webapk_compatible) {
     shortcut_info_.UpdateSource(ShortcutInfo::SOURCE_ADD_TO_HOMESCREEN_PWA);
     NotifyObserver(std::make_pair(raw_primary_icon_, false /* is_generated */));
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h
index 9074e76..1de8039 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h
@@ -32,15 +32,11 @@
  public:
   class Observer {
    public:
-    // Called when the installable check is complete.
-    virtual void OnDidDetermineWebApkCompatibility(
-        bool is_webapk_compatible) = 0;
-
     // Called when the homescreen icon title (and possibly information from the
-    // web manifest) is available. Will be called after
-    // OnDidDetermineWebApkCompatibility.
+    // web manifest) is available.
     virtual void OnUserTitleAvailable(const base::string16& title,
-                                      const GURL& url) = 0;
+                                      const GURL& url,
+                                      bool is_webapk_compatible) = 0;
 
     // Called when all the data needed to create a shortcut is available.
     virtual void OnDataAvailable(const ShortcutInfo& info,
@@ -57,7 +53,6 @@
   // |observer| must outlive AddToHomescreenDataFetcher.
   AddToHomescreenDataFetcher(content::WebContents* web_contents,
                              int data_timeout_ms,
-                             bool check_webapk_compatible,
                              Observer* observer);
 
   ~AddToHomescreenDataFetcher() override;
@@ -111,8 +106,6 @@
 
   const base::TimeDelta data_timeout_ms_;
 
-  // Indicates whether to check WebAPK compatibility.
-  bool check_webapk_compatibility_;
   bool is_waiting_for_manifest_;
 
   base::WeakPtrFactory<AddToHomescreenDataFetcher> weak_ptr_factory_;
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
index 92c1adbe..9dd4efb 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
@@ -17,6 +17,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/android/chrome_feature_list.h"
 #include "chrome/browser/installable/installable_manager.h"
 #include "chrome/browser/installable/installable_metrics.h"
 #include "chrome/common/web_application_info.h"
@@ -46,7 +48,6 @@
  public:
   ObserverWaiter()
       : is_webapk_compatible_(false),
-        determined_webapk_compatibility_(false),
         title_available_(false),
         data_available_(false) {}
   ~ObserverWaiter() override {}
@@ -61,21 +62,15 @@
     run_loop.Run();
   }
 
-  void OnDidDetermineWebApkCompatibility(bool is_webapk_compatible) override {
-    // This should only be called once.
-    EXPECT_FALSE(determined_webapk_compatibility_);
-    EXPECT_FALSE(title_available_);
-    determined_webapk_compatibility_ = true;
-    is_webapk_compatible_ = is_webapk_compatible;
-  }
-
   void OnUserTitleAvailable(const base::string16& title,
-                            const GURL& url) override {
+                            const GURL& url,
+                            bool is_webapk_compatible) override {
     // This should only be called once.
     EXPECT_FALSE(title_available_);
     EXPECT_FALSE(data_available_);
     title_available_ = true;
     title_ = title;
+    is_webapk_compatible_ = is_webapk_compatible;
   }
 
   void OnDataAvailable(const ShortcutInfo& info,
@@ -91,15 +86,11 @@
 
   base::string16 title() const { return title_; }
   bool is_webapk_compatible() const { return is_webapk_compatible_; }
-  bool determined_webapk_compatibility() const {
-    return determined_webapk_compatibility_;
-  }
   bool title_available() const { return title_available_; }
 
  private:
   base::string16 title_;
   bool is_webapk_compatible_;
-  bool determined_webapk_compatibility_;
   bool title_available_;
   bool data_available_;
   base::Closure quit_closure_;
@@ -252,10 +243,9 @@
   }
 
   std::unique_ptr<AddToHomescreenDataFetcher> BuildFetcher(
-      bool check_webapk_compatible,
       AddToHomescreenDataFetcher::Observer* observer) {
-    return base::MakeUnique<AddToHomescreenDataFetcher>(
-        web_contents(), 500, check_webapk_compatible, observer);
+    return std::make_unique<AddToHomescreenDataFetcher>(web_contents(), 500,
+                                                        observer);
   }
 
   void RunFetcher(AddToHomescreenDataFetcher* fetcher,
@@ -270,8 +260,6 @@
     fetcher->OnDidGetWebApplicationInfo(nullptr, web_application_info);
     waiter.WaitForDataAvailable();
 
-    EXPECT_EQ(check_webapk_compatibility(),
-              waiter.determined_webapk_compatibility());
     EXPECT_EQ(is_webapk_compatible, waiter.is_webapk_compatible());
     EXPECT_TRUE(waiter.title_available());
     if (is_webapk_compatible)
@@ -320,38 +308,13 @@
 
   void ResolveQueuedMetrics() { installable_manager_->ResolveQueuedMetrics(); }
 
-  virtual bool check_webapk_compatibility() { return true; }
-
  private:
   TestInstallableManager* installable_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTest);
 };
 
-// Class for tests which should be run with AddToHomescreenDataFetcher built
-// with both true and false values of |check_webapk_compatible|.
-class AddToHomescreenDataFetcherTestCommon
-    : public AddToHomescreenDataFetcherTest,
-      public testing::WithParamInterface<bool> {
- public:
-  AddToHomescreenDataFetcherTestCommon() {}
-  ~AddToHomescreenDataFetcherTestCommon() override {}
-
-  std::unique_ptr<AddToHomescreenDataFetcher> BuildFetcher(
-      AddToHomescreenDataFetcher::Observer* observer) {
-    return AddToHomescreenDataFetcherTest::BuildFetcher(
-        check_webapk_compatibility(), observer);
-  }
-
-  // The value of |check_webapk_compatible| used when building the
-  // AddToHomescreenDataFetcher.
-  bool check_webapk_compatibility() override { return GetParam(); }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTestCommon);
-};
-
-TEST_P(AddToHomescreenDataFetcherTestCommon, EmptyManifest) {
+TEST_F(AddToHomescreenDataFetcherTest, EmptyManifest) {
   // Check that an empty manifest has the appropriate methods run.
   base::HistogramTester histograms;
   ObserverWaiter waiter;
@@ -363,7 +326,7 @@
       AddToHomescreenTimeoutStatus::NO_TIMEOUT_NON_PROGRESSIVE_WEB_APP);
 }
 
-TEST_P(AddToHomescreenDataFetcherTestCommon, NoIconManifest) {
+TEST_F(AddToHomescreenDataFetcherTest, NoIconManifest) {
   // Test a manifest with no icons. This should use the short name and have
   // a generated icon (empty icon url).
   content::Manifest manifest = BuildDefaultManifest();
@@ -397,8 +360,7 @@
   // compatibility.
   base::HistogramTester histograms;
   ObserverWaiter waiter;
-  std::unique_ptr<AddToHomescreenDataFetcher> fetcher =
-      BuildFetcher(true, &waiter);
+  std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
   RunFetcher(fetcher.get(), waiter, kWebApplicationInfoTitle,
              blink::kWebDisplayModeBrowser, false);
   ResolveQueuedMetrics();
@@ -410,7 +372,7 @@
   EXPECT_TRUE(fetcher->shortcut_info().best_primary_icon_url.is_empty());
 }
 
-TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestFetchTimesOutNonPwa) {
+TEST_F(AddToHomescreenDataFetcherTest, ManifestFetchTimesOutNonPwa) {
   SetShouldManifestTimeOut(true);
   SetManifest(BuildDefaultManifest());
   SetInstallable(false);
@@ -431,7 +393,7 @@
   EXPECT_TRUE(fetcher->shortcut_info().best_primary_icon_url.is_empty());
 }
 
-TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestFetchTimesOutUnknown) {
+TEST_F(AddToHomescreenDataFetcherTest, ManifestFetchTimesOutUnknown) {
   SetShouldManifestTimeOut(true);
   SetShouldInstallableTimeOut(true);
   SetManifest(BuildDefaultManifest());
@@ -463,8 +425,7 @@
   // determines PWA-ness.
   base::HistogramTester histograms;
   ObserverWaiter waiter;
-  std::unique_ptr<AddToHomescreenDataFetcher> fetcher =
-      BuildFetcher(true, &waiter);
+  std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
   RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
              blink::kWebDisplayModeStandalone, false);
   ResolveQueuedMetrics();
@@ -486,8 +447,7 @@
   // determines non-PWA-ness.
   base::HistogramTester histograms;
   ObserverWaiter waiter;
-  std::unique_ptr<AddToHomescreenDataFetcher> fetcher =
-      BuildFetcher(true, &waiter);
+  std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
   RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
              blink::kWebDisplayModeStandalone, false);
   ResolveQueuedMetrics();
@@ -509,8 +469,7 @@
   // This is akin to waiting for a service worker forever.
   base::HistogramTester histograms;
   ObserverWaiter waiter;
-  std::unique_ptr<AddToHomescreenDataFetcher> fetcher =
-      BuildFetcher(true, &waiter);
+  std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
   RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
              blink::kWebDisplayModeStandalone, false);
 
@@ -525,7 +484,7 @@
             GURL(kDefaultIconUrl));
 }
 
-TEST_P(AddToHomescreenDataFetcherTestCommon, InstallableManifest) {
+TEST_F(AddToHomescreenDataFetcherTest, InstallableManifest) {
   // Test a site that has an offline-capable service worker.
   content::Manifest manifest(BuildDefaultManifest());
   SetManifest(manifest);
@@ -534,34 +493,22 @@
   ObserverWaiter waiter;
   std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
   RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
-             kDefaultManifestName, blink::kWebDisplayModeStandalone,
-             check_webapk_compatibility());
+             kDefaultManifestName, blink::kWebDisplayModeStandalone, true);
 
   // There should always be a primary icon.
   EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
   EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
             GURL(kDefaultIconUrl));
 
-  // Check that the badge icon is requested only when AddToHomescreenDataFetcher
-  // checks for WebAPK compatibility.
-  if (check_webapk_compatibility()) {
-    EXPECT_FALSE(fetcher->badge_icon().drawsNothing());
-    EXPECT_EQ(fetcher->shortcut_info().best_badge_icon_url,
-              GURL(kDefaultIconUrl));
-    CheckHistograms(
-        histograms,
-        AddToHomescreenTimeoutStatus::NO_TIMEOUT_PROGRESSIVE_WEB_APP);
-  } else {
-    EXPECT_TRUE(fetcher->badge_icon().drawsNothing());
-    EXPECT_TRUE(fetcher->shortcut_info().best_badge_icon_url.is_empty());
-    CheckHistograms(
-        histograms,
-        AddToHomescreenTimeoutStatus::NO_TIMEOUT_NON_PROGRESSIVE_WEB_APP);
-  }
+  // Check that the badge icon is requested.
+  EXPECT_FALSE(fetcher->badge_icon().drawsNothing());
+  EXPECT_EQ(fetcher->shortcut_info().best_badge_icon_url,
+            GURL(kDefaultIconUrl));
+  CheckHistograms(histograms,
+                  AddToHomescreenTimeoutStatus::NO_TIMEOUT_PROGRESSIVE_WEB_APP);
 }
 
-TEST_P(AddToHomescreenDataFetcherTestCommon,
-       ManifestNameClobbersWebApplicationName) {
+TEST_F(AddToHomescreenDataFetcherTest, ManifestNameClobbersWebApplicationName) {
   // Test that when the manifest provides Manifest::name but not
   // Manifest::short_name that Manifest::name is used as the title.
   {
@@ -616,13 +563,13 @@
   }
 
   {
-    // Check a site with an offline-capaable service worker.
+    // Check a site with an offline-capable service worker.
     SetInstallable(true);
     SetShouldInstallableTimeOut(false);
     ObserverWaiter waiter;
     std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
     RunFetcher(fetcher.get(), waiter, kDefaultManifestName,
-               blink::kWebDisplayModeStandalone, check_webapk_compatibility());
+               blink::kWebDisplayModeStandalone, true);
 
     EXPECT_FALSE(fetcher->primary_icon().drawsNothing());
     EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url,
@@ -632,7 +579,7 @@
   }
 }
 
-TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestNoNameNoShortName) {
+TEST_F(AddToHomescreenDataFetcherTest, ManifestNoNameNoShortName) {
   // Test that when the manifest does not provide either Manifest::short_name
   // nor Manifest::name that:
   //  - The page is not WebAPK compatible.
@@ -658,6 +605,25 @@
             GURL(kDefaultIconUrl));
 }
 
-INSTANTIATE_TEST_CASE_P(CheckWebApkCompatibility,
-                        AddToHomescreenDataFetcherTestCommon,
-                        ::testing::Values(false, true));
+TEST_F(AddToHomescreenDataFetcherTest, WebApkFeatureDisabled) {
+  // Test that AddToHomescreenDataFetcher considers Web Manifests as not
+  // WebAPK-compatible when the "Improved add to homescreen" feature is
+  // disabled via variations.
+  bool kTestCasesEnableWebapkFeature[] = {true, false};
+
+  SetManifest(BuildDefaultManifest());
+
+  for (bool enable_webapk_feature : kTestCasesEnableWebapkFeature) {
+    base::test::ScopedFeatureList scoped_feature_list;
+    if (enable_webapk_feature)
+      scoped_feature_list.InitAndEnableFeature(chrome::android::kImprovedA2HS);
+    else
+      scoped_feature_list.InitAndDisableFeature(chrome::android::kImprovedA2HS);
+
+    ObserverWaiter waiter;
+    std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter);
+    RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName,
+               kDefaultManifestName, blink::kWebDisplayModeStandalone,
+               enable_webapk_feature);
+  }
+}
diff --git a/chrome/browser/android/webapps/add_to_homescreen_manager.cc b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
index 5826cfe2e..aec0771e 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_manager.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
@@ -12,7 +12,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/android/shortcut_helper.h"
-#include "chrome/browser/android/webapk/chrome_webapk_host.h"
 #include "chrome/browser/android/webapk/webapk_install_service.h"
 #include "chrome/browser/banners/app_banner_manager_android.h"
 #include "chrome/browser/banners/app_banner_settings_helper.h"
@@ -35,7 +34,7 @@
 
 // The length of time to allow the add to homescreen data fetcher to run before
 // timing out and generating an icon.
-const int kDataTimeoutInMilliseconds = 4000;
+const int kDataTimeoutInMilliseconds = 8000;
 
 }  // namespace
 
@@ -94,17 +93,11 @@
   // Icon generation depends on having a valid visible URL.
   DCHECK(web_contents->GetVisibleURL().is_valid());
 
-  bool check_webapk_compatible = false;
-  if (ChromeWebApkHost::CanInstallWebApk() &&
-      InstallableManager::IsContentSecure(web_contents)) {
-    check_webapk_compatible = true;
-  }
-
   JNIEnv* env = base::android::AttachCurrentThread();
   Java_AddToHomescreenManager_showDialog(env, java_ref_);
 
   data_fetcher_ = base::MakeUnique<AddToHomescreenDataFetcher>(
-      web_contents, kDataTimeoutInMilliseconds, check_webapk_compatible, this);
+      web_contents, kDataTimeoutInMilliseconds, this);
 }
 
 AddToHomescreenManager::~AddToHomescreenManager() {}
@@ -123,14 +116,12 @@
       base::Time::Now());
 }
 
-void AddToHomescreenManager::OnDidDetermineWebApkCompatibility(
-    bool is_webapk_compatible) {
-  is_webapk_compatible_ = is_webapk_compatible;
-}
-
 void AddToHomescreenManager::OnUserTitleAvailable(
     const base::string16& user_title,
-    const GURL& url) {
+    const GURL& url,
+    bool is_webapk_compatible) {
+  is_webapk_compatible_ = is_webapk_compatible;
+
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jstring> j_user_title =
       base::android::ConvertUTF16ToJavaString(env, user_title);
diff --git a/chrome/browser/android/webapps/add_to_homescreen_manager.h b/chrome/browser/android/webapps/add_to_homescreen_manager.h
index 9a0456fd..510ffcb 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_manager.h
+++ b/chrome/browser/android/webapps/add_to_homescreen_manager.h
@@ -44,9 +44,9 @@
   void RecordAddToHomescreen();
 
   // AddToHomescreenDataFetcher::Observer:
-  void OnDidDetermineWebApkCompatibility(bool is_webapk_compatible) override;
   void OnUserTitleAvailable(const base::string16& user_title,
-                            const GURL& url) override;
+                            const GURL& url,
+                            bool is_webapk_compatible) override;
   void OnDataAvailable(const ShortcutInfo& info,
                        const SkBitmap& primary_icon,
                        const SkBitmap& badge_icon) override;
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index ac2d8d5..106a6ea9 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1082,6 +1082,10 @@
 }
 
 IN_PROC_BROWSER_TEST_P(WebViewTest, AudioStateJavascriptAPI) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      switches::kAutoplayPolicy,
+      switches::autoplay::kNoUserGestureRequiredPolicy);
+
   ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
   ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/audio_state_api"))
       << message_;
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
index 0363ffb3..2e8fc75c 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -526,7 +526,10 @@
 }
 
 bool FakeChromeUserManager::IsLoggedInAsPublicAccount() const {
-  return false;
+  const user_manager::User* active_user = GetActiveUser();
+  return active_user
+             ? active_user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT
+             : false;
 }
 
 bool FakeChromeUserManager::IsLoggedInAsGuest() const {
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
index b329229..b09a14d6 100644
--- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
+++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
@@ -36,6 +36,7 @@
 #include "extensions/common/permissions/permissions_data.h"
 #include "media/audio/audio_device_description.h"
 #include "media/audio/audio_system.h"
+#include "media/base/media_switches.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -233,6 +234,13 @@
     ComponentLoader::EnableBackgroundExtensionsForTesting();
     AudioWaitingExtensionTest::SetUp();
   }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    AudioWaitingExtensionTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitchASCII(
+        switches::kAutoplayPolicy,
+        switches::autoplay::kNoUserGestureRequiredPolicy);
+  }
 };
 
 #if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index bdfabc4..b6bf2642 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -766,6 +766,11 @@
     "Include the option to whitelist important sites in the clear browsing "
     "data dialog.";
 
+const char kImprovedLanguageSettingsName[] = "Improved Language Settings";
+const char kImprovedLanguageSettingsDescription[] =
+    "Set of changes for Language Settings. These changes are intended to fix "
+    "the major bugs related to Language Settings.";
+
 const char kInProductHelpDemoModeChoiceName[] = "In-Product Help Demo Mode";
 const char kInProductHelpDemoModeChoiceDescription[] =
     "Selects the In-Product Help demo mode.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 410b6fc..0f8c5877 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -480,6 +480,9 @@
 extern const char kImportantSitesInCbdName[];
 extern const char kImportantSitesInCbdDescription[];
 
+extern const char kImprovedLanguageSettingsName[];
+extern const char kImprovedLanguageSettingsDescription[];
+
 extern const char kInProductHelpDemoModeChoiceName[];
 extern const char kInProductHelpDemoModeChoiceDescription[];
 
diff --git a/chrome/browser/installable/installable_manager.cc b/chrome/browser/installable/installable_manager.cc
index 81c0c55..9cd94479 100644
--- a/chrome/browser/installable/installable_manager.cc
+++ b/chrome/browser/installable/installable_manager.cc
@@ -64,6 +64,23 @@
 #endif
 }
 
+// Returns true if the overall security state of |web_contents| is sufficient to
+// be considered installable.
+bool IsContentSecure(content::WebContents* web_contents) {
+  if (!web_contents)
+    return false;
+
+  // Whitelist localhost. Check the VisibleURL to match what the
+  // SecurityStateTabHelper looks at.
+  if (net::IsLocalhost(web_contents->GetVisibleURL().HostNoBracketsPiece()))
+    return true;
+
+  security_state::SecurityInfo security_info;
+  SecurityStateTabHelper::FromWebContents(web_contents)
+      ->GetSecurityInfo(&security_info);
+  return security_state::IsSslCertificateValid(security_info.security_level);
+}
+
 // Returns true if |manifest| specifies a PNG icon with IconPurpose::ANY and of
 // height and width >= kMinimumPrimaryIconSizeInPx (or size "any").
 bool DoesManifestContainRequiredIcon(const content::Manifest& manifest) {
@@ -147,22 +164,6 @@
 }
 
 // static
-bool InstallableManager::IsContentSecure(content::WebContents* web_contents) {
-  if (!web_contents)
-    return false;
-
-  // Whitelist localhost. Check the VisibleURL to match what the
-  // SecurityStateTabHelper looks at.
-  if (net::IsLocalhost(web_contents->GetVisibleURL().HostNoBracketsPiece()))
-    return true;
-
-  security_state::SecurityInfo security_info;
-  SecurityStateTabHelper::FromWebContents(web_contents)
-      ->GetSecurityInfo(&security_info);
-  return security_state::IsSslCertificateValid(security_info.security_level);
-}
-
-// static
 int InstallableManager::GetMinimumIconSizeInPx() {
   return kMinimumPrimaryIconSizeInPx;
 }
diff --git a/chrome/browser/installable/installable_manager.h b/chrome/browser/installable/installable_manager.h
index 54bcab6..1f3091cc 100644
--- a/chrome/browser/installable/installable_manager.h
+++ b/chrome/browser/installable/installable_manager.h
@@ -36,10 +36,6 @@
   explicit InstallableManager(content::WebContents* web_contents);
   ~InstallableManager() override;
 
-  // Returns true if the overall security state of |web_contents| is sufficient
-  // to be considered installable.
-  static bool IsContentSecure(content::WebContents* web_contents);
-
   // Returns the minimum icon size in pixels for a site to be installable.
   static int GetMinimumIconSizeInPx();
 
diff --git a/chrome/browser/media/media_engagement_browsertest.cc b/chrome/browser/media/media_engagement_browsertest.cc
index 10b26b63..737a0806 100644
--- a/chrome/browser/media/media_engagement_browsertest.cc
+++ b/chrome/browser/media/media_engagement_browsertest.cc
@@ -95,6 +95,13 @@
     injected_clock_ = false;
   }
 
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitchASCII(
+        switches::kAutoplayPolicy,
+        switches::autoplay::kNoUserGestureRequiredPolicy);
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+  }
+
   void LoadTestPage(const GURL& url) {
     // We can't do this in SetUp as the browser isn't ready yet and we
     // need it before the page navigates.
diff --git a/chrome/browser/metrics/desktop_session_duration/audible_contents_tracker_browsertest.cc b/chrome/browser/metrics/desktop_session_duration/audible_contents_tracker_browsertest.cc
index 1f0854e..37823f0f 100644
--- a/chrome/browser/metrics/desktop_session_duration/audible_contents_tracker_browsertest.cc
+++ b/chrome/browser/metrics/desktop_session_duration/audible_contents_tracker_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/test/browser_test_base.h"
+#include "media/base/media_switches.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -43,6 +44,13 @@
     InProcessBrowserTest::SetUp();
   }
 
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitchASCII(
+        switches::kAutoplayPolicy,
+        switches::autoplay::kNoUserGestureRequiredPolicy);
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+  }
+
   void TearDown() override {
     InProcessBrowserTest::TearDown();
     tracker_.reset();
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc
index 7585605..ba8cce24 100644
--- a/chrome/browser/net/errorpage_browsertest.cc
+++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -243,52 +243,6 @@
   DISALLOW_COPY_AND_ASSIGN(FailFirstNRequestsInterceptor);
 };
 
-// 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:
-  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;
-
- private:
-  ErrorPageTest* owner_;
-
-  DISALLOW_COPY_AND_ASSIGN(LinkDoctorInterceptor);
-};
-
-void InstallMockInterceptors(
-    const GURL& search_url,
-    std::unique_ptr<net::URLRequestInterceptor> link_doctor_interceptor) {
-  chrome_browser_net::SetUrlRequestMocksEnabled(true);
-
-  AddInterceptorForURL(google_util::LinkDoctorBaseURL(),
-                       std::move(link_doctor_interceptor));
-
-  // Add a mock for the search engine the error page will use.
-  base::FilePath root_http;
-  PathService::Get(chrome::DIR_TEST_DATA, &root_http);
-  net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
-      search_url.scheme(), search_url.host(),
-      net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile(
-          root_http.AppendASCII("title3.html")));
-}
-
-// When it sees a request for |path|, returns a 500 response with a body that
-// will be sniffed as binary/octet-stream.
-std::unique_ptr<net::test_server::HttpResponse> Return500WithBinaryBody(
-    const std::string& path,
-    const net::test_server::HttpRequest& request) {
-  if (path != request.relative_url)
-    return nullptr;
-  return std::unique_ptr<net::test_server::HttpResponse>(
-      new net::test_server::RawHttpResponse("HTTP/1.1 500 Server Sad :(",
-                                            "\x01"));
-}
 
 class ErrorPageTest : public InProcessBrowserTest {
  public:
@@ -356,6 +310,35 @@
     NavigateHistory(num_navigations, HISTORY_NAVIGATE_FORWARD);
   }
 
+  // Navigates the browser the indicated direction in the history and waits for
+  // |num_navigations| to occur and the title to change to |expected_title|.
+  void NavigateHistoryAndWaitForTitle(const std::string& expected_title,
+                                      int32_t num_navigations,
+                                      HistoryNavigationDirection direction) {
+    content::TitleWatcher title_watcher(
+        browser()->tab_strip_model()->GetActiveWebContents(),
+        base::ASCIIToUTF16(expected_title));
+
+    NavigateHistory(num_navigations, direction);
+
+    EXPECT_EQ(title_watcher.WaitAndGetTitle(),
+              base::ASCIIToUTF16(expected_title));
+  }
+
+  void NavigateHistory(int32_t num_navigations,
+                       HistoryNavigationDirection direction) {
+    content::TestNavigationObserver test_navigation_observer(
+        browser()->tab_strip_model()->GetActiveWebContents(), num_navigations);
+    if (direction == HISTORY_NAVIGATE_BACK) {
+      chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
+    } else if (direction == HISTORY_NAVIGATE_FORWARD) {
+      chrome::GoForward(browser(), WindowOpenDisposition::CURRENT_TAB);
+    } else {
+      FAIL();
+    }
+    test_navigation_observer.Wait();
+  }
+
   // Confirms that the javascript variable indicating whether or not we have
   // a stale copy in the cache has been set to |expected|, and that the
   // stale load button is or isn't there based on the same expectation.
@@ -406,121 +389,8 @@
     return ("success" == result ? testing::AssertionSuccess() :
             (testing::AssertionFailure() << "Exception message is " << result));
   }
-
-  void RequestCreated() {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    num_requests_++;
-    if (num_requests_ == requests_to_wait_for_)
-      run_loop_->Quit();
-  }
-
- protected:
-  void SetUpOnMainThread() override {
-    std::unique_ptr<net::URLRequestInterceptor> owned_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.
-    UIThreadSearchTermsData search_terms_data(browser()->profile());
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE,
-        base::BindOnce(&InstallMockInterceptors,
-                       GURL(search_terms_data.GoogleBaseURLValue()),
-                       base::Passed(&owned_interceptor)));
-  }
-
-  // Returns a GURL that results in a DNS error.
-  GURL GetDnsErrorURL() const {
-    return URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED);
-  }
-
-  // Returns true if the platform has support for a diagnostics tool, which
-  // can be launched from the error page.
-  bool PlatformSupportsDiagnosticsTool() {
-#if defined(OS_CHROMEOS)
-    // ChromeOS uses an extension instead of a diagnostics dialog.
-    return true;
-#else
-    return CanShowNetworkDiagnosticsDialog();
-#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);
-  }
-
-  // Returns the total number of requests handled thus far.
-  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|.
-  void NavigateHistoryAndWaitForTitle(const std::string& expected_title,
-                                      int32_t num_navigations,
-                                      HistoryNavigationDirection direction) {
-    content::TitleWatcher title_watcher(
-        browser()->tab_strip_model()->GetActiveWebContents(),
-        base::ASCIIToUTF16(expected_title));
-
-    NavigateHistory(num_navigations, direction);
-
-    EXPECT_EQ(title_watcher.WaitAndGetTitle(),
-              base::ASCIIToUTF16(expected_title));
-  }
-
-  void NavigateHistory(int32_t num_navigations,
-                       HistoryNavigationDirection direction) {
-    content::TestNavigationObserver test_navigation_observer(
-        browser()->tab_strip_model()->GetActiveWebContents(),
-        num_navigations);
-    if (direction == HISTORY_NAVIGATE_BACK) {
-      chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
-    } else if (direction == HISTORY_NAVIGATE_FORWARD) {
-      chrome::GoForward(browser(), WindowOpenDisposition::CURRENT_TAB);
-    } else {
-      FAIL();
-    }
-    test_navigation_observer.Wait();
-  }
-
- 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)
@@ -554,9 +424,118 @@
   cache->SetHttpNetworkTransactionFactoryForTesting(std::move(factory));
 }
 
+// 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:
+  explicit LinkDoctorInterceptor(class DNSErrorPageTest* owner)
+      : owner_(owner) {}
+  ~LinkDoctorInterceptor() override = default;
+
+  // net::URLRequestInterceptor implementation
+  net::URLRequestJob* MaybeInterceptRequest(
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate) const override;
+
+ private:
+  DNSErrorPageTest* owner_;
+
+  DISALLOW_COPY_AND_ASSIGN(LinkDoctorInterceptor);
+};
+
+class DNSErrorPageTest : public ErrorPageTest {
+ public:
+  DNSErrorPageTest() = default;
+  ~DNSErrorPageTest() override = default;
+
+  static void InstallMockInterceptors(
+      const GURL& search_url,
+      std::unique_ptr<net::URLRequestInterceptor> link_doctor_interceptor) {
+    chrome_browser_net::SetUrlRequestMocksEnabled(true);
+
+    AddInterceptorForURL(google_util::LinkDoctorBaseURL(),
+                         std::move(link_doctor_interceptor));
+
+    // Add a mock for the search engine the error page will use.
+    base::FilePath root_http;
+    PathService::Get(chrome::DIR_TEST_DATA, &root_http);
+    net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
+        search_url.scheme(), search_url.host(),
+        net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile(
+            root_http.AppendASCII("title3.html")));
+  }
+
+  // When it sees a request for |path|, returns a 500 response with a body that
+  // will be sniffed as binary/octet-stream.
+  static std::unique_ptr<net::test_server::HttpResponse>
+  Return500WithBinaryBody(const std::string& path,
+                          const net::test_server::HttpRequest& request) {
+    if (path != request.relative_url)
+      return nullptr;
+    return std::unique_ptr<net::test_server::HttpResponse>(
+        new net::test_server::RawHttpResponse("HTTP/1.1 500 Server Sad :(",
+                                              "\x01"));
+  }
+
+  void SetUpOnMainThread() override {
+    std::unique_ptr<net::URLRequestInterceptor> owned_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.
+    UIThreadSearchTermsData search_terms_data(browser()->profile());
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::BindOnce(&DNSErrorPageTest::InstallMockInterceptors,
+                       GURL(search_terms_data.GoogleBaseURLValue()),
+                       base::Passed(&owned_interceptor)));
+  }
+
+  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);
+  }
+
+  // Returns the total number of requests handled thus far.
+  int32_t num_requests() const {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    return num_requests_;
+  }
+
+  void RequestCreated() {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    num_requests_++;
+    if (num_requests_ == requests_to_wait_for_)
+      run_loop_->Quit();
+  }
+
+  // Returns a GURL that results in a DNS error.
+  GURL GetDnsErrorURL() const {
+    return URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED);
+  }
+
+ 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_;
+
+};
+
 // Test an error with a file URL, and make sure it doesn't have a
 // button to launch a network diagnostics tool.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, FileNotFound) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, FileNotFound) {
   // Create an empty temp directory, to be sure there's no file in it.
   base::ScopedAllowBlockingForTesting allow_blocking;
   base::ScopedTempDir temp_dir;
@@ -576,7 +555,7 @@
 
 // Check an network error page for ERR_FAILED. In particular, this should
 // not trigger a link doctor error page.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, Failed) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Failed) {
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), URLRequestFailedJob::GetMockHttpUrl(net::ERR_FAILED), 1);
 
@@ -586,7 +565,7 @@
 }
 
 // Test that a DNS error occuring in the main frame redirects to an error page.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_Basic) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_Basic) {
   // The first navigation should fail and load a blank page, while it fetches
   // the Link Doctor response.  The second navigation is the Link Doctor.
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -597,7 +576,7 @@
 
 // Test that a DNS error occuring in the main frame does not result in an
 // additional session history entry.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_GoBack1) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack1) {
   NavigateToFileURL("title2.html");
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
@@ -608,7 +587,7 @@
 
 // Test that a DNS error occuring in the main frame does not result in an
 // additional session history entry.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_GoBack2) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack2) {
   NavigateToFileURL("title2.html");
 
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -628,7 +607,7 @@
 
 // Test that a DNS error occuring in the main frame does not result in an
 // additional session history entry.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_GoBack2AndForward) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack2AndForward) {
   NavigateToFileURL("title2.html");
 
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -651,7 +630,7 @@
 
 // Test that a DNS error occuring in the main frame does not result in an
 // additional session history entry.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_GoBack2Forward2) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack2Forward2) {
   NavigateToFileURL("title3.html");
 
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -676,7 +655,7 @@
 }
 
 // Test that the search link on a DNS error page works.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_DoSearch) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_DoSearch) {
   // The first navigation should fail, and the second one should be the error
   // page.
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -722,7 +701,7 @@
 }
 
 // Test that the reload button on a DNS error page works.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_DoReload) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_DoReload) {
   // The first navigation should fail, and the second one should be the error
   // page.
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -754,7 +733,7 @@
 // Test that the reload button on a DNS error page works after a same document
 // navigation on the error page.  Error pages don't seem to do this, but some
 // traces indicate this may actually happen.  This test may hang on regression.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest,
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest,
                        DNSError_DoReloadAfterSameDocumentNavigation) {
   // The first navigation should fail, and the second one should be the error
   // page.
@@ -795,7 +774,7 @@
 }
 
 // Test that clicking links on a DNS error page works.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_DoClickLink) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_DoClickLink) {
   // The first navigation should fail, and the second one should be the error
   // page.
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -833,7 +812,7 @@
 
 // Test that a DNS error occuring in an iframe does not result in showing
 // navigation corrections.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, IFrameDNSError_Basic) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, IFrameDNSError_Basic) {
   ASSERT_TRUE(embedded_test_server()->Start());
   NavigateToURLAndWaitForTitle(
       embedded_test_server()->GetURL("/iframe_dns_error.html"), "Blah", 1);
@@ -853,7 +832,7 @@
 #endif
 // Test that a DNS error occuring in an iframe does not result in an
 // additional session history entry.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_IFrameDNSError_GoBack) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, MAYBE_IFrameDNSError_GoBack) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
   ui_test_utils::NavigateToURL(browser(),
@@ -874,7 +853,8 @@
 #endif
 // Test that a DNS error occuring in an iframe does not result in an
 // additional session history entry.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_IFrameDNSError_GoBackAndForward) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest,
+                       MAYBE_IFrameDNSError_GoBackAndForward) {
   NavigateToFileURL("title2.html");
   NavigateToFileURL("iframe_dns_error.html");
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
@@ -886,7 +866,7 @@
 // completed loading, does not result in an additional session history entry.
 // To ensure that the main document has completed loading, JavaScript is used to
 // inject an iframe after loading is done.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, IFrameDNSError_JavaScript) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, IFrameDNSError_JavaScript) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
   content::WebContents* wc =
@@ -952,7 +932,7 @@
 
 // Checks that navigation corrections are not loaded when we receive an actual
 // 404 page.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Page404) {
   ASSERT_TRUE(embedded_test_server()->Start());
   NavigateToURLAndWaitForTitle(embedded_test_server()->GetURL("/page404.html"),
                                "SUCCESS", 1);
@@ -961,7 +941,7 @@
 
 // Checks that navigation corrections are loaded in response to a 404 page with
 // no body.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, Empty404) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Empty404) {
   // The first navigation should fail and load a blank page, while it fetches
   // the Link Doctor response.  The second navigation is the Link Doctor.
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
@@ -975,7 +955,7 @@
 
 // Checks that a local error page is shown in response to a 500 error page
 // without a body.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, Empty500) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Empty500) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
   ui_test_utils::NavigateToURL(
@@ -989,7 +969,7 @@
 // Checks that when an error occurs, the stale cache status of the page
 // is correctly transferred, and that stale cached copied can be loaded
 // from the javascript.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, StaleCacheStatus) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, StaleCacheStatus) {
   ASSERT_TRUE(embedded_test_server()->Start());
   // Load cache with entry with "nocache" set, to create stale
   // cache.  Currently it needs to at least have an etag for the cache to
@@ -1043,7 +1023,7 @@
 }
 
 // Check that the easter egg is present and initialised and is not disabled.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, CheckEasterEggIsNotDisabled) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, CheckEasterEggIsNotDisabled) {
   ui_test_utils::NavigateToURL(browser(),
       URLRequestFailedJob::GetMockHttpUrl(net::ERR_INTERNET_DISCONNECTED));
 
@@ -1068,6 +1048,22 @@
   EXPECT_EQ(1, result);
 }
 
+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(&DNSErrorPageTest::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 ErrorPageAutoReloadTest : public InProcessBrowserTest {
  public:
   void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -1278,7 +1274,6 @@
     }
   }
 
- private:
   // Adds a filter that causes all correction service requests to fail with
   // ERR_ADDRESS_UNREACHABLE.
   //
@@ -1298,6 +1293,18 @@
     net::URLRequestFilter::GetInstance()->ClearHandlers();
   }
 
+  // Returns true if the platform has support for a diagnostics tool, which
+  // can be launched from the error page.
+  bool PlatformSupportsDiagnosticsTool() {
+#if defined(OS_CHROMEOS)
+    // ChromeOS uses an extension instead of a diagnostics dialog.
+    return true;
+#else
+    return CanShowNetworkDiagnosticsDialog();
+#endif
+  }
+
+ private:
   std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
 };
 
@@ -1367,8 +1374,17 @@
 }
 
 class ErrorPageOfflineTest : public ErrorPageTest {
- protected:
+  static void InstallMockInterceptors() {
+    chrome_browser_net::SetUrlRequestMocksEnabled(true);
+  }
 
+  void SetUpOnMainThread() override {
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::BindOnce(&ErrorPageOfflineTest::InstallMockInterceptors));
+  }
+
+ protected:
   void SetUpInProcessBrowserTestFixture() override {
 #if defined(OS_CHROMEOS)
     if (enroll_) {
@@ -1570,7 +1586,7 @@
 }
 
 // Make sure HTTP/0.9 is disabled on non-default ports by default.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, Http09WeirdPort) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Http09WeirdPort) {
   ASSERT_TRUE(embedded_test_server()->Start());
   ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/echo-raw?spam"));
@@ -1579,7 +1595,7 @@
 
 // Test that redirects to invalid URLs show an error. See
 // https://crbug.com/462272.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, RedirectToInvalidURL) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, RedirectToInvalidURL) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url = embedded_test_server()->GetURL("/server-redirect?https://:");
   ui_test_utils::NavigateToURL(browser(), url);
@@ -1628,10 +1644,11 @@
 // is displayed. This tests the particular case in which the response body
 // is small enough that the entire response must be read before its MIME type
 // can be determined.
-IN_PROC_BROWSER_TEST_F(ErrorPageTest, SniffSmallHttpErrorResponseAsDownload) {
+IN_PROC_BROWSER_TEST_F(DNSErrorPageTest,
+                       SniffSmallHttpErrorResponseAsDownload) {
   const char kErrorPath[] = "/foo";
-  embedded_test_server()->RegisterRequestHandler(
-      base::Bind(&Return500WithBinaryBody, kErrorPath));
+  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+      &DNSErrorPageTest::Return500WithBinaryBody, kErrorPath));
   ASSERT_TRUE(embedded_test_server()->Start());
 
   ui_test_utils::NavigateToURL(browser(),
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index d5144bb..f0242b8 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -112,6 +112,7 @@
 #include "extensions/common/manifest_handlers/mime_types_handler.h"
 #include "extensions/common/switches.h"
 #include "extensions/test/result_catcher.h"
+#include "media/base/media_switches.h"
 #include "net/base/escape.h"
 #include "net/cert/x509_certificate.h"
 #include "net/dns/mock_host_resolver.h"
@@ -602,6 +603,14 @@
 
   ~PrerenderBrowserTest() override {}
 
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitchASCII(
+        switches::kAutoplayPolicy,
+        switches::autoplay::kNoUserGestureRequiredPolicy);
+
+    test_utils::PrerenderInProcessBrowserTest::SetUpCommandLine(command_line);
+  }
+
   std::unique_ptr<TestPrerender> PrerenderTestURL(
       const std::string& html_file,
       FinalStatus expected_final_status,
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
index ce3bfdb..e13632c 100644
--- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
+++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
@@ -32,6 +32,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
+#include "media/base/media_switches.h"
 #include "net/base/filename_util.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
@@ -605,6 +606,10 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     ChromeRenderProcessHostTest::SetUpCommandLine(command_line);
     command_line->AppendSwitch(switches::kProcessPerTab);
+
+    command_line->AppendSwitchASCII(
+        switches::kAutoplayPolicy,
+        switches::autoplay::kNoUserGestureRequiredPolicy);
   }
 
   void SetUpOnMainThread() override {
diff --git a/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css b/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
index c7f58db..54d34e8 100644
--- a/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
+++ b/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
@@ -47,7 +47,8 @@
 #header-text {
   -webkit-padding-end: 4px;
   font-size: 1.175em;
-  margin: 8px;
+  line-height: 36px;
+  margin: 0 8px;
   overflow: hidden;
   text-overflow: ellipsis;
 }
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
index bf29b230..8cc98a9 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -874,6 +874,11 @@
     const arc::mojom::OrientationLock orientation_lock) {
   const std::string app_id = shortcut ? GetAppId(package_name, intent_uri)
                                       : GetAppId(package_name, activity);
+
+  // Do not add Play Store app for Public Session and Kiosk modes.
+  if (app_id == arc::kPlayStoreAppId && arc::IsRobotAccountMode())
+    return;
+
   std::string updated_name = name;
   // Add "(beta)" string to Play Store. See crbug.com/644576 for details.
   if (app_id == arc::kPlayStoreAppId)
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
index ca553618..a51bedf 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -23,6 +23,7 @@
 #include "chrome/browser/chromeos/arc/arc_support_host.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_arc_home_service.h"
+#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_service_test_base.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
@@ -147,6 +148,8 @@
   ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_DISABLED,
   // ARC is persistent but without Play Store UI support.
   ARC_PERSISTENT_WITHOUT_PLAY_STORE,
+  // ARC is persistent, Play Store is managed, enabled, but hidden.
+  ARC_PERSISTENT_MANAGED_ENABLED_AND_PLAY_STORE_HIDDEN,
 };
 
 constexpr ArcState kManagedArcStates[] = {
@@ -154,6 +157,7 @@
     ArcState::ARC_PLAY_STORE_MANAGED_AND_DISABLED,
     ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_ENABLED,
     ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_DISABLED,
+    ArcState::ARC_PERSISTENT_MANAGED_ENABLED_AND_PLAY_STORE_HIDDEN,
 };
 
 constexpr ArcState kUnmanagedArcStates[] = {
@@ -187,6 +191,7 @@
       case ArcState::ARC_PERSISTENT_PLAY_STORE_UNMANAGED:
       case ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_ENABLED:
       case ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_DISABLED:
+      case ArcState::ARC_PERSISTENT_MANAGED_ENABLED_AND_PLAY_STORE_HIDDEN:
         arc::SetArcAlwaysStartForTesting(true);
         break;
       case ArcState::ARC_PERSISTENT_WITHOUT_PLAY_STORE:
@@ -585,6 +590,7 @@
     switch (GetParam()) {
       case ArcState::ARC_PLAY_STORE_MANAGED_AND_ENABLED:
       case ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_ENABLED:
+      case ArcState::ARC_PERSISTENT_MANAGED_ENABLED_AND_PLAY_STORE_HIDDEN:
         return true;
       case ArcState::ARC_PLAY_STORE_MANAGED_AND_DISABLED:
       case ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_DISABLED:
@@ -598,6 +604,13 @@
 
   // ArcPlayStoreAppTest:
   void OnBeforeArcTestSetup() override {
+    if (GetParam() ==
+        ArcState::ARC_PERSISTENT_MANAGED_ENABLED_AND_PLAY_STORE_HIDDEN) {
+      const AccountId account_id(
+          AccountId::FromUserEmail(profile_->GetProfileUserName()));
+      arc_test()->GetUserManager()->AddPublicAccountUser(account_id);
+      arc_test()->GetUserManager()->LoginUser(account_id);
+    }
     policy::ProfilePolicyConnector* const connector =
         policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile());
     connector->OverrideIsManagedForTesting(true);
@@ -2070,7 +2083,9 @@
   // PlayStor exists for managed and enabled state.
   std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
       prefs->GetApp(arc::kPlayStoreAppId);
-  if (IsEnabledByPolicy()) {
+  if (IsEnabledByPolicy() &&
+      GetParam() !=
+          ArcState::ARC_PERSISTENT_MANAGED_ENABLED_AND_PLAY_STORE_HIDDEN) {
     ASSERT_TRUE(app_info);
     EXPECT_FALSE(app_info->ready);
   } else {
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc
index dd946ee2..77c672a 100644
--- a/chrome/browser/ui/views/device_chooser_content_view.cc
+++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -338,13 +338,13 @@
     return std::unique_ptr<views::View>(extra_views.at(0));
 
   auto container = std::make_unique<views::View>();
-  views::BoxLayout* layout =
-      new views::BoxLayout(views::BoxLayout::kHorizontal, gfx::Insets(),
-                           ChromeLayoutProvider::Get()->GetDistanceMetric(
-                               views::DISTANCE_RELATED_CONTROL_HORIZONTAL));
+  auto layout = std::make_unique<views::BoxLayout>(
+      views::BoxLayout::kHorizontal, gfx::Insets(),
+      ChromeLayoutProvider::Get()->GetDistanceMetric(
+          views::DISTANCE_RELATED_CONTROL_HORIZONTAL));
   layout->set_cross_axis_alignment(
       views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
-  container->SetLayoutManager(layout);
+  container->SetLayoutManager(std::move(layout));
   for (auto* view : extra_views)
     container->AddChildView(view);
   return container;
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
index e033a9a..95796ce 100644
--- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
+++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
@@ -96,9 +96,11 @@
   location_bar_view_ =
       new LocationBarView(nullptr, profile, &command_updater_, this, true);
 
-  auto* box = new views::BoxLayout(views::BoxLayout::kVertical);
-  box->set_cross_axis_alignment(views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
-  SetLayoutManager(box);
+  auto box_owner =
+      std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical);
+  box_owner->set_cross_axis_alignment(
+      views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
+  auto* box = SetLayoutManager(std::move(box_owner));
   AddChildView(location_bar_view_);
   box->SetFlexForView(location_bar_view_, 0);
   AddChildView(web_view);
diff --git a/chrome/browser/ui/views/passwords/credentials_selection_view.cc b/chrome/browser/ui/views/passwords/credentials_selection_view.cc
index d86e24d..e369a66b 100644
--- a/chrome/browser/ui/views/passwords/credentials_selection_view.cc
+++ b/chrome/browser/ui/views/passwords/credentials_selection_view.cc
@@ -40,7 +40,6 @@
   // Layout.
   views::GridLayout* layout =
       SetLayoutManager(std::make_unique<views::GridLayout>(this));
-  SetLayoutManager(layout);
 
   // ColumnSet.
   int column_set_id = 0;
diff --git a/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc
index 4fdb0db..13c5ddf 100644
--- a/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc
+++ b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc
@@ -211,7 +211,6 @@
                                      dialog_insets.bottom(), 0));
   views::GridLayout* dialog_layout =
       SetLayoutManager(std::make_unique<views::GridLayout>(this));
-  SetLayoutManager(dialog_layout);
 
   // Use a column set with no padding.
   dialog_layout->AddColumnSet(0)->AddColumn(views::GridLayout::FILL,
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index 092d8fe7e..7cc08f3 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -1083,7 +1083,7 @@
   // own border and a second border can't be added, therefore a parent view with
   // a border has to be created.
   views::View* signin_button_view = new views::View();
-  signin_button_view->SetLayoutManager(new views::FillLayout());
+  signin_button_view->SetLayoutManager(std::make_unique<views::FillLayout>());
   signin_button_view->SetBorder(
       views::CreateSolidBorder(kMenuEdgeMargin, SK_ColorTRANSPARENT));
 
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc
index 6077131b9..c6d0370 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.cc
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -244,7 +244,6 @@
   views::View* uma_view = new views::View();
   GridLayout* uma_layout =
       uma_view->SetLayoutManager(std::make_unique<views::GridLayout>(uma_view));
-  uma_view->SetLayoutManager(uma_layout);
 
   const int kReportColumnSetId = 0;
   views::ColumnSet* cs = uma_layout->AddColumnSet(kReportColumnSetId);
diff --git a/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.cc b/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.cc
index febe172..9bf4c1d 100644
--- a/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.cc
+++ b/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.cc
@@ -8,13 +8,7 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/view.h"
 
-// static
-ButtonLayout* ButtonLayout::CreateAndInstall(views::View* view,
-                                             int view_width) {
-  ButtonLayout* layout = new ButtonLayout(view_width);
-  view->SetLayoutManager(layout);
-  return layout;
-}
+ButtonLayout::ButtonLayout(int view_width) : view_width_(view_width) {}
 
 ButtonLayout::~ButtonLayout() = default;
 
@@ -75,8 +69,6 @@
   return {view_width_, max_child_size.height()};
 }
 
-ButtonLayout::ButtonLayout(int view_width) : view_width_(view_width) {}
-
 // static
 bool ButtonLayout::HasTwoButtons(const views::View* host) {
   const int child_count = host->child_count();
diff --git a/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.h b/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.h
index cd52355..201be01 100644
--- a/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.h
+++ b/chrome/browser/ui/views/try_chrome_dialog_win/button_layout.h
@@ -29,14 +29,12 @@
 // which only the one or two action buttons are added.
 class ButtonLayout : public views::LayoutManager {
  public:
-  // Returns a new instance that has been made the manager of |view|. The
-  // dialog's one or two action button(s) must be the only children of |view|.
-  // |view_width| is the desired width of the view, which controls the width of
-  // the individual buttons as above. The layout manager of |view|'s parent must
-  // respect this width (by, for example, using SizeType::USE_PREF for the
-  // hosting column's size_type if it uses GridLayout).
-  static ButtonLayout* CreateAndInstall(views::View* view, int view_width);
-
+  // The dialog's one or two action button(s) must be the only children of
+  // |view|. |view_width| is the desired width of the view, which controls the
+  // width of the individual buttons as above. The layout manager of |view|'s
+  // parent must respect this width (by, for example, using SizeType::USE_PREF
+  // for the hosting column's size_type if it uses GridLayout).
+  explicit ButtonLayout(int view_width);
   ~ButtonLayout() override;
 
  protected:
@@ -50,8 +48,6 @@
   // The horizontal or vertical space between two buttons.
   enum { kPaddingBetweenButtons = 4 };
 
-  explicit ButtonLayout(int view_width);
-
   // Returns true if |host| contains two buttons, or false if it contains only
   // one.
   static bool HasTwoButtons(const views::View* host);
diff --git a/chrome/browser/ui/views/try_chrome_dialog_win/button_layout_unittest.cc b/chrome/browser/ui/views/try_chrome_dialog_win/button_layout_unittest.cc
index fd851bb..93c3431 100644
--- a/chrome/browser/ui/views/try_chrome_dialog_win/button_layout_unittest.cc
+++ b/chrome/browser/ui/views/try_chrome_dialog_win/button_layout_unittest.cc
@@ -52,7 +52,8 @@
 
  protected:
   ButtonLayoutTest()
-      : layout_(ButtonLayout::CreateAndInstall(&host_, kFixedHostWidth)),
+      : layout_(host_.SetLayoutManager(
+            std::make_unique<ButtonLayout>(kFixedHostWidth))),
         button_1_width_(::testing::get<0>(GetParam())),
         button_2_width_(::testing::get<1>(GetParam())) {}
 
diff --git a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
index 8069db6..fc70391b 100644
--- a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
+++ b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
@@ -1135,7 +1135,7 @@
   static constexpr int kButtonsViewWidth =
       kToastWidth - kTextButtonPadding - kTextButtonPadding;
   auto buttons = std::make_unique<views::View>();
-  ButtonLayout::CreateAndInstall(buttons.get(), kButtonsViewWidth);
+  buttons->SetLayoutManager(std::make_unique<ButtonLayout>(kButtonsViewWidth));
 
   layout->StartRow(0, 2);
   auto accept_button = CreateWin10StyleButton(
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index f42cb81..b24e895a 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -62,7 +62,7 @@
 // The name of the username/password element in the form.
 const char kUsernameName[] = "username";
 const char kPasswordName[] = "password";
-const char kEmailName[] = "email";
+const char kDisplayName[] = "display-name";
 const char kCreditCardOwnerName[] = "creditcardowner";
 const char kCreditCardNumberName[] = "creditcardnumber";
 const char kCreditCardVerificationName[] = "cvc";
@@ -198,8 +198,8 @@
 const char kFormHTMLWithTwoTextFields[] =
     "<FORM name='LoginTestForm' id='LoginTestForm' "
     "action='http://www.bidule.com'>"
+    "  <INPUT type='text' id='display-name'/>"
     "  <INPUT type='text' id='username'/>"
-    "  <INPUT type='text' id='email'/>"
     "  <INPUT type='password' id='password'/>"
     "  <INPUT type='submit' value='Login'/>"
     "</FORM>";
@@ -2189,16 +2189,16 @@
 TEST_F(PasswordAutofillAgentTest, FindingUsernameWithoutAutofillPredictions) {
   LoadHTML(kFormHTMLWithTwoTextFields);
   UpdateUsernameAndPasswordElements();
-  WebInputElement email_element = GetInputElementByID(kEmailName);
+  WebInputElement display_name_element = GetInputElementByID(kDisplayName);
   SimulateUsernameTyping("temp");
-  SimulateUserInputChangeForElement(&email_element, "temp@google.com");
+  SimulateUserInputChangeForElement(&display_name_element, "User123");
   SimulatePasswordTyping("random");
 
   SaveAndSubmitForm();
 
-  // Observe that the PasswordAutofillAgent identifies the second field (e-mail)
-  // as username.
-  ExpectFormSubmittedWithUsernameAndPasswords("temp@google.com", "random", "");
+  // Observe that the PasswordAutofillAgent identifies the second field as
+  // username.
+  ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
 }
 
 // Tests that field predictions are followed when identifying the username
@@ -2206,9 +2206,9 @@
 TEST_F(PasswordAutofillAgentTest, FindingFieldsWithAutofillPredictions) {
   LoadHTML(kFormHTMLWithTwoTextFields);
   UpdateUsernameAndPasswordElements();
-  WebInputElement email_element = GetInputElementByID(kEmailName);
+  WebInputElement display_name_element = GetInputElementByID(kDisplayName);
   SimulateUsernameTyping("temp");
-  SimulateUserInputChangeForElement(&email_element, "temp@google.com");
+  SimulateUserInputChangeForElement(&display_name_element, "User123");
   SimulatePasswordTyping("random");
   // Find FormData for visible password form.
   WebFormElement form_element = username_element_.Form();
@@ -2241,7 +2241,7 @@
   // TODO(msramek): We should also test that adding another password field
   // won't override the password field prediction either. However, the password
   // field predictions are not taken into account yet.
-  ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
+  ExpectFormSubmittedWithUsernameAndPasswords("User123", "random", "");
 }
 
 // The user types in a username and a password. Then JavaScript changes password
diff --git a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc
index 2db91d4..ca1c0fc0 100644
--- a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc
+++ b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc
@@ -473,6 +473,13 @@
 
   snd_htimestamp_t status_timestamp = {};
   alsa_->PcmStatusGetHtstamp(pcm_status_, &status_timestamp);
+  if (status_timestamp.tv_sec == 0 && status_timestamp.tv_nsec == 0) {
+    // ALSA didn't actually give us a timestamp.
+    rendering_delay_.timestamp_microseconds = kNoTimestamp;
+    rendering_delay_.delay_microseconds = 0;
+    return;
+  }
+
   rendering_delay_.timestamp_microseconds =
       TimespecToMicroseconds(status_timestamp);
   snd_pcm_sframes_t delay_frames = alsa_->PcmStatusGetDelay(pcm_status_);
diff --git a/chromecast/public/volume_control.h b/chromecast/public/volume_control.h
index 5f17d51..d61d94d9 100644
--- a/chromecast/public/volume_control.h
+++ b/chromecast/public/volume_control.h
@@ -81,17 +81,18 @@
   static void SetOutputLimit(AudioContentType type, float limit)
       __attribute__((__weak__));
 
-  // Converts a volume level in the range [0.0, 1.0] to/from a volume in dB.
-  // The volume in dB should be full-scale (so a volume level of 1.0 would be
-  // 0.0 dBFS, and any lower volume level would be negative).
-  // May be called from multiple processes.
-  static float VolumeToDbFS(float volume) __attribute__((__weak__));
-  static float DbFSToVolume(float dbfs) __attribute__((__weak__));
-
   // Called to enable power save mode when no audio is being played
   // (|power_save_on| will be true in this case), and to disable power save mode
   // when audio playback resumes (|power_save_on| will be false).
   static void SetPowerSaveMode(bool power_save_on) __attribute__((__weak__));
+
+  // Converts a volume level in the range [0.0, 1.0] to/from a volume in dB.
+  // The volume in dB should be full-scale (so a volume level of 1.0 would be
+  // 0.0 dBFS, and any lower volume level would be negative).
+  // NOTE: Unlike the other VolumeControl methods, these may be called before
+  // Initialize() or after Finalize(). May be called from multiple processes.
+  static float VolumeToDbFS(float volume) __attribute__((__weak__));
+  static float DbFSToVolume(float dbfs) __attribute__((__weak__));
 };
 
 }  // namespace media
diff --git a/components/autofill/content/renderer/html_based_username_detector.cc b/components/autofill/content/renderer/html_based_username_detector.cc
index 046932cc..8437015 100644
--- a/components/autofill/content/renderer/html_based_username_detector.cc
+++ b/components/autofill/content/renderer/html_based_username_detector.cc
@@ -63,43 +63,57 @@
   const size_t non_latin_dictionary_size;
 };
 
-// 1. Removes delimiters from |raw_value| and appends it to |*field_data_value|.
-// A sentinel symbol is added first if |*field_data_value| is not empty.
+// Used only inside DCHECK.
+bool AllElementsBelongsToSameForm(
+    const std::vector<blink::WebFormControlElement>& all_control_elements,
+    const std::vector<blink::WebInputElement>& possible_usernames) {
+  if (std::adjacent_find(
+          possible_usernames.begin(), possible_usernames.end(),
+          [](const blink::WebInputElement& a, const blink::WebInputElement& b) {
+            return a.Form() != b.Form();
+          }) != possible_usernames.end())
+    return false;
+  if (std::adjacent_find(all_control_elements.begin(),
+                         all_control_elements.end(),
+                         [](const blink::WebFormControlElement& a,
+                            const blink::WebFormControlElement& b) {
+                           return a.Form() != b.Form();
+                         }) != all_control_elements.end())
+    return false;
+  DCHECK(!all_control_elements.empty());
+  return all_control_elements[0].Form() == possible_usernames[0].Form();
+}
+
+// 1. Removes delimiters from |raw_value| and appends the remainder to
+// |*field_data_value|. A sentinel symbol is added first if |*field_data_value|
+// is not empty.
 // 2. Tokenizes and appends short tokens (shorter than |kMinimumWordLength|)
 // from |raw_value| to |*field_data_short_tokens|, if any.
 void AppendValueAndShortTokens(
     const base::string16& raw_value,
     base::string16* field_data_value,
     base::flat_set<base::string16>* field_data_short_tokens) {
-  base::string16 lowercase_value = base::i18n::ToLower(raw_value);
+  const base::string16 lowercase_value = base::i18n::ToLower(raw_value);
   const base::string16 delimiters = base::ASCIIToUTF16(kDelimiters);
   std::vector<base::StringPiece16> tokens =
       base::SplitStringPiece(lowercase_value, delimiters, base::TRIM_WHITESPACE,
                              base::SPLIT_WANT_NONEMPTY);
-  // Modify |lowercase_value| only when |tokens| has been processed.
-
-  std::vector<base::string16> short_tokens;
-  std::transform(
-      std::find_if(tokens.begin(), tokens.end(),
-                   [](const base::StringPiece16& token) {
-                     return token.size() < kMinimumWordLength;
-                   }),
-      tokens.end(), std::back_inserter(short_tokens),
-      [](const base::StringPiece16& token) { return token.as_string(); });
-  // It is better to insert elements to a |flat_map| in one operation.
-  field_data_short_tokens->insert(short_tokens.begin(), short_tokens.end());
-
-  // Now that tokens are processed, squeeze delimiters out of |lowercase_value|.
-  lowercase_value.erase(std::remove_if(
-      lowercase_value.begin(), lowercase_value.end(),
-      [delimiters](char c) { return delimiters.find(c) != delimiters.npos; }));
 
   // When computing the developer value, '$' safety guard is being added
   // between field name and id, so that forming of accidental words is
   // prevented.
   if (!field_data_value->empty())
     field_data_value->push_back('$');
-  *field_data_value += lowercase_value;
+
+  field_data_value->reserve(field_data_value->size() + lowercase_value.size());
+  std::vector<base::string16> short_tokens;
+  for (const base::StringPiece16& token : tokens) {
+    if (token.size() < kMinimumWordLength)
+      short_tokens.push_back(token.as_string());
+    token.AppendToString(field_data_value);
+  }
+  // It is better to insert elements to a |base::flat_set| in one operation.
+  field_data_short_tokens->insert(short_tokens.begin(), short_tokens.end());
 }
 
 // For the given |input_element|, compute developer and user value, along with
@@ -119,31 +133,36 @@
   return field_data;
 }
 
-// For the fields of the given form that can be username fields
-// (all_possible_usernames), computes |UsernameFieldData| needed by the
-// detector.
+// For the fields of the given form (all_control_elements), computes
+// |UsernameFieldData| needed by the detector.
 void InferUsernameFieldData(
-    const std::vector<blink::WebInputElement>& all_possible_usernames,
+    const std::vector<blink::WebFormControlElement>& all_control_elements,
     const FormData& form_data,
     std::vector<UsernameFieldData>* possible_usernames_data) {
-  // |all_possible_usernames| and |form_data.fields| may have different set of
+  // |all_control_elements| and |form_data.fields| may have different set of
   // fields. Match them based on |WebInputElement.NameForAutofill| and
   // |FormFieldData.name|.
   size_t next_element_range_begin = 0;
 
-  for (const blink::WebInputElement& input_element : all_possible_usernames) {
-    const base::string16 element_name = input_element.NameForAutofill().Utf16();
+  for (const blink::WebFormControlElement& control_element :
+       all_control_elements) {
+    const blink::WebInputElement* input_element =
+        ToWebInputElement(&control_element);
+    if (!input_element || input_element->IsPasswordFieldForAutofill())
+      continue;
+    const base::string16 element_name =
+        input_element->NameForAutofill().Utf16();
     for (size_t i = next_element_range_begin; i < form_data.fields.size();
          ++i) {
       const FormFieldData& field_data = form_data.fields[i];
-      if (input_element.NameForAutofill().IsEmpty())
+      if (input_element->NameForAutofill().IsEmpty())
         continue;
 
       // Find matching field data and web input element.
       if (field_data.name == element_name) {
         next_element_range_begin = i + 1;
         possible_usernames_data->push_back(
-            ComputeUsernameFieldData(input_element, field_data));
+            ComputeUsernameFieldData(*input_element, field_data));
         break;
       }
     }
@@ -212,13 +231,12 @@
 
 // Check if any word from the given category (|category|) appears in fields from
 // the form (|possible_usernames_data|). If the category words appear in more
-// than 2 fields, do not make a decision, because it may just be a prefix. If
-// the words appears in 1 or 2 fields, the first field is saved to
-// |*username_element|.
-bool FormContainsWordFromCategory(
+// than 2 fields, do nothing, because it may just be a prefix. If the words
+// appears in 1 or 2 fields, the first field is added to |username_predictions|.
+void FindWordsFromCategoryInForm(
     const std::vector<UsernameFieldData>& possible_usernames_data,
     const CategoryOfWords& category,
-    WebInputElement* username_element) {
+    std::vector<blink::WebInputElement>* username_predictions) {
   // Auxiliary element that contains the first field (in order of appearance in
   // the form) in which a substring is encountered.
   WebInputElement chosen_field;
@@ -233,19 +251,21 @@
   }
 
   if (fields_found > 0 && fields_found <= 2) {
-    *username_element = chosen_field;
-    return true;
-  } else {
-    return false;
+    if (std::find(username_predictions->begin(), username_predictions->end(),
+                  chosen_field) == username_predictions->end()) {
+      username_predictions->push_back(chosen_field);
+    }
   }
 }
 
-// Find username element if there is no cached result for the given form.
-bool FindUsernameFieldInternal(
-    const std::vector<blink::WebInputElement>& all_possible_usernames,
+// Find username elements if there is no cached result for the given form and
+// add them to |username_predictions| in the order of decreasing relibility.
+void FindUsernameFieldInternal(
+    const std::vector<blink::WebFormControlElement>& all_control_elements,
     const FormData& form_data,
-    WebInputElement* username_element) {
-  DCHECK(username_element);
+    std::vector<blink::WebInputElement>* username_predictions) {
+  DCHECK(username_predictions);
+  DCHECK(username_predictions->empty());
 
   static const CategoryOfWords kUsernameCategory = {
       kUsernameLatin, kUsernameLatinSize, kUsernameNonLatin,
@@ -263,14 +283,33 @@
       kUsernameCategory, kUserCategory, kTechnicalCategory, kWeakCategory};
 
   std::vector<UsernameFieldData> possible_usernames_data;
-  InferUsernameFieldData(all_possible_usernames, form_data,
+
+  InferUsernameFieldData(all_control_elements, form_data,
                          &possible_usernames_data);
   RemoveFieldsWithNegativeWords(&possible_usernames_data);
 
   // These are the searches performed by the username detector.
   for (const CategoryOfWords& category : kPositiveCategories) {
-    if (FormContainsWordFromCategory(possible_usernames_data, category,
-                                     username_element)) {
+    FindWordsFromCategoryInForm(possible_usernames_data, category,
+                                username_predictions);
+  }
+}
+
+// Find the first element in |username_predictions| (i.e. the most reliable
+// prediction) that occurs in |possible_usernames|. If the element found, the
+// method saves it to |username_element| and returns true.
+bool FindUsernameInPredictions(
+    const std::vector<blink::WebInputElement>& username_predictions,
+    const std::vector<blink::WebInputElement>& possible_usernames,
+    WebInputElement* username_element) {
+  // To keep linear time complexity, convert |possible_usernames| to a set.
+  const base::flat_set<blink::WebInputElement> usernames(
+      possible_usernames.begin(), possible_usernames.end());
+
+  for (const blink::WebInputElement& prediction : username_predictions) {
+    auto iter = usernames.find(prediction);
+    if (iter != usernames.end()) {
+      *username_element = *iter;
       return true;
     }
   }
@@ -280,23 +319,22 @@
 }  // namespace
 
 bool GetUsernameFieldBasedOnHtmlAttributes(
-    const std::vector<blink::WebInputElement>& all_possible_usernames,
+    const std::vector<blink::WebFormControlElement>& all_control_elements,
+    const std::vector<blink::WebInputElement>& possible_usernames,
     const FormData& form_data,
     WebInputElement* username_element,
     UsernameDetectorCache* username_detector_cache) {
   DCHECK(username_element);
 
-  if (all_possible_usernames.empty())
+  if (possible_usernames.empty())
     return false;
 
-  // All elements in |all_possible_usernames| should have the same |Form()|.
+  // All elements in |possible_usernames| and |all_control_elements| should have
+  // the same |Form()|.
   DCHECK(
-      std::adjacent_find(
-          all_possible_usernames.begin(), all_possible_usernames.end(),
-          [](const blink::WebInputElement& a, const blink::WebInputElement& b) {
-            return a.Form() != b.Form();
-          }) == all_possible_usernames.end());
-  const blink::WebFormElement form = all_possible_usernames[0].Form();
+      AllElementsBelongsToSameForm(all_control_elements, possible_usernames));
+
+  const blink::WebFormElement form = possible_usernames[0].Form();
 
   // True if the cache has no entry for |form|.
   bool cache_miss = true;
@@ -304,19 +342,22 @@
   UsernameDetectorCache::iterator form_position;
   if (username_detector_cache) {
     std::tie(form_position, cache_miss) = username_detector_cache->insert(
-        std::make_pair(form, blink::WebInputElement()));
+        std::make_pair(form, std::vector<blink::WebInputElement>()));
   }
 
   if (!username_detector_cache || cache_miss) {
-    bool username_found = FindUsernameFieldInternal(
-        all_possible_usernames, form_data, username_element);
-    if (username_detector_cache && username_found)
-      form_position->second = *username_element;
-    return username_found;
-  } else {
-    *username_element = form_position->second;
-    return !username_element->IsNull();
+    std::vector<blink::WebInputElement> username_predictions;
+    FindUsernameFieldInternal(all_control_elements, form_data,
+                              &username_predictions);
+    bool result = FindUsernameInPredictions(
+        username_predictions, possible_usernames, username_element);
+    if (username_detector_cache && !username_predictions.empty())
+      form_position->second = std::move(username_predictions);
+    return result;
   }
+
+  return FindUsernameInPredictions(form_position->second, possible_usernames,
+                                   username_element);
 }
 
 }  // namespace autofill
diff --git a/components/autofill/content/renderer/html_based_username_detector.h b/components/autofill/content/renderer/html_based_username_detector.h
index a7089fd..4f589ff 100644
--- a/components/autofill/content/renderer/html_based_username_detector.h
+++ b/components/autofill/content/renderer/html_based_username_detector.h
@@ -10,8 +10,10 @@
 
 namespace autofill {
 
+// The detector's cache is a map from WebFormElement to the list of predictions
+// for the given form (in the order of decreasing reliability).
 using UsernameDetectorCache =
-    std::map<blink::WebFormElement, blink::WebInputElement>;
+    std::map<blink::WebFormElement, std::vector<blink::WebInputElement>>;
 
 // Classifier for getting username field by analyzing HTML attribute values.
 // The algorithm looks for words that are likely to point to username field
@@ -20,12 +22,13 @@
 // and the algorithm ends. By searching for words in order of their probability
 // to be username words, it is sure that the first match will also be the best
 // one. The function returns true if username element was found.
-// If the result for the given form is cached in |username_detector_cache|, then
-// |username_element| is set to the cached result. Otherwise, the classifier
-// will be run and the outcome will be saved to the cache.
-// |username_detector_cache| can be null.
+// If detector's outcome for the given form is cached in
+// |username_detector_cache|, then |username_element| is set based on the cached
+// data. Otherwise, the detector will be run and the outcome will be saved to
+// the cache. |username_detector_cache| can be null.
 bool GetUsernameFieldBasedOnHtmlAttributes(
-    const std::vector<blink::WebInputElement>& all_possible_usernames,
+    const std::vector<blink::WebFormControlElement>& all_control_elements,
+    const std::vector<blink::WebInputElement>& possible_usernames,
     const FormData& form_data,
     blink::WebInputElement* username_element,
     UsernameDetectorCache* username_detector_cache);
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc
index f96cde1..f916307dc 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -491,7 +491,7 @@
   std::map<blink::WebInputElement, blink::WebInputElement>
       last_text_input_without_heuristics;
 
-  std::vector<WebInputElement> all_possible_usernames;
+  std::vector<WebInputElement> possible_usernames;
 
   std::map<WebInputElement, PasswordFormFieldPredictionType> predicted_elements;
   if (form_predictions) {
@@ -595,7 +595,7 @@
     // Various input types such as text, url, email can be a username field.
     if (!input_element->IsPasswordFieldForAutofill()) {
       if (!input_element->Value().IsEmpty()) {
-        all_possible_usernames.push_back(*input_element);
+        possible_usernames.push_back(*input_element);
       }
       if (HasAutocompleteAttributeValue(*input_element,
                                         kAutocompleteUsername)) {
@@ -660,11 +660,12 @@
           password_manager::features::kEnableHtmlBasedUsernameDetector)) {
     if (username_element.IsNull()) {
       GetUsernameFieldBasedOnHtmlAttributes(
-          all_possible_usernames, password_form->form_data, &username_element,
-          username_detector_cache);
-      if (!username_element.IsNull())
+          form.control_elements, possible_usernames, password_form->form_data,
+          &username_element, username_detector_cache);
+      if (!username_element.IsNull()) {
         username_detection_method =
             UsernameDetectionMethod::HTML_BASED_CLASSIFIER;
+      }
     }
   }
 
@@ -753,19 +754,21 @@
       form_util::GetCanonicalOriginForDocument(form.document);
   password_form->signon_realm = GetSignOnRealm(password_form->origin);
 
-  // Remove |username_element| from the vector |all_possible_usernames| if the
+  // Remove |username_element| from the vector |possible_usernames| if the
   // value presents in the vector.
   if (!username_element.IsNull()) {
-    all_possible_usernames.erase(
-        std::remove(all_possible_usernames.begin(),
-                    all_possible_usernames.end(), username_element),
-        all_possible_usernames.end());
+    possible_usernames.erase(
+        std::remove(possible_usernames.begin(), possible_usernames.end(),
+                    username_element),
+        possible_usernames.end());
   }
   // Convert |all_possible_usernames| to PossibleUsernamesVector.
   autofill::PossibleUsernamesVector other_possible_usernames;
-  for (WebInputElement possible_username : all_possible_usernames) {
-    other_possible_usernames.push_back(
-        MakePossibleUsernamePair(possible_username));
+  for (WebInputElement possible_username : possible_usernames) {
+    if (!possible_username.Value().IsEmpty()) {
+      other_possible_usernames.push_back(
+          MakePossibleUsernamePair(possible_username));
+    }
   }
   password_form->other_possible_usernames.swap(other_possible_usernames);
 
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
index edc95b4..c3eb4dc 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -462,10 +462,10 @@
               password_form->username_value);
     // Check that the username field was found by HTML detector.
     ASSERT_EQ(1u, username_detector_cache_.size());
-    ASSERT_FALSE(username_detector_cache_.begin()->second.IsNull());
+    ASSERT_FALSE(username_detector_cache_.begin()->second.empty());
     EXPECT_EQ(
         cases[i].expected_username_element,
-        username_detector_cache_.begin()->second.NameForAutofill().Utf8());
+        username_detector_cache_.begin()->second[0].NameForAutofill().Utf8());
   }
 }
 
@@ -496,9 +496,10 @@
   EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
   // Check that the username field was found by HTML detector.
   ASSERT_EQ(1u, username_detector_cache_.size());
-  ASSERT_FALSE(username_detector_cache_.begin()->second.IsNull());
-  EXPECT_EQ("loginid",
-            username_detector_cache_.begin()->second.NameForAutofill().Utf8());
+  ASSERT_EQ(1u, username_detector_cache_.begin()->second.size());
+  EXPECT_EQ(
+      "loginid",
+      username_detector_cache_.begin()->second[0].NameForAutofill().Utf8());
 }
 
 TEST_F(MAYBE_PasswordFormConversionUtilsTest,
@@ -615,10 +616,10 @@
               password_form->username_value);
     // Check that the username field was found by HTML detector.
     ASSERT_EQ(1u, username_detector_cache_.size());
-    ASSERT_FALSE(username_detector_cache_.begin()->second.IsNull());
+    ASSERT_FALSE(username_detector_cache_.begin()->second.empty());
     EXPECT_EQ(
         cases[i].expected_username_element,
-        username_detector_cache_.begin()->second.NameForAutofill().Utf8());
+        username_detector_cache_.begin()->second[0].NameForAutofill().Utf8());
   }
 }
 
@@ -635,17 +636,17 @@
   std::string html = builder.ProduceHTML();
   WebFormElement form;
   LoadWebFormFromHTML(html, &form, nullptr);
-  UsernameDetectorCache username_detector_cache;
+  UsernameDetectorCache detector_cache;
 
   // No signals from HTML attributes. The classifier found nothing and cached
   // it.
   base::HistogramTester histogram_tester;
-  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
-      form, nullptr, nullptr, &username_detector_cache);
+  std::unique_ptr<PasswordForm> password_form =
+      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
   EXPECT_TRUE(password_form);
-  ASSERT_EQ(1u, username_detector_cache.size());
-  EXPECT_EQ(form, username_detector_cache.begin()->first);
-  EXPECT_EQ(blink::WebInputElement(), username_detector_cache.begin()->second);
+  ASSERT_EQ(1u, detector_cache.size());
+  EXPECT_EQ(form, detector_cache.begin()->first);
+  EXPECT_TRUE(detector_cache.begin()->second.empty());
   histogram_tester.ExpectUniqueSample("PasswordManager.UsernameDetectionMethod",
                                       UsernameDetectionMethod::BASE_HEURISTIC,
                                       1);
@@ -655,27 +656,26 @@
   WebVector<WebFormControlElement> control_elements;
   form.GetFormControlElements(control_elements);
   control_elements[0].SetAttribute("name", "id");
-  password_form = CreatePasswordFormFromWebForm(form, nullptr, nullptr,
-                                                &username_detector_cache);
+  password_form =
+      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
   EXPECT_TRUE(password_form);
-  ASSERT_EQ(1u, username_detector_cache.size());
-  EXPECT_EQ(form, username_detector_cache.begin()->first);
-  EXPECT_EQ(blink::WebInputElement(), username_detector_cache.begin()->second);
+  ASSERT_EQ(1u, detector_cache.size());
+  EXPECT_EQ(form, detector_cache.begin()->first);
+  EXPECT_TRUE(detector_cache.begin()->second.empty());
   histogram_tester.ExpectUniqueSample("PasswordManager.UsernameDetectionMethod",
                                       UsernameDetectionMethod::BASE_HEURISTIC,
                                       2);
 
   // Clear the cache. The classifier will find username field and cache it.
-  username_detector_cache.clear();
+  detector_cache.clear();
   ASSERT_EQ(4u, control_elements.size());
-  password_form = CreatePasswordFormFromWebForm(form, nullptr, nullptr,
-                                                &username_detector_cache);
+  password_form =
+      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
   EXPECT_TRUE(password_form);
-  ASSERT_EQ(1u, username_detector_cache.size());
-  EXPECT_EQ(form, username_detector_cache.begin()->first);
-  ASSERT_FALSE(username_detector_cache.begin()->second.IsNull());
-  EXPECT_EQ("id",
-            username_detector_cache.begin()->second.NameForAutofill().Utf8());
+  ASSERT_EQ(1u, detector_cache.size());
+  EXPECT_EQ(form, detector_cache.begin()->first);
+  ASSERT_EQ(1u, detector_cache.begin()->second.size());
+  EXPECT_EQ("id", detector_cache.begin()->second[0].NameForAutofill().Utf8());
   EXPECT_THAT(
       histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"),
       testing::UnorderedElementsAre(
@@ -685,14 +685,13 @@
   // Change the attributes again ("username" is stronger signal than "login"),
   // but keep the cache. The classifier's output should be the same.
   control_elements[1].SetAttribute("name", "username");
-  password_form = CreatePasswordFormFromWebForm(form, nullptr, nullptr,
-                                                &username_detector_cache);
+  password_form =
+      CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache);
   EXPECT_TRUE(password_form);
-  ASSERT_EQ(1u, username_detector_cache.size());
-  EXPECT_EQ(form, username_detector_cache.begin()->first);
-  ASSERT_FALSE(username_detector_cache.begin()->second.IsNull());
-  EXPECT_EQ("id",
-            username_detector_cache.begin()->second.NameForAutofill().Utf8());
+  ASSERT_EQ(1u, detector_cache.size());
+  EXPECT_EQ(form, detector_cache.begin()->first);
+  ASSERT_EQ(1u, detector_cache.begin()->second.size());
+  EXPECT_EQ("id", detector_cache.begin()->second[0].NameForAutofill().Utf8());
   EXPECT_THAT(
       histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"),
       testing::UnorderedElementsAre(
@@ -701,6 +700,51 @@
 }
 
 TEST_F(MAYBE_PasswordFormConversionUtilsTest,
+       HTMLDetectorCache_SkipSomePredictions) {
+  // The cache of HTML based username detector may contain several predictions
+  // (in the order of decreasing reliability) for the given form, but the
+  // detector should consider only |possible_usernames| passed to
+  // GetUsernameFieldBasedOnHtmlAttributes. For example, if a field has no user
+  // input while others has, the field cannot be an username field.
+
+  PasswordFormBuilder builder(kTestFormActionURL);
+  builder.AddTextField("username", "12345", nullptr);
+  builder.AddTextField("email", "smith@google.com", nullptr);
+  builder.AddTextField("id", "12345", nullptr);
+  builder.AddPasswordField("password", "secret", nullptr);
+  builder.AddSubmitButton("submit");
+  std::string html = builder.ProduceHTML();
+  WebFormElement form;
+  LoadWebFormFromHTML(html, &form, nullptr);
+  WebVector<WebFormControlElement> control_elements;
+  form.GetFormControlElements(control_elements);
+  ASSERT_FALSE(control_elements.empty());
+
+  // Add predictions for "email" and "id" fields to the cache.
+  UsernameDetectorCache username_detector_cache;
+  username_detector_cache[control_elements[0].Form()] = {
+      *ToWebInputElement(&control_elements[1]),   // email
+      *ToWebInputElement(&control_elements[2])};  // id
+
+  // A user typed only into "id" and "password" fields. So, the prediction for
+  // "email" field should be ignored despite it is more reliable than prediction
+  // for "id" field.
+  FieldValueAndPropertiesMaskMap user_input;
+  user_input[control_elements[2]] = std::make_pair(  // id
+      base::MakeUnique<base::string16>(control_elements[2].Value().Utf16()),
+      FieldPropertiesFlags::USER_TYPED);
+  user_input[control_elements[3]] = std::make_pair(  // password
+      base::MakeUnique<base::string16>(control_elements[3].Value().Utf16()),
+      FieldPropertiesFlags::USER_TYPED);
+
+  std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm(
+      form, &user_input, nullptr, &username_detector_cache);
+
+  ASSERT_TRUE(password_form);
+  EXPECT_EQ(base::UTF8ToUTF16("id"), password_form->username_element);
+}
+
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
        IdentifyingUsernameFieldsWithBaseHeuristic) {
   // Each test case consists of a set of parameters to be plugged into the
   // PasswordFormBuilder below, plus the corresponding expectations.
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 7204fe1..a929053 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
@@ -182,7 +182,7 @@
 void DataReductionProxyConfig::OnNewClientConfigFetched() {
   DCHECK(thread_checker_.CalledOnValidThread());
   ReloadConfig();
-  FetchWarmupURL();
+  FetchWarmupProbeURL();
 }
 
 void DataReductionProxyConfig::ReloadConfig() {
@@ -394,7 +394,7 @@
         base::Bind(&DataReductionProxyConfig::HandleSecureProxyCheckResponse,
                    base::Unretained(this)));
   }
-  FetchWarmupURL();
+  FetchWarmupProbeURL();
 }
 
 void DataReductionProxyConfig::HandleCaptivePortal() {
@@ -425,12 +425,19 @@
   enabled_by_user_ = enabled;
   network_properties_manager_->SetIsSecureProxyDisallowedByCarrier(
       !secure_proxies_allowed);
-  network_properties_manager_->SetHasWarmupURLProbeFailed(
-      false /* secure_proxy */, false /* is_core_proxy */,
-      !insecure_proxies_allowed);
-  network_properties_manager_->SetHasWarmupURLProbeFailed(
-      false /* secure_proxy */, true /* is_core_proxy */,
-      !insecure_proxies_allowed);
+  if (!insecure_proxies_allowed !=
+          network_properties_manager_->HasWarmupURLProbeFailed(
+              false /* secure_proxy */, false /* is_core_proxy */) ||
+      !insecure_proxies_allowed !=
+          network_properties_manager_->HasWarmupURLProbeFailed(
+              false /* secure_proxy */, true /* is_core_proxy */)) {
+    network_properties_manager_->SetHasWarmupURLProbeFailed(
+        false /* secure_proxy */, false /* is_core_proxy */,
+        !insecure_proxies_allowed);
+    network_properties_manager_->SetHasWarmupURLProbeFailed(
+        false /* secure_proxy */, true /* is_core_proxy */,
+        !insecure_proxies_allowed);
+  }
 }
 
 void DataReductionProxyConfig::SetNetworkPropertiesManagerForTesting(
@@ -438,6 +445,44 @@
   network_properties_manager_ = manager;
 }
 
+base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+DataReductionProxyConfig::GetProxyConnectionToProbe() const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  const std::vector<DataReductionProxyServer>& proxies =
+      DataReductionProxyConfig::GetProxiesForHttp();
+
+  for (const auto proxy_server : proxies) {
+    // First find a proxy server that has never been probed before. Proxies that
+    // have been probed before successfully do not need to be probed. On the
+    // other hand, proxies that have been probed before unsuccessfully are
+    // already disabled, and so they need not be probed immediately.
+    bool is_secure_proxy = proxy_server.IsSecureProxy();
+    bool is_core_proxy = proxy_server.IsCoreProxy();
+    if (!network_properties_manager_->HasWarmupURLProbeFailed(is_secure_proxy,
+                                                              is_core_proxy) &&
+        network_properties_manager_->ShouldFetchWarmupProbeURL(is_secure_proxy,
+                                                               is_core_proxy)) {
+      return std::make_pair(is_secure_proxy, is_core_proxy);
+    }
+  }
+
+  for (const auto proxy_server : proxies) {
+    // Now find any proxy server that can be probed. This would return proxies
+    // that were probed before, the result was unsuccessful, but they have not
+    // yet hit the maximum probe retry limit.
+    bool is_secure_proxy = proxy_server.IsSecureProxy();
+    bool is_core_proxy = proxy_server.IsCoreProxy();
+    if (network_properties_manager_->ShouldFetchWarmupProbeURL(is_secure_proxy,
+                                                               is_core_proxy)) {
+      return std::make_pair(is_secure_proxy, is_core_proxy);
+    }
+  }
+
+  // No more proxies left to probe.
+  return base::nullopt;
+}
+
 void DataReductionProxyConfig::HandleWarmupFetcherResponse(
     const net::ProxyServer& proxy_server,
     bool success_response) {
@@ -449,19 +494,26 @@
     return;
   }
 
-  bool is_secure_drp_proxy = proxy_server.is_https() || proxy_server.is_quic();
+  bool is_secure_proxy = proxy_server.is_https() || proxy_server.is_quic();
   bool is_core_proxy = IsDataReductionProxyServerCore(proxy_server);
-  if (is_secure_drp_proxy && is_core_proxy) {
+
+  // The proxy server through which the warmup URL was fetched should match
+  // the proxy server for which the warmup URL is in-flight.
+  DCHECK(GetInFlightWarmupProxyDetails());
+  DCHECK_EQ(is_secure_proxy, GetInFlightWarmupProxyDetails()->first);
+  DCHECK_EQ(is_core_proxy, GetInFlightWarmupProxyDetails()->second);
+
+  if (is_secure_proxy && is_core_proxy) {
     UMA_HISTOGRAM_BOOLEAN(
         "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
         "SecureProxy.Core",
         success_response);
-  } else if (is_secure_drp_proxy && !is_core_proxy) {
+  } else if (is_secure_proxy && !is_core_proxy) {
     UMA_HISTOGRAM_BOOLEAN(
         "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
         "SecureProxy.NonCore",
         success_response);
-  } else if (!is_secure_drp_proxy && is_core_proxy) {
+  } else if (!is_secure_proxy && is_core_proxy) {
     UMA_HISTOGRAM_BOOLEAN(
         "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
         "InsecureProxy.Core",
@@ -474,18 +526,22 @@
   }
 
   bool warmup_url_failed_past =
-      network_properties_manager_->HasWarmupURLProbeFailed(is_secure_drp_proxy,
+      network_properties_manager_->HasWarmupURLProbeFailed(is_secure_proxy,
                                                            is_core_proxy);
 
   network_properties_manager_->SetHasWarmupURLProbeFailed(
-      is_secure_drp_proxy, is_core_proxy,
-      !success_response /* warmup failed */);
+      is_secure_proxy, is_core_proxy, !success_response /* warmup failed */);
 
   if (warmup_url_failed_past !=
-      network_properties_manager_->HasWarmupURLProbeFailed(is_secure_drp_proxy,
+      network_properties_manager_->HasWarmupURLProbeFailed(is_secure_proxy,
                                                            is_core_proxy)) {
     ReloadConfig();
   }
+
+  // May probe other proxy types that have not been probed yet, or may retry
+  // probe of proxy types that has failed but the maximum probe limit has not
+  // been reached yet.
+  FetchWarmupProbeURL();
 }
 
 void DataReductionProxyConfig::HandleSecureProxyCheckResponse(
@@ -549,7 +605,7 @@
 
   ReloadConfig();
 
-  FetchWarmupURL();
+  FetchWarmupProbeURL();
 
   if (enabled_by_user_) {
     HandleCaptivePortal();
@@ -603,7 +659,7 @@
   secure_proxy_checker_->CheckIfSecureProxyIsAllowed(fetcher_callback);
 }
 
-void DataReductionProxyConfig::FetchWarmupURL() {
+void DataReductionProxyConfig::FetchWarmupProbeURL() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   if (!enabled_by_user_) {
@@ -612,7 +668,7 @@
     return;
   }
 
-  if (!params::FetchWarmupURLEnabled()) {
+  if (!params::FetchWarmupProbeURLEnabled()) {
     RecordWarmupURLFetchAttemptEvent(
         WarmupURLFetchAttemptEvent::kWarmupURLFetchingDisabled);
     return;
@@ -624,8 +680,23 @@
     return;
   }
 
+  base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+      warmup_config = GetProxyConnectionToProbe();
+
+  if (!warmup_config)
+    return;
+
+  // Refetch the warmup URL when it has failed.
+  warmup_url_fetch_in_flight_secure_proxy_ = warmup_config->first;
+  warmup_url_fetch_in_flight_core_proxy_ = warmup_config->second;
+
+  network_properties_manager_->OnWarmupFetchInitiated(
+      warmup_url_fetch_in_flight_secure_proxy_,
+      warmup_url_fetch_in_flight_core_proxy_);
+
   RecordWarmupURLFetchAttemptEvent(WarmupURLFetchAttemptEvent::kFetchInitiated);
 
+  // TODO(tbansal): https://crbug.com/760294. Use exponential backoffs.
   warmup_url_fetcher_->FetchWarmupURL();
 }
 
@@ -681,7 +752,8 @@
 net::ProxyConfig DataReductionProxyConfig::ProxyConfigIgnoringHoldback() const {
   if (!enabled_by_user_ || config_values_->proxies_for_http().empty())
     return net::ProxyConfig::CreateDirect();
-  return configurator_->CreateProxyConfig(*network_properties_manager_,
+  return configurator_->CreateProxyConfig(false /* probe_url_config */,
+                                          *network_properties_manager_,
                                           config_values_->proxies_for_http());
 }
 
@@ -749,4 +821,20 @@
   return *network_properties_manager_;
 }
 
+bool DataReductionProxyConfig::IsFetchInFlight() const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  return warmup_url_fetcher_->IsFetchInFlight();
+}
+
+base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+DataReductionProxyConfig::GetInFlightWarmupProxyDetails() const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (!IsFetchInFlight())
+    return base::nullopt;
+
+  return std::make_pair(warmup_url_fetch_in_flight_secure_proxy_,
+                        warmup_url_fetch_in_flight_core_proxy_);
+}
+
 }  // namespace data_reduction_proxy
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 f9e518f..4f9117a4 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
@@ -20,6 +20,7 @@
 #include "base/time/time.h"
 #include "components/data_reduction_proxy/core/browser/secure_proxy_checker.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
+#include "components/data_reduction_proxy/proto/client_config.pb.h"
 #include "components/previews/core/previews_experiments.h"
 #include "net/base/network_change_notifier.h"
 #include "net/log/net_log_with_source.h"
@@ -201,6 +202,12 @@
   // saver proxy is currently allowed or not.
   const NetworkPropertiesManager& GetNetworkPropertiesManager() const;
 
+  // Returns the details of the proxy to which the warmup URL probe is
+  // in-flight. Returns base::nullopt if no warmup probe is in-flight.
+  virtual base::Optional<
+      std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+  GetInFlightWarmupProxyDetails() const;
+
  protected:
   virtual base::TimeTicks GetTicksNow() const;
 
@@ -223,6 +230,14 @@
   void HandleWarmupFetcherResponse(const net::ProxyServer& proxy_server,
                                    bool success_response);
 
+  // Returns the details of the proxy to which the next warmup URL probe should
+  // be sent to.
+  base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+  GetProxyConnectionToProbe() const;
+
+  // Returns true if a warmup URL probe is in-flight. Virtualized for testing.
+  virtual bool IsFetchInFlight() const;
+
  private:
   friend class MockDataReductionProxyConfig;
   friend class TestDataReductionProxyConfig;
@@ -295,7 +310,7 @@
   virtual bool GetIsCaptivePortal() const;
 
   // Fetches the warmup URL.
-  void FetchWarmupURL();
+  void FetchWarmupProbeURL();
 
   // Returns true if |proxy_server| is a core data reduction proxy server.
   // Should be called only if |proxy_server| is a valid data reduction proxy
@@ -337,6 +352,12 @@
   // The current connection type.
   net::NetworkChangeNotifier::ConnectionType connection_type_;
 
+  // Stores the properties of the proxy which is currently being probed. The
+  // values are valid only if a probe (or warmup URL) fetch is currently
+  // in-flight.
+  bool warmup_url_fetch_in_flight_secure_proxy_;
+  bool warmup_url_fetch_in_flight_core_proxy_;
+
   // Should be accessed only on the IO thread. Guaranteed to be non-null during
   // the lifetime of |this| if accessed on the IO thread.
   NetworkPropertiesManager* network_properties_manager_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
index f3ba9fa9..a0e43a8 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
@@ -134,6 +134,30 @@
   current_network_id_ = network_id;
 }
 
+base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+TestDataReductionProxyConfig::GetInFlightWarmupProxyDetails() const {
+  if (in_flight_warmup_proxy_details_)
+    return in_flight_warmup_proxy_details_;
+  return DataReductionProxyConfig::GetInFlightWarmupProxyDetails();
+}
+
+void TestDataReductionProxyConfig::SetInFlightWarmupProxyDetails(
+    base::Optional<
+        std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+        in_flight_warmup_proxy_details) {
+  in_flight_warmup_proxy_details_ = in_flight_warmup_proxy_details;
+}
+
+bool TestDataReductionProxyConfig::IsFetchInFlight() const {
+  if (fetch_in_flight_)
+    return fetch_in_flight_.value();
+  return DataReductionProxyConfig::IsFetchInFlight();
+}
+
+void TestDataReductionProxyConfig::SetIsFetchInFlight(bool fetch_in_flight) {
+  fetch_in_flight_ = fetch_in_flight;
+}
+
 MockDataReductionProxyConfig::MockDataReductionProxyConfig(
     std::unique_ptr<DataReductionProxyConfigValues> config_values,
     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
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 046df80..5790c1b 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
@@ -106,6 +106,18 @@
 
   void SetCurrentNetworkID(const std::string& network_id);
 
+  base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+  GetInFlightWarmupProxyDetails() const override;
+
+  void SetInFlightWarmupProxyDetails(
+      base::Optional<
+          std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+          in_flight_warmup_proxy_details);
+
+  bool IsFetchInFlight() const override;
+
+  void SetIsFetchInFlight(bool fetch_in_flight);
+
   using DataReductionProxyConfig::UpdateConfigForTesting;
   using DataReductionProxyConfig::HandleWarmupFetcherResponse;
 
@@ -119,6 +131,9 @@
 
   base::Optional<std::string> current_network_id_;
 
+  base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+      in_flight_warmup_proxy_details_;
+
   // Set to true if the captive portal probe for the current network has been
   // blocked.
   bool is_captive_portal_;
@@ -127,6 +142,8 @@
   // when fetching resources from an embedded test server running on localhost.
   bool add_default_proxy_bypass_rules_;
 
+  base::Optional<bool> fetch_in_flight_;
+
   DISALLOW_COPY_AND_ASSIGN(TestDataReductionProxyConfig);
 };
 
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 4e7b794..a72ff7bf 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
@@ -475,7 +475,7 @@
       // the test device does not have connectivity.
       config.connection_type_ = net::NetworkChangeNotifier::CONNECTION_WIFI;
       config.SetProxyConfig(test.data_reduction_proxy_enabled, true);
-      ASSERT_TRUE(params::FetchWarmupURLEnabled());
+      ASSERT_TRUE(params::FetchWarmupProbeURLEnabled());
 
       if (test.data_reduction_proxy_enabled) {
         histogram_tester.ExpectUniqueSample(
@@ -1032,6 +1032,10 @@
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
             GetConfiguredProxiesForHttp());
 
+  // Set the details of the proxy to which the warmup URL probe is in-flight to
+  // avoid triggering the DCHECKs in HandleWarmupFetcherResponse method.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(true /* is_secure_proxy */, false /* is_core_proxy */));
   // Report successful warmup of |kHttpsProxy|.
   test_config()->HandleWarmupFetcherResponse(kHttpsProxy, true);
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
@@ -1043,6 +1047,8 @@
 
   // Report failed warmup |kHttpsProxy| and verify it is removed from the list
   // of proxies.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(true /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}),
             GetConfiguredProxiesForHttp());
@@ -1053,6 +1059,8 @@
 
   // Report failed warmup |kHttpsProxy| again, and verify it does not change the
   // list of proxies.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(true /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}),
             GetConfiguredProxiesForHttp());
@@ -1062,6 +1070,8 @@
       0, 2);
 
   // |kHttpsProxy| should now be added back to the list of proxies.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(true /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpsProxy, true);
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
             GetConfiguredProxiesForHttp());
@@ -1071,7 +1081,9 @@
       1, 2);
 
   // Report successful warmup |kHttpsProxy| again, and verify that there is no
-  // change in the list of proxies..
+  // change in the list of proxies.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(true /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpsProxy, true);
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
             GetConfiguredProxiesForHttp());
@@ -1081,6 +1093,8 @@
       1, 3);
 
   // |kHttpsProxy| should be removed again from the list of proxies.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(true /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}),
             GetConfiguredProxiesForHttp());
@@ -1095,6 +1109,8 @@
 
   // Now report failed warmup for |kHttpProxy| and verify that it is also
   // removed from the list of proxies.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(false /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
   EXPECT_EQ(std::vector<net::ProxyServer>({}), GetConfiguredProxiesForHttp());
   histogram_tester.ExpectUniqueSample(
@@ -1103,7 +1119,11 @@
       0, 1);
 
   // Both proxies should be added back.
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(true /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpsProxy, true);
+  test_config()->SetInFlightWarmupProxyDetails(
+      std::make_pair(false /* is_secure_proxy */, false /* is_core_proxy */));
   test_config()->HandleWarmupFetcherResponse(kHttpProxy, true);
   EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
             GetConfiguredProxiesForHttp());
@@ -1131,4 +1151,245 @@
             GetConfiguredProxiesForHttp());
 }
 
+TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherRetry) {
+  constexpr size_t kMaxWarmupURLFetchAttempts = 3;
+
+  base::HistogramTester histogram_tester;
+  const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK);
+  const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI(
+      "https://origin.net:443", net::ProxyServer::SCHEME_HTTP);
+  const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI(
+      "fallback.net:80", net::ProxyServer::SCHEME_HTTP);
+
+  SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy});
+  ResetSettings();
+
+  // Enable the proxy.
+  test_config()->UpdateConfigForTesting(true, true, true);
+
+  test_config()->SetIsFetchInFlight(true);
+
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 0);
+  test_config()->OnNewClientConfigFetched();
+  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
+            GetConfiguredProxiesForHttp());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}),
+            GetConfiguredProxiesForHttp());
+
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "InsecureProxy.NonCore",
+      0);
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "SecureProxy.NonCore",
+      0);
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 1);
+
+  // The first probe should go through the HTTPS data saver proxy.
+  test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}),
+            GetConfiguredProxiesForHttp());
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "SecureProxy.NonCore",
+      0, 1);
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 2);
+  test_config()->SetInFlightWarmupProxyDetails(base::nullopt);
+  EXPECT_EQ(std::make_pair(false, false),
+            test_config()->GetInFlightWarmupProxyDetails());
+  base::RunLoop().RunUntilIdle();
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 2);
+
+  // The second probe should go through the HTTP data saver proxy.
+  test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(std::vector<net::ProxyServer>({}), GetConfiguredProxiesForHttp());
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "InsecureProxy.NonCore",
+      0, 1);
+  EXPECT_EQ(std::make_pair(true, false),
+            test_config()->GetInFlightWarmupProxyDetails());
+  base::RunLoop().RunUntilIdle();
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 3);
+
+  EXPECT_EQ(std::make_pair(true, false),
+            test_config()->GetInFlightWarmupProxyDetails());
+
+  for (size_t i = 1; i <= 4; ++i) {
+    // Two more probes should go through the HTTPS data saver proxy, and two
+    // more probes through the HTTP proxy.
+    if (i <= 2) {
+      EXPECT_EQ(std::make_pair(true, false),
+                test_config()->GetInFlightWarmupProxyDetails());
+
+      test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
+    } else {
+      EXPECT_EQ(std::make_pair(false, false),
+                test_config()->GetInFlightWarmupProxyDetails());
+
+      test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
+    }
+    base::RunLoop().RunUntilIdle();
+    histogram_tester.ExpectTotalCount(
+        "DataReductionProxy.WarmupURL.FetchInitiated",
+        std::min(3 + i,
+                 kMaxWarmupURLFetchAttempts + kMaxWarmupURLFetchAttempts));
+  }
+  EXPECT_EQ(std::vector<net::ProxyServer>({}), GetConfiguredProxiesForHttp());
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "SecureProxy.NonCore",
+      1, 0);
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "SecureProxy.NonCore",
+      0, 3);
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "InsecureProxy.NonCore",
+      1, 0);
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch."
+      "InsecureProxy.NonCore",
+      0, 3);
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 6);
+
+  for (size_t i = 1; i <= 10; ++i) {
+    // Set the details of the proxy to which the warmup URL probe is in-flight
+    // to avoid triggering the DCHECKs in HandleWarmupFetcherResponse method.
+    test_config()->SetInFlightWarmupProxyDetails(
+        std::make_pair(false /* is_secure_proxy */, false /* is_core_proxy */));
+
+    // Fetcher callback should not trigger fetching of probe URL since
+    // kMaxWarmupURLFetchAttempts probes have been tried through each of the
+    // data saver proxy.
+    test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
+    base::RunLoop().RunUntilIdle();
+    // At most kMaxWarmupURLFetchAttempts warmup URLs should be fetched via
+    // each of the two insecure proxies.
+    histogram_tester.ExpectTotalCount(
+        "DataReductionProxy.WarmupURL.FetchInitiated",
+        kMaxWarmupURLFetchAttempts + kMaxWarmupURLFetchAttempts);
+  }
+
+  test_config()->SetInFlightWarmupProxyDetails(base::nullopt);
+}
+
+TEST_F(DataReductionProxyConfigTest,
+       HandleWarmupFetcherRetryWithConnectionChange) {
+  constexpr size_t kMaxWarmupURLFetchAttempts = 3;
+
+  base::HistogramTester histogram_tester;
+  const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK);
+  const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI(
+      "https://origin.net:443", net::ProxyServer::SCHEME_HTTP);
+  const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI(
+      "fallback.net:80", net::ProxyServer::SCHEME_HTTP);
+
+  SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy});
+  ResetSettings();
+
+  // Enable the proxy.
+  test_config()->UpdateConfigForTesting(true, true, true);
+
+  test_config()->SetIsFetchInFlight(true);
+
+  test_config()->OnNewClientConfigFetched();
+
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 1);
+
+  // The first probe should go through the HTTPS data saver proxy.
+  test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
+  base::RunLoop().RunUntilIdle();
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 2);
+  test_config()->SetInFlightWarmupProxyDetails(base::nullopt);
+  base::RunLoop().RunUntilIdle();
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 2);
+
+  // The second probe should go through the HTTP data saver proxy.
+  test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(std::vector<net::ProxyServer>({}), GetConfiguredProxiesForHttp());
+  base::RunLoop().RunUntilIdle();
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 3);
+
+  EXPECT_EQ(std::make_pair(true, false),
+            test_config()->GetInFlightWarmupProxyDetails());
+
+  for (size_t i = 1; i <= 4; ++i) {
+    // Two more probes should go through the HTTPS data saver proxy, and two
+    // more probes through the HTTP proxy.
+    if (i <= 2) {
+      test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
+    } else {
+      test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
+    }
+    base::RunLoop().RunUntilIdle();
+    histogram_tester.ExpectTotalCount(
+        "DataReductionProxy.WarmupURL.FetchInitiated",
+        std::min(3 + i,
+                 kMaxWarmupURLFetchAttempts + kMaxWarmupURLFetchAttempts));
+  }
+  EXPECT_EQ(std::make_pair(false, false),
+            test_config()->GetInFlightWarmupProxyDetails());
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated", 6);
+
+  test_config()->SetInFlightWarmupProxyDetails(base::nullopt);
+  EXPECT_EQ(std::vector<net::ProxyServer>({}), GetConfiguredProxiesForHttp());
+
+  // A change in the connection type should reset the probe fetch attempt count,
+  // and trigger fetching of the probe URL.
+  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+      net::NetworkChangeNotifier::CONNECTION_WIFI);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(std::make_pair(true, false),
+            test_config()->GetInFlightWarmupProxyDetails());
+  EXPECT_NE(std::vector<net::ProxyServer>({}), GetConfiguredProxiesForHttp());
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated",
+      kMaxWarmupURLFetchAttempts + kMaxWarmupURLFetchAttempts + 1);
+
+  // At most kMaxWarmupURLFetchAttempts warmup URLs should be fetched via
+  // secure proxy, and kMaxWarmupURLFetchAttempts via insecure.
+  test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
+  base::RunLoop().RunUntilIdle();
+  test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
+  base::RunLoop().RunUntilIdle();
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated",
+      kMaxWarmupURLFetchAttempts + kMaxWarmupURLFetchAttempts + 3);
+
+  for (size_t i = 1; i <= 2; ++i) {
+    test_config()->HandleWarmupFetcherResponse(kHttpsProxy, false);
+    base::RunLoop().RunUntilIdle();
+  }
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated",
+      kMaxWarmupURLFetchAttempts + kMaxWarmupURLFetchAttempts + 5);
+
+  for (size_t i = 1; i <= 2; ++i) {
+    test_config()->HandleWarmupFetcherResponse(kHttpProxy, false);
+    base::RunLoop().RunUntilIdle();
+  }
+
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.WarmupURL.FetchInitiated",
+      kMaxWarmupURLFetchAttempts + kMaxWarmupURLFetchAttempts + 6);
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc
index f82846c..474ea79 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.cc
@@ -36,7 +36,8 @@
     const std::vector<DataReductionProxyServer>& proxies_for_http) {
   DCHECK(thread_checker_.CalledOnValidThread());
   net::ProxyConfig config =
-      CreateProxyConfig(network_properties_manager, proxies_for_http);
+      CreateProxyConfig(false /* probe_url_config */,
+                        network_properties_manager, proxies_for_http);
   data_reduction_proxy_event_creator_->AddProxyEnabledEvent(
       net_log_, network_properties_manager.IsSecureProxyDisallowedByCarrier(),
       DataReductionProxyServer::ConvertToNetProxyServers(proxies_for_http));
@@ -44,6 +45,7 @@
 }
 
 net::ProxyConfig DataReductionProxyConfigurator::CreateProxyConfig(
+    bool probe_url_config,
     const NetworkPropertiesManager& network_properties_manager,
     const std::vector<DataReductionProxyServer>& proxies_for_http) const {
   DCHECK(thread_checker_.CalledOnValidThread());
@@ -54,22 +56,33 @@
       net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
 
   for (const auto& http_proxy : proxies_for_http) {
-    if (!network_properties_manager.IsSecureProxyAllowed(true) &&
+    // If the config is being generated for fetching the probe URL, then the
+    // proxies that are disabled by the network properties manager are still
+    // added to the proxy config. This is because the network properties manager
+    // may have disabled a proxy because the warmup URL to the proxy has failed
+    // in this session or in a previous session on the same connection. Adding
+    // the proxy enables probing the proxy even though the proxy may not be
+    // usable for non-proble traffic.
+    if (!probe_url_config &&
+        !network_properties_manager.IsSecureProxyAllowed(true) &&
         http_proxy.IsSecureProxy() && http_proxy.IsCoreProxy()) {
       continue;
     }
 
-    if (!network_properties_manager.IsInsecureProxyAllowed(true) &&
+    if (!probe_url_config &&
+        !network_properties_manager.IsInsecureProxyAllowed(true) &&
         !http_proxy.IsSecureProxy() && http_proxy.IsCoreProxy()) {
       continue;
     }
 
-    if (!network_properties_manager.IsSecureProxyAllowed(false) &&
+    if (!probe_url_config &&
+        !network_properties_manager.IsSecureProxyAllowed(false) &&
         http_proxy.IsSecureProxy() && !http_proxy.IsCoreProxy()) {
       continue;
     }
 
-    if (!network_properties_manager.IsInsecureProxyAllowed(false) &&
+    if (!probe_url_config &&
+        !network_properties_manager.IsInsecureProxyAllowed(false) &&
         !http_proxy.IsSecureProxy() && !http_proxy.IsCoreProxy()) {
       continue;
     }
@@ -93,6 +106,7 @@
   // config will return invalid.
   net::ProxyConfig::ID unused_id = 1;
   config.set_id(unused_id);
+
   return config;
 }
 
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 63eb1be..8ddf7f7 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
@@ -56,8 +56,11 @@
   const net::ProxyConfig& GetProxyConfig() const;
 
   // Constructs a proxy configuration suitable for enabling the Data Reduction
-  // proxy.
+  // proxy. |probe_url_config| should be true if the proxy config is needed for
+  // fetching the probe URL. If |probe_url_config| is true, then proxies that
+  // are temporarily disabled may be included in the generated proxy config.
   net::ProxyConfig CreateProxyConfig(
+      bool probe_url_config,
       const NetworkPropertiesManager& network_properties_manager,
       const std::vector<DataReductionProxyServer>& proxies_for_http) const;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
index 2b31cd63..0717a6d4 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_unittest.cc
@@ -82,6 +82,26 @@
     }
   }
 
+  void CheckProbeProxyConfig(
+      const std::vector<DataReductionProxyServer>& http_proxies,
+      bool probe_url_config,
+      const net::ProxyConfig::ProxyRules::Type& expected_rules_type,
+      const std::string& expected_http_proxies,
+      const std::string& expected_bypass_list) {
+    test_context_->RunUntilIdle();
+    net::ProxyConfig::ProxyRules rules =
+        config_
+            ->CreateProxyConfig(probe_url_config, *manager_.get(), http_proxies)
+            .proxy_rules();
+    ASSERT_EQ(expected_rules_type, rules.type);
+    if (net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME ==
+        expected_rules_type) {
+      ASSERT_EQ(expected_http_proxies, rules.proxies_for_http.ToPacString());
+      ASSERT_EQ(std::string(), rules.proxies_for_https.ToPacString());
+      ASSERT_EQ(expected_bypass_list, rules.bypass_rules.ToString());
+    }
+  }
+
   TestingPrefServiceSimple test_prefs;
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   std::unique_ptr<DataReductionProxyTestContext> test_context_;
@@ -232,4 +252,22 @@
   EXPECT_TRUE(expected.Equals(config_->bypass_rules_));
 }
 
+TEST_F(DataReductionProxyConfiguratorTest,
+       TestProbeSecureInsecureCoreRestricted) {
+  manager_->SetHasWarmupURLProbeFailed(true, true, true);
+  manager_->SetHasWarmupURLProbeFailed(false, true, true);
+
+  const std::vector<DataReductionProxyServer>& http_proxies =
+      BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
+                     "http://www.bar.com:80", ProxyServer::CORE);
+  config_->Enable(*manager_, http_proxies);
+  CheckProbeProxyConfig(http_proxies, true /* probe_url_config */,
+                        net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+                        "HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT",
+                        std::string());
+  CheckProbeProxyConfig(http_proxies, false /* probe_url_config */,
+                        net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, "",
+                        std::string());
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
index 1951399..65a3c6c6 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
@@ -145,8 +145,36 @@
                      }),
       proxies_for_http.end());
 
+  base::Optional<std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
+      warmup_proxy = config_->GetInFlightWarmupProxyDetails();
+
+  bool is_warmup_url = warmup_proxy &&
+                       url.host() == params::GetWarmupURL().host() &&
+                       url.path() == params::GetWarmupURL().path();
+
+  if (is_warmup_url) {
+    // This is a request to fetch the warmup (aka probe) URL.
+    // |is_secure_proxy| and |is_core_proxy| indicate the properties of the
+    // proxy that is being currently probed.
+    bool is_secure_proxy = warmup_proxy->first;
+    bool is_core_proxy = warmup_proxy->second;
+    // Remove the proxies with properties that do not match the properties of
+    // the proxy that is being probed.
+    proxies_for_http.erase(
+        std::remove_if(proxies_for_http.begin(), proxies_for_http.end(),
+                       [is_secure_proxy,
+                        is_core_proxy](const DataReductionProxyServer& proxy) {
+                         return proxy.IsSecureProxy() != is_secure_proxy ||
+                                proxy.IsCoreProxy() != is_core_proxy;
+                       }),
+        proxies_for_http.end());
+  }
+
+  // If the proxy is disabled due to warmup URL fetch failing in the past,
+  // then enable it temporarily. This ensures that |configurator_| includes
+  // this proxy type when generating the |proxy_config|.
   net::ProxyConfig proxy_config = configurator_->CreateProxyConfig(
-      config_->GetNetworkPropertiesManager(), proxies_for_http);
+      is_warmup_url, config_->GetNetworkPropertiesManager(), proxies_for_http);
 
   OnResolveProxyHandler(url, method, proxy_config, proxy_retry_info, *config_,
                         io_data_, result);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
index 05966fc..dba34b6 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
@@ -654,6 +654,82 @@
   EXPECT_TRUE(result.is_direct());
 }
 
+TEST_F(DataReductionProxyDelegateTest, OnResolveProxyWarmupURL) {
+  const struct {
+    bool is_secure_proxy;
+    bool is_core_proxy;
+    bool use_warmup_url;
+  } tests[] = {
+      {false, false, false}, {false, true, false}, {true, false, false},
+      {true, true, false},   {false, false, true}, {false, true, true},
+      {true, false, true},   {true, true, true},
+  };
+
+  for (const auto& test : tests) {
+    config()->SetInFlightWarmupProxyDetails(
+        std::make_pair(test.is_secure_proxy, test.is_core_proxy));
+    GURL url;
+    if (test.use_warmup_url) {
+      url = params::GetWarmupURL();
+    } else {
+      url = GURL("http://www.google.com");
+    }
+    params()->UseNonSecureProxiesForHttp();
+
+    // A regular HTTP URL (i.e., a non-warmup URL) should always be fetched
+    // using the data reduction proxies configured by this test framework.
+    bool expect_data_reduction_proxy_used = true;
+
+    if (test.use_warmup_url) {
+      // This test framework only sets insecure, core proxies in the data
+      // reduction proxy configuration. When the in-flight warmup proxy details
+      // are set to a proxy that is either secure or non-core, then all
+      // configured data saver proxies should be removed when doing proxy
+      // resolution for the warmup URL. Hence, the warmup URL will be fetched
+      // directly in all cases except when the in-flight warmup proxy details
+      // match the properties of the data saver proxies configured by this test.
+      expect_data_reduction_proxy_used =
+          !test.is_secure_proxy && test.is_core_proxy;
+    }
+
+    // Other proxy info
+    net::ProxyInfo other_proxy_info;
+    other_proxy_info.UseNamedProxy("proxy.com");
+    EXPECT_FALSE(other_proxy_info.is_empty());
+
+    // Direct
+    net::ProxyInfo direct_proxy_info;
+    direct_proxy_info.UseDirect();
+    EXPECT_TRUE(direct_proxy_info.is_direct());
+
+    // Empty retry info map
+    net::ProxyRetryInfoMap empty_proxy_retry_info;
+
+    net::ProxyInfo result;
+    // Another proxy is used. It should be used afterwards.
+    result.Use(other_proxy_info);
+    proxy_delegate()->OnResolveProxy(url, "GET", empty_proxy_retry_info,
+                                     &result);
+    EXPECT_EQ(other_proxy_info.proxy_server(), result.proxy_server());
+
+    // A direct connection is used. The data reduction proxy should be used
+    // afterwards.
+    result.Use(direct_proxy_info);
+    net::ProxyConfig::ID prev_id = result.config_id();
+    proxy_delegate()->OnResolveProxy(url, "GET", empty_proxy_retry_info,
+                                     &result);
+    //
+    if (expect_data_reduction_proxy_used) {
+      EXPECT_EQ(params()->proxies_for_http().front().proxy_server(),
+                result.proxy_server());
+    } else {
+      EXPECT_TRUE(result.proxy_server().is_direct());
+    }
+    // Only the proxy list should be updated, not the proxy info.
+    EXPECT_EQ(result.config_id(), prev_id);
+  }
+}
+
 // Verifies that requests that were not proxied through data saver proxy due to
 // missing config are recorded properly.
 TEST_F(DataReductionProxyDelegateTest, HTTPRequests) {
diff --git a/components/data_reduction_proxy/core/browser/network_properties_manager.cc b/components/data_reduction_proxy/core/browser/network_properties_manager.cc
index f83490c5..31a64d9 100644
--- a/components/data_reduction_proxy/core/browser/network_properties_manager.cc
+++ b/components/data_reduction_proxy/core/browser/network_properties_manager.cc
@@ -20,6 +20,10 @@
 
 constexpr size_t kMaxCacheSize = 10u;
 
+// Maximum number of times a data saver proxy with unique tuple
+// (is_secure_proxy, is_core_proxy) is probed.
+constexpr size_t kMaxWarmupURLFetchAttempts = 3;
+
 // Parses a base::Value to NetworkProperties struct. If the parsing is
 // unsuccessful, a nullptr is returned.
 base::Optional<NetworkProperties> GetParsedNetworkProperty(
@@ -145,6 +149,16 @@
   pref_manager_.reset(new PrefManager(pref_service));
   pref_manager_weak_ptr_ = pref_manager_->GetWeakPtr();
 
+  has_warmup_url_succeded_secure_core_ = false;
+  has_warmup_url_succeded_secure_non_core_ = false;
+  has_warmup_url_succeded_insecure_core_ = false;
+  has_warmup_url_succeded_insecure_non_core_ = false;
+
+  warmup_url_fetch_attempt_counts_secure_core_ = 0;
+  warmup_url_fetch_attempt_counts_secure_non_core_ = 0;
+  warmup_url_fetch_attempt_counts_insecure_core_ = 0;
+  warmup_url_fetch_attempt_counts_insecure_non_core_ = 0;
+
   DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
@@ -173,6 +187,16 @@
     const std::string& network_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  has_warmup_url_succeded_secure_core_ = false;
+  has_warmup_url_succeded_secure_non_core_ = false;
+  has_warmup_url_succeded_insecure_core_ = false;
+  has_warmup_url_succeded_insecure_non_core_ = false;
+
+  warmup_url_fetch_attempt_counts_secure_core_ = 0;
+  warmup_url_fetch_attempt_counts_secure_non_core_ = 0;
+  warmup_url_fetch_attempt_counts_insecure_core_ = 0;
+  warmup_url_fetch_attempt_counts_insecure_non_core_ = 0;
+
   network_id_ = network_id;
 
   bool cached_entry_found = false;
@@ -290,20 +314,72 @@
     bool is_core_proxy,
     bool warmup_url_probe_failed) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   if (secure_proxy && is_core_proxy) {
+    has_warmup_url_succeded_secure_core_ = !warmup_url_probe_failed;
     network_properties_.mutable_secure_proxy_flags()
         ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed);
   } else if (secure_proxy && !is_core_proxy) {
+    has_warmup_url_succeded_secure_non_core_ = !warmup_url_probe_failed;
     network_properties_.mutable_secure_non_core_proxy_flags()
         ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed);
   } else if (!secure_proxy && is_core_proxy) {
+    has_warmup_url_succeded_insecure_core_ = !warmup_url_probe_failed;
     network_properties_.mutable_insecure_proxy_flags()
         ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed);
   } else {
+    has_warmup_url_succeded_insecure_non_core_ = !warmup_url_probe_failed;
     network_properties_.mutable_insecure_non_core_proxy_flags()
         ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed);
   }
   OnChangeInNetworkPropertyOnIOThread();
 }
 
+bool NetworkPropertiesManager::ShouldFetchWarmupProbeURL(
+    bool secure_proxy,
+    bool is_core_proxy) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (secure_proxy && is_core_proxy) {
+    return !has_warmup_url_succeded_secure_core_ &&
+           warmup_url_fetch_attempt_counts_secure_core_ <
+               kMaxWarmupURLFetchAttempts;
+  } else if (secure_proxy && !is_core_proxy) {
+    return !has_warmup_url_succeded_secure_non_core_ &&
+           warmup_url_fetch_attempt_counts_secure_non_core_ <
+               kMaxWarmupURLFetchAttempts;
+  } else if (!secure_proxy && is_core_proxy) {
+    return !has_warmup_url_succeded_insecure_core_ &&
+           warmup_url_fetch_attempt_counts_insecure_core_ <
+               kMaxWarmupURLFetchAttempts;
+  } else {
+    return !has_warmup_url_succeded_insecure_non_core_ &&
+           warmup_url_fetch_attempt_counts_insecure_non_core_ <
+               kMaxWarmupURLFetchAttempts;
+  }
+}
+
+void NetworkPropertiesManager::OnWarmupFetchInitiated(bool secure_proxy,
+                                                      bool is_core_proxy) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (secure_proxy && is_core_proxy) {
+    ++warmup_url_fetch_attempt_counts_secure_core_;
+    DCHECK_GE(kMaxWarmupURLFetchAttempts,
+              warmup_url_fetch_attempt_counts_secure_core_);
+  } else if (secure_proxy && !is_core_proxy) {
+    ++warmup_url_fetch_attempt_counts_secure_non_core_;
+    DCHECK_GE(kMaxWarmupURLFetchAttempts,
+              warmup_url_fetch_attempt_counts_secure_non_core_);
+  } else if (!secure_proxy && is_core_proxy) {
+    ++warmup_url_fetch_attempt_counts_insecure_core_;
+    DCHECK_GE(kMaxWarmupURLFetchAttempts,
+              warmup_url_fetch_attempt_counts_insecure_core_);
+  } else {
+    ++warmup_url_fetch_attempt_counts_insecure_non_core_;
+    DCHECK_GE(kMaxWarmupURLFetchAttempts,
+              warmup_url_fetch_attempt_counts_insecure_non_core_);
+  }
+}
+
 }  // namespace data_reduction_proxy
\ No newline at end of file
diff --git a/components/data_reduction_proxy/core/browser/network_properties_manager.h b/components/data_reduction_proxy/core/browser/network_properties_manager.h
index b5085ae..c920ec7 100644
--- a/components/data_reduction_proxy/core/browser/network_properties_manager.h
+++ b/components/data_reduction_proxy/core/browser/network_properties_manager.h
@@ -77,6 +77,14 @@
                                   bool is_core_proxy,
                                   bool warmup_url_probe_failed);
 
+  // Returns true if the warmup URL probe can be fetched from the proxy with the
+  // specified properties.
+  bool ShouldFetchWarmupProbeURL(bool secure_proxy, bool is_core_proxy) const;
+
+  // Called when the warmup URL probe to a proxy with the specified properties
+  // has been initiated.
+  void OnWarmupFetchInitiated(bool secure_proxy, bool is_core_proxy);
+
  private:
   // Map from network IDs to network properties.
   typedef std::map<std::string, NetworkProperties> NetworkPropertiesContainer;
@@ -108,6 +116,22 @@
 
   std::unique_ptr<PrefManager> pref_manager_;
 
+  // Set to true if the fetch of the warmup URL was successful since the last
+  // connection change. The status is recorded separately for each combination
+  // of (is_secure_proxy) and (is_core_proxy).
+  bool has_warmup_url_succeded_secure_core_;
+  bool has_warmup_url_succeded_secure_non_core_;
+  bool has_warmup_url_succeded_insecure_core_;
+  bool has_warmup_url_succeded_insecure_non_core_;
+
+  // Count of warmup URL fetch attempts since the last connection change. The
+  // count is recorded separately for each combination of (is_secure_proxy) and
+  // (is_core_proxy).
+  size_t warmup_url_fetch_attempt_counts_secure_core_;
+  size_t warmup_url_fetch_attempt_counts_secure_non_core_;
+  size_t warmup_url_fetch_attempt_counts_insecure_core_;
+  size_t warmup_url_fetch_attempt_counts_insecure_non_core_;
+
   // Should be dereferenced only on the UI thread.
   base::WeakPtr<PrefManager> pref_manager_weak_ptr_;
 
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
index de2f85b..88c160c 100644
--- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
+++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
@@ -28,6 +28,7 @@
         url_request_context_getter,
     WarmupURLFetcherCallback callback)
     : url_request_context_getter_(url_request_context_getter),
+      is_fetch_in_flight_(false),
       callback_(callback) {
   DCHECK(url_request_context_getter_);
 }
@@ -63,6 +64,7 @@
   GetWarmupURLWithQueryParam(&warmup_url_with_query_params);
 
   fetcher_.reset();
+  is_fetch_in_flight_ = true;
 
   fetcher_ =
       net::URLFetcher::Create(warmup_url_with_query_params,
@@ -100,6 +102,7 @@
 
 void WarmupURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
   DCHECK_EQ(source, fetcher_.get());
+  is_fetch_in_flight_ = false;
   UMA_HISTOGRAM_BOOLEAN(
       "DataReductionProxy.WarmupURL.FetchSuccessful",
       source->GetStatus().status() == net::URLRequestStatus::SUCCESS);
@@ -146,4 +149,8 @@
   callback_.Run(source->ProxyServerUsed(), success_response);
 }
 
+bool WarmupURLFetcher::IsFetchInFlight() const {
+  return is_fetch_in_flight_;
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
index f470b32..86c06e48 100644
--- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
+++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
@@ -41,6 +41,9 @@
   // Creates and starts a URLFetcher that fetches the warmup URL.
   void FetchWarmupURL();
 
+  // Returns true if a warmup URL fetch is currently in-flight.
+  bool IsFetchInFlight() const;
+
  protected:
   // Sets |warmup_url_with_query_params| to the warmup URL. Attaches random
   // query params to the warmup URL.
@@ -54,6 +57,8 @@
   // The URLFetcher being used for fetching the warmup URL.
   std::unique_ptr<net::URLFetcher> fetcher_;
 
+  bool is_fetch_in_flight_;
+
   // Callback that should be executed when the fetching of the warmup URL is
   // completed.
   WarmupURLFetcherCallback callback_;
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
index 92590b0..b33aab4 100644
--- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
@@ -130,8 +130,11 @@
                                            std::move(test_request_context));
 
   WarmupURLFetcherTest warmup_url_fetcher(request_context_getter);
+  EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight());
   warmup_url_fetcher.FetchWarmupURL();
+  EXPECT_TRUE(warmup_url_fetcher.IsFetchInFlight());
   base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight());
 
   histogram_tester.ExpectUniqueSample(
       "DataReductionProxy.WarmupURL.FetchInitiated", 1, 1);
@@ -186,8 +189,11 @@
                                            std::move(test_request_context));
 
   WarmupURLFetcherTest warmup_url_fetcher(request_context_getter);
+  EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight());
   warmup_url_fetcher.FetchWarmupURL();
+  EXPECT_TRUE(warmup_url_fetcher.IsFetchInFlight());
   base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight());
 
   histogram_tester.ExpectUniqueSample(
       "DataReductionProxy.WarmupURL.FetchInitiated", 1, 1);
@@ -289,8 +295,11 @@
                                            std::move(test_request_context));
 
   WarmupURLFetcherTest warmup_url_fetcher(request_context_getter);
+  EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight());
   warmup_url_fetcher.FetchWarmupURL();
+  EXPECT_TRUE(warmup_url_fetcher.IsFetchInFlight());
   base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight());
 
   histogram_tester.ExpectUniqueSample(
       "DataReductionProxy.WarmupURL.FetchInitiated", 1, 1);
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
index b51164b0..49f2027b 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -147,7 +147,7 @@
                  .find(kDisabled) != 0;
 }
 
-bool FetchWarmupURLEnabled() {
+bool FetchWarmupProbeURLEnabled() {
   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kDisableDataReductionProxyWarmupURLFetch);
 }
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
index c1674f4..3c7413ef 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -135,7 +135,7 @@
 GURL GetSecureProxyCheckURL();
 
 // Returns true if fetching of the warmup URL is enabled.
-bool FetchWarmupURLEnabled();
+bool FetchWarmupProbeURLEnabled();
 
 // Returns the warmup URL.
 GURL GetWarmupURL();
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
index 93a8e6bb..187a7f6 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -251,7 +251,7 @@
       EXPECT_EQ(GURL("http://check.googlezip.net/generate_204"),
                 params::GetWarmupURL());
     }
-    EXPECT_TRUE(params::FetchWarmupURLEnabled());
+    EXPECT_TRUE(params::FetchWarmupProbeURLEnabled());
   }
 }
 
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index 9d9ce41..db3d0856 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -18,7 +18,7 @@
 
 // Use HTML based username detector.
 const base::Feature kEnableHtmlBasedUsernameDetector = {
-    "EnableHtmlBaseUsernameDetector", base::FEATURE_DISABLED_BY_DEFAULT};
+    "EnableHtmlBaseUsernameDetector", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enable additional elements in the form popup UI, which will allow the user to
 // view all saved passwords.
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
index 0712ad0..117f3baa 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
@@ -581,19 +581,7 @@
 
         private AccountManagerResult<Account[]> getAccountManagerResult() {
             try {
-                Account[] accounts = mDelegate.getAccountsSync();
-                if (accounts.length <= 1) return new AccountManagerResult<>(accounts);
-
-                ArrayList<Account> filteredAccounts = new ArrayList<>();
-                for (Account account : accounts) {
-                    if (hasFeatures(account, new String[] {FEATURE_IS_CHILD_ACCOUNT_KEY})) {
-                        filteredAccounts.add(account);
-                    }
-                }
-                // Don't filter if there are no child accounts
-                if (filteredAccounts.isEmpty()) return new AccountManagerResult<>(accounts);
-
-                return new AccountManagerResult<>(filteredAccounts.toArray(new Account[0]));
+                return new AccountManagerResult<>(mDelegate.getAccountsSync());
             } catch (AccountManagerDelegateException ex) {
                 return new AccountManagerResult<>(ex);
             }
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 92e81e29..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
@@ -5,7 +5,6 @@
 package org.chromium.components.signin.test;
 
 import android.accounts.Account;
-import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.UiThreadTestRule;
 
@@ -16,7 +15,6 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.components.signin.AccountManagerDelegateException;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ProfileDataSource;
 import org.chromium.components.signin.test.util.AccountHolder;
@@ -67,42 +65,6 @@
     }
 
     @Test
-    @MediumTest
-    public void testGetAccountsMultipleAccounts() throws AccountManagerDelegateException {
-        Assert.assertArrayEquals(new Account[] {}, mFacade.getGoogleAccounts());
-
-        Account account = addTestAccount("test@gmail.com");
-        Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts());
-
-        Account account2 = addTestAccount("test2@gmail.com");
-        Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts());
-
-        Account account3 = addTestAccount("test3@gmail.com");
-        Assert.assertArrayEquals(
-                new Account[] {account, account2, account3}, mFacade.getGoogleAccounts());
-
-        removeTestAccount(account2);
-        Assert.assertArrayEquals(new Account[] {account, account3}, mFacade.getGoogleAccounts());
-    }
-
-    @Test
-    @MediumTest
-    public void testGetAccountsChildAccountFiltering() throws AccountManagerDelegateException {
-        Account account = addTestAccount("test@gmail.com");
-        Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts());
-
-        Account childAccount = addChildTestAccount("child@gmail.com");
-        Assert.assertArrayEquals(new Account[] {childAccount}, mFacade.getGoogleAccounts());
-
-        Account account2 = addTestAccount("test2@gmail.com");
-        Assert.assertArrayEquals(new Account[] {childAccount}, mFacade.getGoogleAccounts());
-
-        // If child account is gone, non-child accounts should be exposed again
-        removeTestAccount(childAccount);
-        Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts());
-    }
-
-    @Test
     @SmallTest
     public void testProfileDataSource() throws Throwable {
         String accountName = "test@gmail.com";
@@ -130,19 +92,4 @@
         mDelegate.addAccountHolderBlocking(holder);
         return account;
     }
-
-    private Account addChildTestAccount(String accountName) {
-        Account account = AccountManagerFacade.createAccountFromName(accountName);
-        AccountHolder holder =
-                AccountHolder.builder(account)
-                        .alwaysAccept(true)
-                        .addFeature(AccountManagerFacade.FEATURE_IS_CHILD_ACCOUNT_KEY)
-                        .build();
-        mDelegate.addAccountHolderBlocking(holder);
-        return account;
-    }
-
-    private void removeTestAccount(Account account) {
-        mDelegate.removeAccountHolderBlocking(AccountHolder.builder(account).build());
-    }
 }
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
index 6ba0455..8a301678 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
+++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
@@ -27,7 +27,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.LinkedHashSet;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -110,7 +110,7 @@
     /** Use {@link FakeProfileDataSource}. */
     public static final int ENABLE_PROFILE_DATA_SOURCE = 1;
 
-    private final Set<AccountHolder> mAccounts = new LinkedHashSet<>();
+    private final Set<AccountHolder> mAccounts = new HashSet<>();
     private final ObserverList<AccountsChangeObserver> mObservers = new ObserverList<>();
     private boolean mRegisterObserversCalled;
     private FakeProfileDataSource mFakeProfileDataSource;
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index dcefd73..a1ec9be 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -4,10 +4,11 @@
 
 import("//build/buildflag_header.gni")
 import("//build/config/features.gni")
+import("//build/config/jumbo.gni")
 import("//components/sync/protocol/protocol_sources.gni")
 import("//testing/test.gni")
 
-static_library("sync") {
+jumbo_static_library("sync") {
   sources = [
     "base/attachment_id_proto.cc",
     "base/attachment_id_proto.h",
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index 3be2bdc..1f26f248 100644
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -112,6 +112,17 @@
 // in the expected parts of the NavigationEntry in each stage of navigation, and
 // that we don't kill the renderer on reload.  See https://crbug.com/522567.
 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, LoadDataWithBaseURL) {
+  // LoadDataWithBaseURL is never subject to --site-per-process policy today
+  // (this API is only used by Android WebView [where OOPIFs have not shipped
+  // yet] and WebView Guest tag [which always hosts guests inside a renderer
+  // without an origin lock]).  Therefore, skip the test in --site-per-process
+  // mode to avoid renderer kills which won't happen in practice as described
+  // above.
+  // TODO(lukasza): https://crbug.com/614463: Consider enabling this test
+  // once WebView guests support OOPIFs and/or origin locks.
+  if (AreAllSitesIsolatedForTesting())
+    return;
+
   const GURL base_url("http://baseurl");
   const GURL history_url("http://historyurl");
   const std::string data = "<html><body>foo</body></html>";
@@ -165,6 +176,17 @@
 // See https://crbug.com/612196.
 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
                        LoadDataWithBaseURLTitleAfterBack) {
+  // LoadDataWithBaseURL is never subject to --site-per-process policy today
+  // (this API is only used by Android WebView [where OOPIFs have not shipped
+  // yet] and WebView Guest tag [which always hosts guests inside a renderer
+  // without an origin lock]).  Therefore, skip the test in --site-per-process
+  // mode to avoid renderer kills which won't happen in practice as described
+  // above.
+  // TODO(lukasza): https://crbug.com/614463: Consider enabling this test
+  // once WebView guests support OOPIFs and/or origin locks.
+  if (AreAllSitesIsolatedForTesting())
+    return;
+
   const GURL base_url("http://baseurl");
   const GURL history_url(
       embedded_test_server()->GetURL("/navigation_controller/form.html"));
@@ -285,6 +307,17 @@
 
 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
                        NavigateFromLoadDataWithBaseURL) {
+  // LoadDataWithBaseURL is never subject to --site-per-process policy today
+  // (this API is only used by Android WebView [where OOPIFs have not shipped
+  // yet] and WebView Guest tag [which always hosts guests inside a renderer
+  // without an origin lock]).  Therefore, skip the test in --site-per-process
+  // mode to avoid renderer kills which won't happen in practice as described
+  // above.
+  // TODO(lukasza): https://crbug.com/614463: Consider enabling this test
+  // once WebView guests support OOPIFs and/or origin locks.
+  if (AreAllSitesIsolatedForTesting())
+    return;
+
   const GURL base_url("http://baseurl");
   const GURL history_url("http://historyurl");
   const std::string data = "<html><body></body></html>";
@@ -329,6 +362,17 @@
 
 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
                        FragmentNavigateFromLoadDataWithBaseURL) {
+  // LoadDataWithBaseURL is never subject to --site-per-process policy today
+  // (this API is only used by Android WebView [where OOPIFs have not shipped
+  // yet] and WebView Guest tag [which always hosts guests inside a renderer
+  // without an origin lock]).  Therefore, skip the test in --site-per-process
+  // mode to avoid renderer kills which won't happen in practice as described
+  // above.
+  // TODO(lukasza): https://crbug.com/614463: Consider enabling this test
+  // once WebView guests support OOPIFs and/or origin locks.
+  if (AreAllSitesIsolatedForTesting())
+    return;
+
   const GURL base_url("http://baseurl");
   const GURL history_url("http://historyurl");
   const std::string data =
@@ -697,6 +741,17 @@
 // crash.  See https://crbug.com/768575.
 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
                        NavigateBackInChildOfLoadDataWithBaseURL) {
+  // LoadDataWithBaseURL is never subject to --site-per-process policy today
+  // (this API is only used by Android WebView [where OOPIFs have not shipped
+  // yet] and WebView Guest tag [which always hosts guests inside a renderer
+  // without an origin lock]).  Therefore, skip the test in --site-per-process
+  // mode to avoid renderer kills which won't happen in practice as described
+  // above.
+  // TODO(lukasza): https://crbug.com/614463: Consider enabling this test
+  // once WebView guests support OOPIFs and/or origin locks.
+  if (AreAllSitesIsolatedForTesting())
+    return;
+
   GURL iframe_url(embedded_test_server()->GetURL(
       "/navigation_controller/page_with_links.html"));
 
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index 210f076..b49d022 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -245,6 +245,11 @@
     return navigation_request->common_params().url;
   }
 
+  TestRenderFrameHost* GetNavigatingRenderFrameHost() {
+    return AreAllSitesIsolatedForTesting() ? contents()->GetPendingMainFrame()
+                                           : contents()->GetMainFrame();
+  }
+
  protected:
   GURL navigated_url_;
   size_t navigation_entry_committed_counter_ = 0;
@@ -975,9 +980,7 @@
 
   // ... Do a new navigation.
   const GURL kNewURL("http://see");
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(kNewURL, true);
-  main_test_rfh()->PrepareForCommit();
-  contents()->GetMainFrame()->SendNavigate(0, true, kNewURL);
+  NavigationSimulator::NavigateAndCommitFromDocument(kNewURL, main_test_rfh());
 
   // There should no longer be any pending entry, and the third navigation we
   // just made should be committed.
@@ -1435,7 +1438,8 @@
   EXPECT_EQ(0U, navigation_list_pruned_counter_);
 
   main_test_rfh()->PrepareForCommitWithServerRedirect(url2);
-  main_test_rfh()->SendNavigate(entry_id, true, url2);
+  TestRenderFrameHost* navigating_rfh = GetNavigatingRenderFrameHost();
+  navigating_rfh->SendNavigate(entry_id, true, url2);
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -1631,7 +1635,7 @@
 
   // Normal navigation will preserve redirects in the committed entry.
   main_test_rfh()->PrepareForCommitWithServerRedirect(url2);
-  main_test_rfh()->SendNavigateWithModificationCallback(entry_id, true, url1,
+  main_test_rfh()->SendNavigateWithModificationCallback(entry_id, true, url2,
                                                         set_redirects_callback);
   NavigationEntryImpl* committed_entry = controller.GetLastCommittedEntry();
   ASSERT_EQ(1U, committed_entry->GetRedirectChain().size());
@@ -1717,11 +1721,9 @@
   EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(),
             controller.GetEntryAtIndex(0)->GetTimestamp());
 
-  TestRenderFrameHost* navigating_rfh = AreAllSitesIsolatedForTesting()
-                                            ? contents()->GetPendingMainFrame()
-                                            : contents()->GetMainFrame();
+  TestRenderFrameHost* navigating_rfh = GetNavigatingRenderFrameHost();
   navigating_rfh->PrepareForCommit();
-  navigating_rfh->SendNavigate(entry_id, false, url2);
+  navigating_rfh->SendNavigate(entry_id, false, url1);
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -1836,25 +1838,16 @@
   const GURL url1("http://foo1");
   const GURL url2("http://foo2");
 
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(url1, true);
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(0, true, url1);
-  NavigationEntry* entry1 = controller.GetLastCommittedEntry();
+  NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(url2, true);
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(0, true, url2);
+  NavigationSimulator::NavigateAndCommitFromDocument(url2, main_test_rfh());
   NavigationEntry* entry2 = controller.GetLastCommittedEntry();
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
-  controller.GoBack();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigateWithTransition(
-      entry1->GetUniqueID(), false, url1,
-      controller.GetPendingEntry()->GetTransitionType());
+  NavigationSimulator::GoBack(contents());
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -1878,8 +1871,9 @@
   EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(),
             controller.GetEntryAtIndex(1)->GetTimestamp());
 
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigateWithTransition(
+  TestRenderFrameHost* navigating_rfh = GetNavigatingRenderFrameHost();
+  navigating_rfh->PrepareForCommit();
+  navigating_rfh->SendNavigateWithTransition(
       entry2->GetUniqueID(), false, url2,
       controller.GetPendingEntry()->GetTransitionType());
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
@@ -1911,24 +1905,16 @@
   const GURL url2("http://foo2");
   const GURL url3("http://foo3");
 
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(url1, true);
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(0, true, url1);
+  NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
-  NavigationEntry* entry1 = controller.GetLastCommittedEntry();
   navigation_entry_committed_counter_ = 0;
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(url2, true);
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(0, true, url2);
+
+  NavigationSimulator::NavigateAndCommitFromDocument(url2, main_test_rfh());
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   NavigationEntry* entry2 = controller.GetLastCommittedEntry();
   navigation_entry_committed_counter_ = 0;
 
-  controller.GoBack();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigateWithTransition(
-      entry1->GetUniqueID(), false, url1,
-      controller.GetPendingEntry()->GetTransitionType());
+  NavigationSimulator::GoBack(contents());
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
@@ -1944,8 +1930,9 @@
   EXPECT_TRUE(controller.CanGoBack());
   EXPECT_FALSE(controller.CanGoForward());
 
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry2->GetUniqueID(), true, url3);
+  GetNavigatingRenderFrameHost()->PrepareForCommitWithServerRedirect(url3);
+  GetNavigatingRenderFrameHost()->SendNavigate(entry2->GetUniqueID(), true,
+                                               url3);
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
   EXPECT_EQ(1U, navigation_list_pruned_counter_);
@@ -3066,23 +3053,18 @@
   NavigationControllerImpl& controller = controller_impl();
   // First navigate somewhere normal.
   const GURL url1("http://foo");
-  controller.LoadURL(
-      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
-  int entry_id = controller.GetPendingEntry()->GetUniqueID();
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url1);
+  NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
 
   // Now navigate somewhere with an interstitial.
   const GURL url2("http://bar");
-  controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_TYPED,
-                     std::string());
-  entry_id = controller.GetPendingEntry()->GetUniqueID();
+  std::unique_ptr<NavigationSimulator> simulator =
+      NavigationSimulator::CreateBrowserInitiated(url2, contents());
+  simulator->Start();
   controller.GetPendingEntry()->set_page_type(PAGE_TYPE_INTERSTITIAL);
 
   // At this point the interstitial will be displayed and the load will still
   // be pending. If the user continues, the load will commit.
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigate(entry_id, true, url2);
+  simulator->Commit();
 
   // The page should be a normal page again.
   EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
@@ -3455,14 +3437,15 @@
 
   // If the user clicks another link, we should replace the pending entry.
   main_test_rfh()->SendRendererInitiatedNavigationRequest(url2, false);
-  main_test_rfh()->PrepareForCommit();
-  navigator->DidStartProvisionalLoad(main_test_rfh(), url2, std::vector<GURL>(),
+  TestRenderFrameHost* navigating_rfh = GetNavigatingRenderFrameHost();
+  navigating_rfh->PrepareForCommit();
+  navigator->DidStartProvisionalLoad(navigating_rfh, url2, std::vector<GURL>(),
                                      base::TimeTicks::Now());
   EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
   EXPECT_EQ(url2, controller.GetPendingEntry()->GetVirtualURL());
 
   // Once it commits, the URL and virtual URL should reflect the actual page.
-  main_test_rfh()->SendNavigate(0, true, url2);
+  navigating_rfh->SendNavigate(0, true, url2);
   EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
   EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetVirtualURL());
 
@@ -3824,7 +3807,8 @@
   // Don't honor allow_universal_access_from_file_urls if actual URL is
   // not file scheme.
   const GURL url("http://www.google.com/home.html");
-  main_test_rfh()->NavigateAndCommitRendererInitiated(true, url);
+  NavigationSimulator::NavigateAndCommitFromDocument(url, main_test_rfh());
+  rph = main_test_rfh()->GetProcess();  // Navigation could swap the process.
   EXPECT_FALSE(controller.IsURLSameDocumentNavigation(
       different_origin_url, url::Origin::Create(different_origin_url), true,
       main_test_rfh()));
@@ -4737,13 +4721,11 @@
   favicon_status.valid = true;
   EXPECT_FALSE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image));
 
-  main_test_rfh()->SendRendererInitiatedNavigationRequest(kPageWithoutFavicon,
-                                                          false);
-  main_test_rfh()->PrepareForCommit();
-  main_test_rfh()->SendNavigateWithTransition(
-      0,      // nav_entry_id
-      false,  // no new entry
-      kPageWithoutFavicon, ui::PAGE_TRANSITION_CLIENT_REDIRECT);
+  std::unique_ptr<NavigationSimulator> simulator =
+      NavigationSimulator::CreateRendererInitiated(kPageWithoutFavicon,
+                                                   main_test_rfh());
+  simulator->SetTransition(ui::PAGE_TRANSITION_CLIENT_REDIRECT);
+  simulator->Commit();
   EXPECT_EQ(1U, navigation_entry_committed_counter_);
   navigation_entry_committed_counter_ = 0;
 
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index ceddb61..4e24794 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -3217,7 +3217,9 @@
   }
 
   // It is safe to commit into a unique origin, regardless of the URL, as it is
-  // restricted from accessing other origins.
+  // restricted from accessing other origins.  Note that all error pages commit
+  // as a unique origin - this helps avoid renderer kills when
+  // ERR_BLOCKED_BY_CLIENT commits in an unexpected renderer process.
   if (origin.unique())
     return true;
 
@@ -3230,6 +3232,32 @@
   // conversion to GURL.
   GURL origin_url = origin.GetPhysicalOrigin().GetURL();
 
+  // Check the origin against the (potential) origin lock of the current
+  // process.
+  // TODO(lukasza): https://crbug.com/770239: Expand the check to cover other
+  // verifications from RenderProcessHostImpl::IsSuitableHost (e.g. WebUI
+  // bindings, extension process privilege level, etc.).  Avoid duplicating
+  // the code here and in IsSuitableHost.
+  BrowserContext* browser_context = GetSiteInstance()->GetBrowserContext();
+  GURL site_url = SiteInstance::GetSiteForURL(browser_context, origin_url);
+  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+  switch (policy->CheckOriginLock(GetProcess()->GetID(), site_url)) {
+    case ChildProcessSecurityPolicyImpl::CheckOriginLockResult::HAS_EQUAL_LOCK:
+      break;
+    case ChildProcessSecurityPolicyImpl::CheckOriginLockResult::HAS_WRONG_LOCK:
+      // If the process is locked to an origin, disallow reusing this process
+      // for a different origin.
+      return false;
+    case ChildProcessSecurityPolicyImpl::CheckOriginLockResult::NO_LOCK:
+      // TODO(lukasza): https://crbug.com/794315: Return false if
+      // ShouldLockToOrigin(site_url) returns true, similarily to how this is
+      // done by RenderProcessHostImpl::IsSuitableHost.  We don't do this here,
+      // because this breaks hosted apps (which can return
+      // !ShouldLockToOrigin(full_url_with_path, but here they would return
+      // ShouldLockToOrigin(origin_only_part_of_url)).
+      break;
+  }
+
   // Verify that the origin is allowed to commit in this process.
   // Note: This also handles non-standard cases for |url|, such as
   // about:blank, data, and blob URLs.
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index a1673d3..0e6c69c 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -1242,15 +1242,21 @@
     return SiteInstanceDescriptor(render_frame_host_->GetSiteInstance());
 
   // Shortcut some common cases for reusing an existing frame's SiteInstance.
-  // Looking at the main frame and openers is required for TDI mode. It also
-  // helps with hosted apps, allowing same-site, non-app subframes to be kept
-  // inside the hosted app process.
+  // There are several reasons for this:
+  // - looking at the main frame and openers is required for TDI mode.
+  // - with hosted apps, this allows same-site, non-app subframes to be kept
+  //   inside the hosted app process.
+  // - this avoids putting same-site iframes into different processes after
+  //   navigations from isolated origins.  This matters for some OAuth flows;
+  //   see https://crbug.com/796912.
   //
-  // TODO(alexmos): Normally, we'd find these SiteInstances later, as part of
-  // creating a new related SiteInstance from
-  // BrowsingInstance::GetSiteInstanceForURL(), but the lookup there does not
-  // properly deal with hosted apps.  Once that's refactored to skip effective
-  // URLs when necessary, this can be removed.  See https://crbug.com/718516.
+  // TODO(alexmos): Ideally, the right SiteInstance for these cases should be
+  // found later, as part of creating a new related SiteInstance from
+  // BrowsingInstance::GetSiteInstanceForURL().  However, the lookup there (1)
+  // does not properly deal with hosted apps (see https://crbug.com/718516),
+  // and (2) does not yet deal with cases where a SiteInstance is shared by
+  // several sites that don't require a dedicated process (see
+  // https://crbug.com/787576).
   if (!frame_tree_node_->IsMainFrame()) {
     RenderFrameHostImpl* main_frame =
         frame_tree_node_->frame_tree()->root()->current_frame_host();
diff --git a/content/browser/isolated_origin_browsertest.cc b/content/browser/isolated_origin_browsertest.cc
index bad8c5f3..acb1b5b 100644
--- a/content/browser/isolated_origin_browsertest.cc
+++ b/content/browser/isolated_origin_browsertest.cc
@@ -355,6 +355,120 @@
   EXPECT_NE(third_shell_instance->GetProcess(), isolated_process);
 }
 
+// Check that when a cross-site, non-isolated-origin iframe opens a popup,
+// navigates it to an isolated origin, and then the popup navigates back to its
+// opener iframe's site, the popup and the opener iframe end up in the same
+// process and can script each other.  See https://crbug.com/796912.
+IN_PROC_BROWSER_TEST_F(IsolatedOriginTest,
+                       PopupNavigatesToIsolatedOriginAndBack) {
+  // Start on a page with same-site iframe.
+  GURL foo_url(
+      embedded_test_server()->GetURL("www.foo.com", "/page_with_iframe.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
+  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+  FrameTreeNode* child = root->child_at(0);
+
+  // Navigate iframe cross-site, but not to an isolated origin.  This should
+  // stay in the main frame's SiteInstance, unless we're in --site-per-process
+  // mode.  (Note that the bug for which this test is written is exclusive to
+  // --isolate-origins and does not happen with --site-per-process.)
+  GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
+  NavigateIframeToURL(web_contents(), "test_iframe", bar_url);
+  if (AreAllSitesIsolatedForTesting()) {
+    EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  } else {
+    EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
+              child->current_frame_host()->GetSiteInstance());
+  }
+
+  // Open a blank popup from the iframe.
+  ShellAddedObserver new_shell_observer;
+  EXPECT_TRUE(ExecuteScript(child, "window.w = window.open();"));
+  Shell* new_shell = new_shell_observer.GetShell();
+
+  // Have the opener iframe navigate the popup to an isolated origin.
+  GURL isolated_url(
+      embedded_test_server()->GetURL("isolated.foo.com", "/title1.html"));
+  {
+    TestNavigationManager manager(new_shell->web_contents(), isolated_url);
+    EXPECT_TRUE(ExecuteScript(
+        child, "window.w.location.href = '" + isolated_url.spec() + "';"));
+    manager.WaitForNavigationFinished();
+  }
+
+  // Simulate the isolated origin in the popup navigating back to bar.com.
+  GURL bar_url2(embedded_test_server()->GetURL("bar.com", "/title2.html"));
+  {
+    TestNavigationManager manager(new_shell->web_contents(), bar_url2);
+    EXPECT_TRUE(
+        ExecuteScript(new_shell, "location.href = '" + bar_url2.spec() + "';"));
+    manager.WaitForNavigationFinished();
+  }
+
+  // Check that the popup ended up in the same SiteInstance as its same-site
+  // opener iframe.
+  EXPECT_EQ(new_shell->web_contents()->GetMainFrame()->GetSiteInstance(),
+            child->current_frame_host()->GetSiteInstance());
+
+  // Check that the opener iframe can script the popup.
+  std::string popup_location;
+  EXPECT_TRUE(ExecuteScriptAndExtractString(
+      child, "domAutomationController.send(window.w.location.href);",
+      &popup_location));
+  EXPECT_EQ(bar_url2.spec(), popup_location);
+}
+
+// Check that with an ABA hierarchy, where B is an isolated origin, the root
+// and grandchild frames end up in the same process and can script each other.
+// See https://crbug.com/796912.
+IN_PROC_BROWSER_TEST_F(IsolatedOriginTest,
+                       IsolatedOriginSubframeCreatesGrandchildInRootSite) {
+  // Start at foo.com and do a cross-site, renderer-initiated navigation to
+  // bar.com, which should stay in the same SiteInstance (outside of
+  // --site-per-process mode).  This sets up the main frame such that its
+  // SiteInstance's site URL does not match its actual origin - a prerequisite
+  // for https://crbug.com/796912 to happen.
+  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
+  GURL bar_url(
+      embedded_test_server()->GetURL("bar.com", "/page_with_iframe.html"));
+  TestNavigationObserver observer(web_contents());
+  EXPECT_TRUE(
+      ExecuteScript(shell(), "location.href = '" + bar_url.spec() + "';"));
+  observer.Wait();
+
+  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+  FrameTreeNode* child = root->child_at(0);
+
+  // Navigate bar.com's subframe to an isolated origin with its own subframe.
+  GURL isolated_url(embedded_test_server()->GetURL("isolated.foo.com",
+                                                   "/page_with_iframe.html"));
+  NavigateIframeToURL(web_contents(), "test_iframe", isolated_url);
+  EXPECT_EQ(isolated_url, child->current_url());
+  FrameTreeNode* grandchild = child->child_at(0);
+
+  // Navigate the isolated origin's subframe back to bar.com, completing the
+  // ABA hierarchy.
+  NavigateFrameToURL(grandchild, bar_url);
+
+  // The root and grandchild should be in the same SiteInstance, and the
+  // middle child should be in a different SiteInstance.
+  EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
+            child->current_frame_host()->GetSiteInstance());
+  EXPECT_NE(child->current_frame_host()->GetSiteInstance(),
+            grandchild->current_frame_host()->GetSiteInstance());
+  EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
+            grandchild->current_frame_host()->GetSiteInstance());
+
+  // Check that the root frame can script the same-site grandchild frame.
+  std::string location;
+  EXPECT_TRUE(ExecuteScriptAndExtractString(
+      root, "domAutomationController.send(frames[0][0].location.href);",
+      &location));
+  EXPECT_EQ(bar_url.spec(), location);
+}
+
 // Check that isolated origins can access cookies.  This requires cookie checks
 // on the IO thread to be aware of isolated origins.
 IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, Cookies) {
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 74bcb61..aba2a76 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1321,7 +1321,6 @@
   return AddStandardHandlers(request, request_data.resource_type,
                              resource_context, request_data.fetch_request_mode,
                              request_data.fetch_request_context_type,
-                             request_data.fetch_mixed_content_context_type,
                              requester_info->appcache_service(), child_id,
                              route_id, std::move(handler), nullptr, nullptr);
 }
@@ -1347,7 +1346,6 @@
     ResourceContext* resource_context,
     network::mojom::FetchRequestMode fetch_request_mode,
     RequestContextType fetch_request_context_type,
-    blink::WebMixedContentContextType fetch_mixed_content_context_type,
     AppCacheService* appcache_service,
     int child_id,
     int route_id,
@@ -2013,7 +2011,6 @@
       new_request.get(), resource_type, resource_context,
       network::mojom::FetchRequestMode::kNoCORS,
       info.begin_params->request_context_type,
-      info.begin_params->mixed_content_context_type,
       appcache_handle_core ? appcache_handle_core->GetAppCacheService()
                            : nullptr,
       -1,  // child_id
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index d92a4e3..391e7667 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -41,7 +41,6 @@
 #include "net/base/load_states.h"
 #include "net/base/request_priority.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/WebKit/public/platform/WebMixedContentContextType.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -615,7 +614,6 @@
       ResourceContext* resource_context,
       network::mojom::FetchRequestMode fetch_request_mode,
       RequestContextType fetch_request_context_type,
-      blink::WebMixedContentContextType fetch_mixed_content_context_type,
       AppCacheService* appcache_service,
       int child_id,
       int route_id,
diff --git a/content/browser/message_port_provider_browsertest.cc b/content/browser/message_port_provider_browsertest.cc
index 3563529..5f8892193 100644
--- a/content/browser/message_port_provider_browsertest.cc
+++ b/content/browser/message_port_provider_browsertest.cc
@@ -23,25 +23,34 @@
 
 // Verify that messages can be posted to main frame.
 IN_PROC_BROWSER_TEST_F(MessagePortProviderBrowserTest, PostMessage) {
-  const std::string data =
-      "<!DOCTYPE html><html><body>"
-      "    <script type=\"text/javascript\">"
-      "        onmessage = function (e) { document.title = e.data; }"
-      "   </script>"
-      "</body></html>";
-  const base::string16 target_origin(base::UTF8ToUTF16("http://baseurl"));
-  const GURL base_url(target_origin);
-  const GURL history_url;
-  // Load data. Blocks until it is done.
-  content::LoadDataWithBaseURL(shell(), history_url, data, base_url);
-  const base::string16 source_origin(base::UTF8ToUTF16("source"));
-  const base::string16 message(base::UTF8ToUTF16("success"));
-  content::TitleWatcher title_watcher(shell()->web_contents(), message);
-  MessagePortProvider::PostMessageToFrame(shell()->web_contents(),
-                                          source_origin,
-                                          target_origin,
-                                          message);
-  EXPECT_EQ(message, title_watcher.WaitAndGetTitle());
+  // Listen for a message.
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+  EXPECT_TRUE(ExecuteScript(shell(), R"(
+      onmessage = function(e) {
+          domAutomationController.send(e.origin + ':' + e.data);
+      } )"));
+
+  // Post a message.
+  const std::string target_origin(url.GetOrigin().spec());
+  const std::string source_origin("https://source.origin.com");
+  const std::string message("success");
+  DOMMessageQueue msg_queue;
+  MessagePortProvider::PostMessageToFrame(
+      shell()->web_contents(), base::UTF8ToUTF16(source_origin),
+      base::UTF8ToUTF16(target_origin), base::UTF8ToUTF16(message));
+
+  // Verify that the message was received (and had the expected payload).
+  std::string expected_test_reply;
+  expected_test_reply += '"';
+  expected_test_reply += source_origin;
+  expected_test_reply += ':';
+  expected_test_reply += message;
+  expected_test_reply += '"';
+  std::string actual_test_reply;
+  EXPECT_TRUE(msg_queue.WaitForMessage(&actual_test_reply));
+  EXPECT_EQ(expected_test_reply, actual_test_reply);
 }
 
 }  // namespace content
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index f09d54c..2df31a823 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -535,9 +535,7 @@
 
   // Setup an URL which will never commit, allowing this test to send its own,
   // malformed, commit message.
-  GURL url(embedded_test_server()->GetURL("/title2.html"));
-  NavigationStallDelegate stall_delegate(url);
-  ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+  GURL url(embedded_test_server()->GetURL("/hung"));
 
   // Use LoadURL, as the test shouldn't wait for navigation commit.
   NavigationController& controller = shell()->web_contents()->GetController();
@@ -564,8 +562,10 @@
   params->page_state = PageState::CreateFromURL(url);
   params->origin = url::Origin::Create(GURL("http://bar.com/"));
 
+  service_manager::mojom::InterfaceProviderPtr interface_provider;
   static_cast<mojom::FrameHost*>(root->current_frame_host())
-      ->DidCommitProvisionalLoad(std::move(params), nullptr);
+      ->DidCommitProvisionalLoad(std::move(params),
+                                 mojo::MakeRequest(&interface_provider));
 
   // When the IPC message is received and validation fails, the process is
   // terminated. However, the notification for that should be processed in a
@@ -575,7 +575,6 @@
 
   exit_observer.Wait();
   EXPECT_FALSE(exit_observer.did_exit_normally());
-  ResourceDispatcherHost::Get()->SetDelegate(nullptr);
 }
 
 namespace {
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index d4124b2..b3c74d8 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -576,11 +576,11 @@
       << "Event of type " << static_cast<int>(event_type)
       << " can only be dispatched to an active worker: " << status();
 
-  auto request =
-      std::make_unique<PendingRequest>(std::move(error_callback), clock_->Now(),
-                                       tick_clock_->NowTicks(), event_type);
-  PendingRequest* request_rawptr = request.get();
-  int request_id = pending_requests_.Add(std::move(request));
+  auto request = std::make_unique<InflightRequest>(
+      std::move(error_callback), clock_->Now(), tick_clock_->NowTicks(),
+      event_type);
+  InflightRequest* request_rawptr = request.get();
+  int request_id = inflight_requests_.Add(std::move(request));
   TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", "ServiceWorkerVersion::Request",
                            request_rawptr, "Request id", request_id,
                            "Event type",
@@ -588,7 +588,7 @@
 
   base::TimeTicks expiration_time = tick_clock_->NowTicks() + timeout;
   bool is_inserted = false;
-  std::set<RequestInfo>::iterator iter;
+  std::set<InflightRequestTimeoutInfo>::iterator iter;
   std::tie(iter, is_inserted) = request_timeouts_.emplace(
       request_id, event_type, expiration_time, timeout_behavior);
   DCHECK(is_inserted);
@@ -626,7 +626,7 @@
 bool ServiceWorkerVersion::FinishRequest(int request_id,
                                          bool was_handled,
                                          base::Time dispatch_event_time) {
-  PendingRequest* request = pending_requests_.Lookup(request_id);
+  InflightRequest* request = inflight_requests_.Lookup(request_id);
   if (!request)
     return false;
   if (event_recorder_)
@@ -642,7 +642,7 @@
   TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
                          request, "Handled", was_handled);
   request_timeouts_.erase(request->timeout_iter);
-  pending_requests_.Remove(request_id);
+  inflight_requests_.Remove(request_id);
 
   if (!HasWorkInBrowser())
     OnNoWorkInBrowser();
@@ -673,7 +673,7 @@
 ServiceWorkerVersion::SimpleEventCallback
 ServiceWorkerVersion::CreateSimpleEventCallback(int request_id) {
   // The weak reference to |this| is safe because storage of the callbacks, the
-  // pending responses of the ServiceWorkerEventDispatcher, is owned by |this|.
+  // inflight responses of the ServiceWorkerEventDispatcher, is owned by |this|.
   return base::Bind(&ServiceWorkerVersion::OnSimpleEventFinished,
                     base::Unretained(this), request_id);
 }
@@ -720,13 +720,13 @@
 }
 
 void ServiceWorkerVersion::OnStreamResponseStarted() {
-  CHECK_LT(pending_stream_response_count_, std::numeric_limits<int>::max());
-  pending_stream_response_count_++;
+  CHECK_LT(inflight_stream_response_count_, std::numeric_limits<int>::max());
+  inflight_stream_response_count_++;
 }
 
 void ServiceWorkerVersion::OnStreamResponseFinished() {
-  DCHECK_GT(pending_stream_response_count_, 0);
-  pending_stream_response_count_--;
+  DCHECK_GT(inflight_stream_response_count_, 0);
+  inflight_stream_response_count_--;
   if (!HasWorkInBrowser())
     OnNoWorkInBrowser();
 }
@@ -865,7 +865,7 @@
   return main_script_http_info_.get();
 }
 
-ServiceWorkerVersion::RequestInfo::RequestInfo(
+ServiceWorkerVersion::InflightRequestTimeoutInfo::InflightRequestTimeoutInfo(
     int id,
     ServiceWorkerMetrics::EventType event_type,
     const base::TimeTicks& expiration,
@@ -875,17 +875,17 @@
       expiration(expiration),
       timeout_behavior(timeout_behavior) {}
 
-ServiceWorkerVersion::RequestInfo::~RequestInfo() {
-}
+ServiceWorkerVersion::InflightRequestTimeoutInfo::
+    ~InflightRequestTimeoutInfo() {}
 
-bool ServiceWorkerVersion::RequestInfo::operator<(
-    const RequestInfo& other) const {
+bool ServiceWorkerVersion::InflightRequestTimeoutInfo::operator<(
+    const InflightRequestTimeoutInfo& other) const {
   if (expiration == other.expiration)
     return id < other.id;
   return expiration < other.expiration;
 }
 
-ServiceWorkerVersion::PendingRequest::PendingRequest(
+ServiceWorkerVersion::InflightRequest::InflightRequest(
     StatusCallback callback,
     base::Time time,
     const base::TimeTicks& time_ticks,
@@ -895,7 +895,7 @@
       start_time_ticks(time_ticks),
       event_type(event_type) {}
 
-ServiceWorkerVersion::PendingRequest::~PendingRequest() {}
+ServiceWorkerVersion::InflightRequest::~InflightRequest() {}
 
 void ServiceWorkerVersion::OnThreadStarted() {
   DCHECK_EQ(EmbeddedWorkerStatus::STARTING, running_status());
@@ -1168,7 +1168,7 @@
     int request_id,
     blink::mojom::ServiceWorkerEventStatus status,
     base::Time dispatch_event_time) {
-  PendingRequest* request = pending_requests_.Lookup(request_id);
+  InflightRequest* request = inflight_requests_.Lookup(request_id);
   // |request| will be null when the request has been timed out.
   if (!request)
     return;
@@ -1504,7 +1504,7 @@
 
 void ServiceWorkerVersion::StartWorkerInternal() {
   DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status());
-  DCHECK(pending_requests_.IsEmpty());
+  DCHECK(inflight_requests_.IsEmpty());
   DCHECK(request_timeouts_.empty());
   DCHECK(start_worker_first_purpose_);
 
@@ -1521,9 +1521,9 @@
   StartTimeoutTimer();
   idle_timer_fired_in_renderer_ = false;
 
-  std::unique_ptr<ServiceWorkerProviderHost> pending_provider_host =
+  std::unique_ptr<ServiceWorkerProviderHost> provider_host =
       ServiceWorkerProviderHost::PreCreateForController(context());
-  provider_host_ = pending_provider_host->AsWeakPtr();
+  provider_host_ = provider_host->AsWeakPtr();
 
   auto params = mojom::EmbeddedWorkerStartParams::New();
   params->service_worker_version_id = version_id_;
@@ -1556,7 +1556,7 @@
       // Unretained is used here because the callback will be owned by
       // |embedded_worker_| whose owner is |this|.
       base::BindOnce(&CompleteProviderHostPreparation, base::Unretained(this),
-                     std::move(pending_provider_host), context()),
+                     std::move(provider_host), context()),
       mojo::MakeRequest(&event_dispatcher_),
       mojo::MakeRequest(&controller_ptr_), std::move(installed_scripts_info),
       std::move(service_worker_host_ptr_info),
@@ -1673,10 +1673,10 @@
   bool stop_for_timeout = false;
   auto timeout_iter = request_timeouts_.begin();
   while (timeout_iter != request_timeouts_.end()) {
-    const RequestInfo& info = *timeout_iter;
+    const InflightRequestTimeoutInfo& info = *timeout_iter;
     if (!RequestExpired(info.expiration))
       break;
-    if (MaybeTimeOutRequest(info)) {
+    if (MaybeTimeoutRequest(info)) {
       stop_for_timeout =
           stop_for_timeout || info.timeout_behavior == KILL_ON_TIMEOUT;
       ServiceWorkerMetrics::RecordEventTimeout(info.event_type);
@@ -1764,7 +1764,7 @@
 }
 
 bool ServiceWorkerVersion::HasWorkInBrowser() const {
-  return !pending_requests_.IsEmpty() || pending_stream_response_count_ > 0 ||
+  return !inflight_requests_.IsEmpty() || inflight_stream_response_count_ > 0 ||
          !start_callbacks_.empty();
 }
 
@@ -1823,28 +1823,29 @@
                             EmbeddedWorkerInstance::STARTING_PHASE_MAX_VALUE);
 }
 
-bool ServiceWorkerVersion::MaybeTimeOutRequest(const RequestInfo& info) {
-  PendingRequest* request = pending_requests_.Lookup(info.id);
+bool ServiceWorkerVersion::MaybeTimeoutRequest(
+    const InflightRequestTimeoutInfo& info) {
+  InflightRequest* request = inflight_requests_.Lookup(info.id);
   if (!request)
     return false;
 
   TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
                          request, "Error", "Timeout");
   std::move(request->error_callback).Run(SERVICE_WORKER_ERROR_TIMEOUT);
-  pending_requests_.Remove(info.id);
+  inflight_requests_.Remove(info.id);
   return true;
 }
 
 void ServiceWorkerVersion::SetAllRequestExpirations(
     const base::TimeTicks& expiration) {
-  std::set<RequestInfo> new_timeouts;
+  std::set<InflightRequestTimeoutInfo> new_timeouts;
   for (const auto& info : request_timeouts_) {
     bool is_inserted = false;
-    std::set<RequestInfo>::iterator iter;
+    std::set<InflightRequestTimeoutInfo>::iterator iter;
     std::tie(iter, is_inserted) = new_timeouts.emplace(
         info.id, info.event_type, expiration, info.timeout_behavior);
     DCHECK(is_inserted);
-    PendingRequest* request = pending_requests_.Lookup(info.id);
+    InflightRequest* request = inflight_requests_.Lookup(info.id);
     DCHECK(request);
     request->timeout_iter = iter;
   }
@@ -1960,8 +1961,8 @@
   // Let all message callbacks fail (this will also fire and clear all
   // callbacks for events).
   // TODO(kinuko): Consider if we want to add queue+resend mechanism here.
-  base::IDMap<std::unique_ptr<PendingRequest>>::iterator iter(
-      &pending_requests_);
+  base::IDMap<std::unique_ptr<InflightRequest>>::iterator iter(
+      &inflight_requests_);
   while (!iter.IsAtEnd()) {
     TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
                            iter.GetCurrentValue(), "Error", "Worker Stopped");
@@ -1969,7 +1970,7 @@
         .Run(SERVICE_WORKER_ERROR_FAILED);
     iter.Advance();
   }
-  pending_requests_.Clear();
+  inflight_requests_.Clear();
   request_timeouts_.clear();
   external_request_uuid_to_request_id_.clear();
   event_dispatcher_.reset();
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 06e61a5..bdb230c 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -304,7 +304,7 @@
   bool StartExternalRequest(const std::string& request_uuid);
 
   // Informs ServiceWorkerVersion that an event has finished being dispatched.
-  // Returns false if no pending requests with the provided id exist, for
+  // Returns false if no inflight requests with the provided id exist, for
   // example if the request has already timed out.
   // Pass the result of the event to |was_handled|, which is used to record
   // statistics based on the event status.
@@ -436,7 +436,7 @@
   void SetClockForTesting(base::Clock* clock);
 
   // Non-S13nServiceWorker: returns true if the service worker has work to do:
-  // it has pending requests, in-progress streaming URLRequestJobs, or pending
+  // it has inflight requests, in-progress streaming URLRequestJobs, or pending
   // start callbacks.
   //
   // S13nServiceWorker: returns true if the worker has work on the browser.
@@ -540,14 +540,15 @@
 
   class PingController;
 
-  struct RequestInfo {
-    RequestInfo(int id,
-                ServiceWorkerMetrics::EventType event_type,
-                const base::TimeTicks& expiration,
-                TimeoutBehavior timeout_behavior);
-    ~RequestInfo();
+  // Contains timeout info for InflightRequest.
+  struct InflightRequestTimeoutInfo {
+    InflightRequestTimeoutInfo(int id,
+                               ServiceWorkerMetrics::EventType event_type,
+                               const base::TimeTicks& expiration,
+                               TimeoutBehavior timeout_behavior);
+    ~InflightRequestTimeoutInfo();
     // Compares |expiration|, or |id| if |expiration| is the same.
-    bool operator<(const RequestInfo& other) const;
+    bool operator<(const InflightRequestTimeoutInfo& other) const;
 
     const int id;
     const ServiceWorkerMetrics::EventType event_type;
@@ -555,19 +556,21 @@
     const TimeoutBehavior timeout_behavior;
   };
 
-  struct PendingRequest {
-    PendingRequest(StatusCallback error_callback,
-                   base::Time time,
-                   const base::TimeTicks& time_ticks,
-                   ServiceWorkerMetrics::EventType event_type);
-    ~PendingRequest();
+  // Keeps track of the status of each request, which starts at StartRequest()
+  // and ends at FinishRequest().
+  struct InflightRequest {
+    InflightRequest(StatusCallback error_callback,
+                    base::Time time,
+                    const base::TimeTicks& time_ticks,
+                    ServiceWorkerMetrics::EventType event_type);
+    ~InflightRequest();
 
     StatusCallback error_callback;
     base::Time start_time;
     base::TimeTicks start_time_ticks;
     ServiceWorkerMetrics::EventType event_type;
     // Points to this request's entry in |request_timeouts_|.
-    std::set<RequestInfo>::iterator timeout_iter;
+    std::set<InflightRequestTimeoutInfo>::iterator timeout_iter;
   };
 
   using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>;
@@ -706,7 +709,7 @@
                                bool is_browser_startup_complete,
                                ServiceWorkerStatusCode status);
 
-  bool MaybeTimeOutRequest(const RequestInfo& info);
+  bool MaybeTimeoutRequest(const InflightRequestTimeoutInfo& info);
   void SetAllRequestExpirations(const base::TimeTicks& expiration);
 
   // Returns the reason the embedded worker failed to start, using information
@@ -760,13 +763,13 @@
 
   // Holds in-flight requests, including requests due to outstanding push,
   // fetch, sync, etc. events.
-  base::IDMap<std::unique_ptr<PendingRequest>> pending_requests_;
+  base::IDMap<std::unique_ptr<InflightRequest>> inflight_requests_;
 
   // Keeps track of in-flight requests for timeout purposes. Requests are sorted
   // by their expiration time (soonest to expire at the beginning of the
   // set). The timeout timer periodically checks |request_timeouts_| for entries
   // that should time out.
-  std::set<RequestInfo> request_timeouts_;
+  std::set<InflightRequestTimeoutInfo> request_timeouts_;
 
   // Container for pending external requests for this service worker.
   // (key, value): (request uuid, request id).
@@ -784,8 +787,8 @@
 
   // The number of fetch event responses that the service worker is streaming to
   // the browser process. We try to not stop the service worker while there is
-  // an ongoing response.
-  int pending_stream_response_count_ = 0;
+  // an inflight response.
+  int inflight_stream_response_count_ = 0;
 
   // S13nServiceWorker:
   // Set to true if the worker has no inflight events and the idle timer has
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index c163d7a..ed7d48d 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -1055,7 +1055,7 @@
   EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
                                        base::Time::Now()));
 
-  // Simulate the renderer aborting the pending event.
+  // Simulate the renderer aborting the inflight event.
   // This should not crash: https://crbug.com/676984.
   TakeExtendableMessageEventCallback().Run(
       blink::mojom::ServiceWorkerEventStatus::ABORTED, base::Time::Now());
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 37445b29..af2cb15 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -38,6 +38,7 @@
 #include "build/build_config.h"
 #include "cc/input/touch_action.h"
 #include "components/network_session_configurator/common/network_switches.h"
+#include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/frame_host/cross_process_frame_connector.h"
 #include "content/browser/frame_host/frame_navigation_entry.h"
 #include "content/browser/frame_host/frame_tree.h"
@@ -127,7 +128,6 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/json/json_reader.h"
 #include "content/browser/android/ime_adapter_android.h"
 #include "content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h"
 #include "content/browser/renderer_host/render_widget_host_view_android.h"
@@ -1833,9 +1833,9 @@
   RenderFrameHostImpl* child_frame_b = root->child_at(0)->current_frame_host();
   RenderFrameHostImpl* child_frame_c =
       root->child_at(0)->child_at(0)->current_frame_host();
-  RenderWidgetHostView *main_frame_rwhv = main_frame->GetView(),
-                       *child_frame_b_rwhv = child_frame_b->GetView(),
-                       *child_frame_c_rwhv = child_frame_c->GetView();
+  RenderWidgetHostView* main_frame_rwhv = main_frame->GetView();
+  RenderWidgetHostView* child_frame_b_rwhv = child_frame_b->GetView();
+  RenderWidgetHostView* child_frame_c_rwhv = child_frame_c->GetView();
 
   // Wait until <iframe> 'b' is not visible (in main frame).
   while (main_frame_rwhv->GetViewBounds().Intersects(
@@ -12932,4 +12932,64 @@
   }
 }
 
+// Test that a renderer locked to origin A will be killed if it tries to commit
+// a navigation to origin B.  See also https://crbug.com/770239.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+                       CommittedOriginIncompatibleWithOriginLock) {
+  GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), start_url));
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+
+  // Setup an URL which will never commit, allowing this test to send its own,
+  // malformed, commit message.
+  GURL another_url(embedded_test_server()->GetURL("b.com", "/hung"));
+
+  // Use LoadURL, as the test shouldn't wait for navigation commit.
+  NavigationController& controller = shell()->web_contents()->GetController();
+  controller.LoadURL(another_url, Referrer(), ui::PAGE_TRANSITION_LINK,
+                     std::string());
+  EXPECT_NE(nullptr, controller.GetPendingEntry());
+  EXPECT_EQ(another_url, controller.GetPendingEntry()->GetURL());
+
+  RenderProcessHostWatcher exit_observer(
+      root->current_frame_host()->GetProcess(),
+      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+
+  // Create commit params with a different origin than the origin lock
+  // of the process.
+  std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
+      std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
+  params->nav_entry_id = 0;
+  params->did_create_new_entry = false;
+  params->url = another_url;
+  params->transition = ui::PAGE_TRANSITION_LINK;
+  params->should_update_history = false;
+  params->gesture = NavigationGestureAuto;
+  params->was_within_same_document = false;
+  params->method = "GET";
+  params->page_state = PageState::CreateFromURL(another_url);
+  // Use an origin mismatched with the origin lock.
+  params->origin = url::Origin::Create(another_url);
+  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+  int process_id = root->current_frame_host()->GetProcess()->GetID();
+  EXPECT_EQ(start_url.host(), policy->GetOriginLock(process_id).host());
+  EXPECT_NE(another_url.host(), policy->GetOriginLock(process_id).host());
+  // Simulate a commit IPC.
+  service_manager::mojom::InterfaceProviderPtr interface_provider;
+  static_cast<mojom::FrameHost*>(root->current_frame_host())
+      ->DidCommitProvisionalLoad(std::move(params),
+                                 mojo::MakeRequest(&interface_provider));
+
+  // When the IPC message is received and validation fails, the process is
+  // terminated. However, the notification for that should be processed in a
+  // separate task of the message loop, so ensure that the process is still
+  // considered alive.
+  EXPECT_TRUE(root->current_frame_host()->GetProcess()->HasConnection());
+
+  exit_observer.Wait();
+  EXPECT_FALSE(exit_observer.did_exit_normally());
+}
+
 }  // namespace content
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index 4e3c31a..ae56adf 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -1755,7 +1755,7 @@
 TEST_F(WebContentsImplTest,
        ShowInterstitialFromBrowserNewNavigationProceed) {
   // Navigate to a page.
-  GURL url1("http://www.google.com");
+  GURL url1("http://www.thepage.com/one");
   NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
   EXPECT_EQ(1, controller().GetEntryCount());
 
@@ -1797,7 +1797,7 @@
 
   // Simulate the navigation to the page, that's when the interstitial gets
   // hidden.
-  GURL url3("http://www.thepage.com");
+  GURL url3("http://www.thepage.com/two");
   main_test_rfh()->PrepareForCommit();
   main_test_rfh()->SendNavigate(0, true, url3);
 
@@ -2241,7 +2241,7 @@
 // Test showing an interstitial while another interstitial is already showing.
 TEST_F(WebContentsImplTest, ShowInterstitialOnInterstitial) {
   // Navigate to a page so we have a navigation entry in the controller.
-  GURL start_url("http://www.google.com");
+  GURL start_url("http://www.thepage.com/one");
   NavigationSimulator::NavigateAndCommitFromDocument(start_url,
                                                      main_test_rfh());
   EXPECT_EQ(1, controller().GetEntryCount());
@@ -2280,7 +2280,7 @@
 
   // Let's make sure interstitial2 is working as intended.
   interstitial2->Proceed();
-  GURL landing_url("http://www.thepage.com");
+  GURL landing_url("http://www.thepage.com/two");
   main_test_rfh()->SendNavigate(0, true, landing_url);
 
   EXPECT_FALSE(contents()->ShowingInterstitialPage());
@@ -2297,7 +2297,7 @@
 // interstitial.
 TEST_F(WebContentsImplTest, ShowInterstitialProceedShowInterstitial) {
   // Navigate to a page so we have a navigation entry in the controller.
-  GURL start_url("http://www.google.com");
+  GURL start_url("http://www.thepage.com/one");
   NavigationSimulator::NavigateAndCommitFromDocument(start_url,
                                                      main_test_rfh());
   EXPECT_EQ(1, controller().GetEntryCount());
@@ -2340,7 +2340,7 @@
 
   // Let's make sure interstitial2 is working as intended.
   interstitial2->Proceed();
-  GURL landing_url("http://www.thepage.com");
+  GURL landing_url("http://www.thepage.com/two");
   main_test_rfh()->SendNavigate(0, true, landing_url);
 
   RunAllPendingInMessageLoop();
@@ -3241,9 +3241,9 @@
 // TODO(fdegans): Rewrite the test for PlzNavigate when DidStartLoading and
 // DidStopLoading are properly called.
 TEST_F(WebContentsImplTest, NoEarlyStop) {
-  const GURL kUrl1("http://www.chromium.org");
+  const GURL kUrl1("http://www.chromium.org/one");
   const GURL kUrl2("http://www.google.com");
-  const GURL kUrl3("http://www.wikipedia.org");
+  const GURL kUrl3("http://www.chromium.org/two");
 
   contents()->NavigateAndCommit(kUrl1);
 
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h
index f4e8b4b..1ecd22e 100644
--- a/content/common/resource_messages.h
+++ b/content/common/resource_messages.h
@@ -217,7 +217,6 @@
   IPC_STRUCT_TRAITS_MEMBER(fetch_redirect_mode)
   IPC_STRUCT_TRAITS_MEMBER(fetch_integrity)
   IPC_STRUCT_TRAITS_MEMBER(fetch_request_context_type)
-  IPC_STRUCT_TRAITS_MEMBER(fetch_mixed_content_context_type)
   IPC_STRUCT_TRAITS_MEMBER(fetch_frame_type)
   IPC_STRUCT_TRAITS_MEMBER(request_body)
   IPC_STRUCT_TRAITS_MEMBER(download_to_file)
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
index 49c90b3..cd580610 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
@@ -5,7 +5,6 @@
 package org.chromium.content.browser;
 
 import android.content.pm.ActivityInfo;
-import android.support.test.filters.MediumTest;
 import android.view.Surface;
 
 import org.junit.After;
@@ -18,7 +17,7 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.content_public.common.ScreenOrientationValues;
 import org.chromium.content_shell_apk.ContentShellActivityTestRule;
 import org.chromium.ui.display.DisplayAndroid;
@@ -172,9 +171,10 @@
         return mCallbackHelper.getLastRotation();
     }
 
+    // @MediumTest
+    // @Feature({"ScreenOrientation"})
     @Test
-    @MediumTest
-    @Feature({"ScreenOrientation"})
+    @DisabledTest(message = "https://crbug.com/797175")
     public void testOrientationChanges() throws Exception {
         int rotation = lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
         Assert.assertEquals(
@@ -252,9 +252,10 @@
         return mCallbackHelper.getLastRotation();
     }
 
+    // @MediumTest
+    // @Feature({"ScreenOrientation"})
     @Test
-    @MediumTest
-    @Feature({"ScreenOrientation"})
+    @DisabledTest(message = "https://crbug.com/797175")
     public void testBasicValues() throws Exception {
         int rotation = lockOrientationValueAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
         Assert.assertEquals(
diff --git a/content/public/common/resource_request.h b/content/public/common/resource_request.h
index cd94da67..d637851 100644
--- a/content/public/common/resource_request.h
+++ b/content/public/common/resource_request.h
@@ -23,7 +23,6 @@
 #include "services/network/public/interfaces/fetch_api.mojom.h"
 #include "services/network/public/interfaces/request_context_frame_type.mojom.h"
 #include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
-#include "third_party/WebKit/public/platform/WebMixedContentContextType.h"
 #include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
 #include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
@@ -135,10 +134,6 @@
   RequestContextType fetch_request_context_type =
       REQUEST_CONTEXT_TYPE_UNSPECIFIED;
 
-  // The mixed content context type to be used for mixed content checks.
-  blink::WebMixedContentContextType fetch_mixed_content_context_type =
-      blink::WebMixedContentContextType::kBlockable;
-
   // The frame type passed to the ServiceWorker.
   network::mojom::RequestContextFrameType fetch_frame_type =
       network::mojom::RequestContextFrameType::kAuxiliary;
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc
index 09569f88..efafce70 100644
--- a/content/public/common/web_preferences.cc
+++ b/content/public/common/web_preferences.cc
@@ -232,11 +232,7 @@
       presentation_receiver(false),
       media_controls_enabled(true),
       do_not_update_selection_on_mutating_selection_range(false),
-#if defined(OS_ANDROID)
-      autoplay_policy(AutoplayPolicy::kUserGestureRequired) {
-#else
-      autoplay_policy(AutoplayPolicy::kNoUserGestureRequired) {
-#endif  // defined(OS_ANDROID)
+      autoplay_policy(AutoplayPolicy::kDocumentUserActivationRequired) {
   standard_font_family_map[kCommonScript] =
       base::ASCIIToUTF16("Times New Roman");
   fixed_font_family_map[kCommonScript] = base::ASCIIToUTF16("Courier New");
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index 9be05695..fefce106 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -639,8 +639,6 @@
       GetFetchIntegrityForWebURLRequest(request);
   resource_request->fetch_request_context_type =
       GetRequestContextTypeForWebURLRequest(request);
-  resource_request->fetch_mixed_content_context_type =
-      GetMixedContentContextTypeForWebURLRequest(request);
 
   resource_request->fetch_frame_type = request.GetFrameType();
   resource_request->request_body =
diff --git a/content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc b/content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc
similarity index 95%
rename from content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc
rename to content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc
index ca0760bf..f59a469 100644
--- a/content/renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc
+++ b/content/renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc
@@ -10,8 +10,8 @@
 
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
-#include "content/public/test/render_view_test.h"
-#include "content/public/test/test_utils.h"
+#include "base/message_loop/message_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebLockOrientationCallback.h"
 
 namespace content {
@@ -51,12 +51,9 @@
   LockOrientationResultHolder* results_;
 };
 
-// TODO(loonybear): When available, test mojo service without needing a
-// RenderViewTest.
-class ScreenOrientationDispatcherTest : public RenderViewTest {
+class ScreenOrientationDispatcherTest : public testing::Test {
  protected:
   void SetUp() override {
-    RenderViewTest::SetUp();
     dispatcher_.reset(new ScreenOrientationDispatcher(nullptr));
     ScreenOrientationAssociatedPtr screen_orientation;
     mojo::MakeRequestAssociatedWithDedicatedPipe(&screen_orientation);
@@ -77,6 +74,7 @@
     dispatcher_->OnLockOrientationResult(request_id, result);
   }
 
+  base::MessageLoop message_loop_;
   std::unique_ptr<ScreenOrientationDispatcher> dispatcher_;
 };
 
diff --git a/content/renderer/web_ui_extension.cc b/content/renderer/web_ui_extension.cc
index 3259b5f7..93ff280 100644
--- a/content/renderer/web_ui_extension.cc
+++ b/content/renderer/web_ui_extension.cc
@@ -120,6 +120,13 @@
     content = base::ListValue::From(V8ValueConverter::Create()->FromV8Value(
         obj, frame->MainWorldScriptContext()));
     DCHECK(content);
+    // The conversion of |obj| could have triggered arbitrary JavaScript code,
+    // so check that the frame is still valid to avoid dereferencing a stale
+    // pointer.
+    if (frame != blink::WebLocalFrame::FrameForCurrentContext()) {
+      NOTREACHED();
+      return;
+    }
   }
 
   // Send the message up to the browser.
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc
index 616d1075..8bbd09a5 100644
--- a/content/shell/browser/layout_test/blink_test_controller.cc
+++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -800,6 +800,11 @@
     RenderViewHost* rvh = main_window_->web_contents()->GetRenderViewHost();
     rvh->Send(new ShellViewMsg_Reset(rvh->GetRoutingID()));
   }
+  if (secondary_window_) {
+    RenderViewHost* rvh =
+        secondary_window_->web_contents()->GetRenderViewHost();
+    rvh->Send(new ShellViewMsg_Reset(rvh->GetRoutingID()));
+  }
 }
 
 void BlinkTestController::OnImageDump(const std::string& actual_pixel_hash,
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index a6491e1..4cc50a0 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -822,7 +822,6 @@
     "../renderer/render_view_browsertest.cc",
     "../renderer/render_view_browsertest_mac.mm",
     "../renderer/render_widget_browsertest.cc",
-    "../renderer/screen_orientation/screen_orientation_dispatcher_browsertest.cc",
     "../renderer/visual_state_browsertest.cc",
     "../renderer/webclipboard_impl_browsertest.cc",
     "../test/browser_test_utils_browsertest.cc",
@@ -866,7 +865,6 @@
     "//content/shell:pak",
     "//content/test:test_support",
     "//device/base/synchronization",
-    "//device/screen_orientation/public/interfaces",
     "//device/sensors",
     "//device/sensors/public/cpp:full",
     "//gin",
@@ -1587,6 +1585,7 @@
     "../renderer/presentation/test_presentation_connection.h",
     "../renderer/render_thread_impl_unittest.cc",
     "../renderer/render_widget_unittest.cc",
+    "../renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc",
     "../renderer/service_worker/service_worker_context_client_unittest.cc",
     "../renderer/service_worker/service_worker_dispatcher_unittest.cc",
     "../renderer/service_worker/service_worker_provider_context_unittest.cc",
@@ -1683,6 +1682,7 @@
     "//device/gamepad/public/cpp:shared_with_blink",
     "//device/geolocation",
     "//device/geolocation/public/interfaces",
+    "//device/screen_orientation/public/interfaces",
     "//device/sensors/public/cpp:full",
     "//device/sensors/public/interfaces",
     "//gin",
diff --git a/content/test/ppapi/ppapi_test.cc b/content/test/ppapi/ppapi_test.cc
index c5fef56..31d0cdb9 100644
--- a/content/test/ppapi/ppapi_test.cc
+++ b/content/test/ppapi/ppapi_test.cc
@@ -16,6 +16,7 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/test/ppapi_test_utils.h"
 #include "content/shell/browser/shell.h"
+#include "media/base/media_switches.h"
 #include "net/base/filename_util.h"
 #include "ppapi/shared_impl/ppapi_switches.h"
 
@@ -57,6 +58,10 @@
   command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose_gc");
 
   command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
+
+  command_line->AppendSwitchASCII(
+      switches::kAutoplayPolicy,
+      switches::autoplay::kNoUserGestureRequiredPolicy);
 }
 
 GURL PPAPITestBase::GetTestFileUrl(const std::string& test_case) {
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc
index 5bdf9f6..78a596a 100644
--- a/ios/chrome/browser/pref_names.cc
+++ b/ios/chrome/browser/pref_names.cc
@@ -60,6 +60,13 @@
 // Prefs for persisting HttpServerProperties.
 const char kHttpServerProperties[] = "net.http_server_properties";
 
+// Caches the folder id of user's position in the bookmark hierarchy navigator.
+const char kIosBookmarkCachedFolderId[] = "ios.bookmark.cached_folder_id";
+
+// Caches the scroll position of Bookmarks.
+const char kIosBookmarkCachedScrollPosition[] =
+    "ios.bookmark.cached_scroll_position";
+
 // Preference that keep information about where to create a new bookmark.
 const char kIosBookmarkFolderDefault[] = "ios.bookmark.default_folder";
 
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h
index 5a0c3cd..e3b07c1 100644
--- a/ios/chrome/browser/pref_names.h
+++ b/ios/chrome/browser/pref_names.h
@@ -21,6 +21,8 @@
 extern const char kDefaultCharset[];
 extern const char kEnableDoNotTrack[];
 extern const char kHttpServerProperties[];
+extern const char kIosBookmarkCachedFolderId[];
+extern const char kIosBookmarkCachedScrollPosition[];
 extern const char kIosBookmarkFolderDefault[];
 extern const char kIosBookmarkPromoAlreadySeen[];
 extern const char kIosBookmarkSigninPromoDisplayedCount[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm
index be4f23cc..e1745c4 100644
--- a/ios/chrome/browser/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -49,6 +49,8 @@
 #include "ios/chrome/browser/signin/signin_manager_factory.h"
 #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_mediator.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 #include "ios/chrome/browser/voice/voice_search_prefs_registration.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -118,6 +120,7 @@
   RegisterVoiceSearchBrowserStatePrefs(registry);
 
   [BookmarkMediator registerBrowserStatePrefs:registry];
+  [BookmarkPathCache registerBrowserStatePrefs:registry];
   [SigninPromoViewMediator registerBrowserStatePrefs:registry];
   [HandoffManager registerBrowserStatePrefs:registry];
 
diff --git a/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm b/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm
index 624a4ca9..80cfc7ac4 100644
--- a/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm
+++ b/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm
@@ -14,11 +14,16 @@
   return nil;
 }
 
-- (UIEdgeInsets)snapshotEdgeInsets {
+- (BOOL)canTakeSnapshotForWebState:(web::WebState*)webState {
+  return YES;
+}
+
+- (UIEdgeInsets)snapshotEdgeInsetsForWebState:(web::WebState*)webState {
   return UIEdgeInsetsZero;
 }
 
-- (NSArray<SnapshotOverlay*>*)snapshotOverlays {
+- (NSArray<SnapshotOverlay*>*)snapshotOverlaysForWebState:
+    (web::WebState*)webState {
   return nil;
 }
 
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.h b/ios/chrome/browser/snapshots/snapshot_generator.h
index 2f915a8f..dfc0442 100644
--- a/ios/chrome/browser/snapshots/snapshot_generator.h
+++ b/ios/chrome/browser/snapshots/snapshot_generator.h
@@ -37,11 +37,9 @@
 - (void)retrieveSnapshot:(void (^)(UIImage*))callback;
 
 // Gets a grey snapshot for the current page, calling |callback| once it has
-// been retrieved or regenerated. If |generate| is NO, then the snapshot will
-// not be generated if missing.  If the snapshot cannot be generated, the
+// been retrieved or regenerated. If the snapshot cannot be generated, the
 // |callback| will be called with nil.
-- (void)retrieveGreySnapshot:(void (^)(UIImage*))callback
-                    generate:(BOOL)generate;
+- (void)retrieveGreySnapshot:(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
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm
index 3b5c27d..3c19901 100644
--- a/ios/chrome/browser/snapshots/snapshot_generator.mm
+++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -162,13 +162,12 @@
   }
 }
 
-- (void)retrieveGreySnapshot:(void (^)(UIImage*))callback
-                    generate:(BOOL)generate {
+- (void)retrieveGreySnapshot:(void (^)(UIImage*))callback {
   DCHECK(callback);
 
   __weak SnapshotGenerator* weakSelf = self;
   void (^wrappedCallback)(UIImage*) = ^(UIImage* image) {
-    if (!image && generate) {
+    if (!image) {
       image = [weakSelf updateSnapshotWithOverlays:YES visibleFrameOnly:YES];
       if (image)
         image = GreyImage(image);
@@ -196,7 +195,7 @@
 
   UIImage* snapshotToCache = snapshot;
   if (!visibleFrameOnly) {
-    UIEdgeInsets insets = [_delegate snapshotEdgeInsets];
+    UIEdgeInsets insets = [_delegate snapshotEdgeInsetsForWebState:_webState];
     if (!UIEdgeInsetsEqualToEdgeInsets(insets, UIEdgeInsetsZero)) {
       CGRect cropRect =
           UIEdgeInsetsInsetRect(CGRect{CGPointZero, [snapshot size]}, insets);
@@ -211,13 +210,20 @@
 
 - (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay
                         visibleFrameOnly:(BOOL)visibleFrameOnly {
-  if (!_webState->CanTakeSnapshot())
+  // Do not generate a snapshot if web usage is disabled (as the WebState's
+  // view is blank in that case).
+  if (!_webState->IsWebUsageEnabled())
+    return nil;
+
+  // Do not generate a snapshot if the delegate says the WebState view is
+  // not ready (this generally mean a placeholder is displayed).
+  if (_delegate && ![_delegate canTakeSnapshotForWebState:_webState])
     return nil;
 
   UIView* view = _webState->GetView();
   CGRect bounds = [view bounds];
   if (visibleFrameOnly) {
-    UIEdgeInsets insets = [_delegate snapshotEdgeInsets];
+    UIEdgeInsets insets = [_delegate snapshotEdgeInsetsForWebState:_webState];
     bounds = UIEdgeInsetsInsetRect(bounds, insets);
   }
 
@@ -225,7 +231,8 @@
     return nil;
 
   NSArray<SnapshotOverlay*>* overlays =
-      shouldAddOverlay ? [_delegate snapshotOverlays] : nil;
+      shouldAddOverlay ? [_delegate snapshotOverlaysForWebState:_webState]
+                       : nil;
   UIImage* snapshot =
       [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays
                                             visibleFrameOnly:visibleFrameOnly];
diff --git a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
index 28f659a91..101d986 100644
--- a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
+++ b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
@@ -20,14 +20,19 @@
 // Returns the default image to return when the snapshot cannot be generated.
 - (UIImage*)defaultSnapshotImage;
 
-// Returns the edge insets to use to crop the snapshot during generation. If
-// the snapshot should not be cropped, then UIEdgeInsetsZero can be returned.
-- (UIEdgeInsets)snapshotEdgeInsets;
+// Returns whether it is possible to capture a snapshot for |webState|.
+- (BOOL)canTakeSnapshotForWebState:(web::WebState*)webState;
+
+// Returns the edge insets to use to crop the snapshot for |webState| during
+// generation. If the snapshot should not be cropped, then UIEdgeInsetsZero
+// can be returned.
+- (UIEdgeInsets)snapshotEdgeInsetsForWebState:(web::WebState*)webState;
 
 // Returns the list of SnapshotOverlays that should be rendered over the
-// page when generating the snapshot. If no overlays should be rendered,
-// the list may be nil or empty.
-- (NSArray<SnapshotOverlay*>*)snapshotOverlays;
+// page when generating the snapshot for |webState|. If no overlays should
+// be rendered, the list may be nil or empty.
+- (NSArray<SnapshotOverlay*>*)snapshotOverlaysForWebState:
+    (web::WebState*)webState;
 
 // Invoked before capturing a snapshot for |webState|. The delegate can remove
 // subviews from the hierarchy or take other actions to ensure the snapshot
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.h b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
index f2239c1..990b4ab 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper.h
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.h
@@ -41,9 +41,8 @@
   // Retrieves a grey snapshot for the current page, invoking |callback|
   // with the image. The callback may be called synchronously is there is
   // a cached snapshot available in memory, otherwise it will be invoked
-  // asynchronously after retrieved from disk or re-generated. If |generate|
-  // is false, then the snapshot is not regenerated if not found in cache.
-  void RetrieveGreySnapshot(void (^callback)(UIImage*), bool generate);
+  // asynchronously after retrieved from disk or re-generated.
+  void RetrieveGreySnapshot(void (^callback)(UIImage*));
 
   // Invalidates the cached snapshot for the current page and forces the
   // generation of a more recent snapshot. Returns the snapshot with or
@@ -64,8 +63,6 @@
   void RemoveSnapshot();
 
  private:
-  friend class web::WebStateUserData<SnapshotTabHelper>;
-
   SnapshotTabHelper(web::WebState* web_state, NSString* session_id);
 
   // web::WebStateObserver implementation.
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
index fe909b5..65cf3eb 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper.mm
@@ -114,9 +114,8 @@
   [snapshot_generator_ retrieveSnapshot:callback];
 }
 
-void SnapshotTabHelper::RetrieveGreySnapshot(void (^callback)(UIImage*),
-                                             bool generate) {
-  [snapshot_generator_ retrieveGreySnapshot:callback generate:generate];
+void SnapshotTabHelper::RetrieveGreySnapshot(void (^callback)(UIImage*)) {
+  [snapshot_generator_ retrieveGreySnapshot:callback];
 }
 
 UIImage* SnapshotTabHelper::UpdateSnapshot(bool with_overlays,
diff --git a/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm b/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm
index 4e21d541..4856dbe 100644
--- a/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm
+++ b/ios/chrome/browser/snapshots/snapshot_tab_helper_unittest.mm
@@ -28,7 +28,8 @@
 using ui::test::uiimage_utils::UIImageWithSizeAndSolidColor;
 
 // SnapshotGeneratorDelegate used to test SnapshotTabHelper by allowing to
-// set a default snapshot image and to count the number of snapshot generated.
+// set a default snapshot image, control whether capturing a snapshot is
+// possible and to count the number of snapshot generated.
 @interface TabHelperSnapshotGeneratorDelegate : FakeSnapshotGeneratorDelegate
 
 // Initialize the delegate with the default snapshot image.
@@ -38,6 +39,10 @@
 // calls to -willUpdateSnapshotForWebState:).
 @property(nonatomic, readonly) NSUInteger snapshotTakenCount;
 
+// This property controls the value returned by -canTakeSnapshotForWebState:
+// method of the SnapshotGeneratorDelegate protocol.
+@property(nonatomic, assign) BOOL canTakeSnapshot;
+
 @end
 
 @implementation TabHelperSnapshotGeneratorDelegate {
@@ -45,6 +50,7 @@
 }
 
 @synthesize snapshotTakenCount = _snapshotTakenCount;
+@synthesize canTakeSnapshot = _canTakeSnapshot;
 
 - (instancetype)initWithDefaultSnapshotImage:(UIImage*)defaultSnapshotImage {
   if ((self = [super init])) {
@@ -59,6 +65,10 @@
   return _defaultSnapshotImage;
 }
 
+- (BOOL)canTakeSnapshotForWebState:(web::WebState*)webState {
+  return !_canTakeSnapshot;
+}
+
 - (void)willUpdateSnapshotForWebState:(web::WebState*)webState {
   ++_snapshotTakenCount;
 }
@@ -100,8 +110,7 @@
     browser_state_ = builder.Build();
     web_state_.SetBrowserState(browser_state_.get());
 
-    // Creates a default delegate. Some tests override it to check that
-    // the tab helper works correctly even if the delegate is nil.
+    // Create the SnapshotTabHelper with a fake delegate.
     snapshot_session_id_ = [[NSUUID UUID] UUIDString];
     delegate_ = [[TabHelperSnapshotGeneratorDelegate alloc]
         initWithDefaultSnapshotImage:UIImageWithSizeAndSolidColor(
@@ -156,7 +165,7 @@
 
 // Tests that RetrieveColorSnapshot uses the image from the cache if
 // there is one present.
-TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshot_CachedSnapshot) {
+TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshotCachedSnapshot) {
   SetCachedSnapshot(
       UIImageWithSizeAndSolidColor(kCachedSnapshotSize, [UIColor greenColor]));
 
@@ -177,10 +186,12 @@
   EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
 }
 
-// Tests that RetrieveColorSnapshot returns the default snapshot image if
-// there is one defined when there is no cached snapshot and the WebState
-// is not ready for taking a snapshot.
-TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshot_DefaultSnapshotImage) {
+// Tests that RetrieveColorSnapshot returns the default snapshot image when
+// there is no cached snapshot and the WebState web usage is disabled.
+TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshotWebUsageDisabled) {
+  web_state_.SetWebUsageEnabled(false);
+  AddDefaultWebStateView();
+
   base::RunLoop run_loop;
   base::RunLoop* run_loop_ptr = &run_loop;
 
@@ -198,10 +209,12 @@
   EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
 }
 
-// Tests that RetrieveColorSnapshot when there is no cached snapshot, the
-// WebState is not ready for taking a snapshot and there is no delegate.
-TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshot_CannotTakeSnapshot) {
-  SnapshotTabHelper::FromWebState(&web_state_)->SetDelegate(nil);
+// Tests that RetrieveColorSnapshot returns the default snapshot image when
+// there is no cached snapshot and the delegate says it is not possible to
+// take a snapshot.
+TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshotCannotTakeSnapshot) {
+  delegate_.canTakeSnapshot = YES;
+  AddDefaultWebStateView();
 
   base::RunLoop run_loop;
   base::RunLoop* run_loop_ptr = &run_loop;
@@ -215,13 +228,14 @@
 
   run_loop.Run();
 
-  EXPECT_FALSE(snapshot);
+  ASSERT_TRUE(snapshot);
+  EXPECT_TRUE(UIImagesAreEqual(snapshot, [delegate_ defaultSnapshotImage]));
   EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
 }
 
 // Tests that RetrieveColorSnapshot generates the image if there is no
 // image in the cache.
-TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshot_NoCachedSnapshot) {
+TEST_F(SnapshotTabHelperTest, RetrieveColorSnapshotGenerate) {
   AddDefaultWebStateView();
 
   base::RunLoop run_loop;
@@ -244,7 +258,7 @@
 
 // Tests that RetrieveGreySnapshot uses the image from the cache if
 // there is one present, and that it is greyscale.
-TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshot_CachedSnapshot) {
+TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshotCachedSnapshot) {
   SetCachedSnapshot(
       UIImageWithSizeAndSolidColor(kCachedSnapshotSize, [UIColor greenColor]));
 
@@ -253,12 +267,10 @@
 
   __block UIImage* snapshot = nil;
   SnapshotTabHelper::FromWebState(&web_state_)
-      ->RetrieveGreySnapshot(
-          ^(UIImage* image) {
-            snapshot = image;
-            run_loop_ptr->Quit();
-          },
-          /*generate=*/true);
+      ->RetrieveGreySnapshot(^(UIImage* image) {
+        snapshot = image;
+        run_loop_ptr->Quit();
+      });
 
   run_loop.Run();
 
@@ -267,21 +279,21 @@
   EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
 }
 
-// Tests that RetrieveGreySnapshot returns the default snapshot image if
-// there is one defined when there is no cached snapshot and the WebState
-// is not ready for taking a snapshot, and that it is greyscale.
-TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshot_DefaultSnapshotImage) {
+// Tests that RetrieveGreySnapshot returns the default snapshot image when
+// there is no cached snapshot and the WebState web usage is disabled.
+TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshotWebUsageDisabled) {
+  web_state_.SetWebUsageEnabled(false);
+  AddDefaultWebStateView();
+
   base::RunLoop run_loop;
   base::RunLoop* run_loop_ptr = &run_loop;
 
   __block UIImage* snapshot = nil;
   SnapshotTabHelper::FromWebState(&web_state_)
-      ->RetrieveGreySnapshot(
-          ^(UIImage* image) {
-            snapshot = image;
-            run_loop_ptr->Quit();
-          },
-          /*generate=*/true);
+      ->RetrieveGreySnapshot(^(UIImage* image) {
+        snapshot = image;
+        run_loop_ptr->Quit();
+      });
 
   run_loop.Run();
 
@@ -291,32 +303,10 @@
   EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
 }
 
-// Tests that RetrieveGreySnapshot when there is no cached snapshot, the
-// WebState is not ready for taking a snapshot and there is no delegate.
-TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshot_CannotTakeSnapshot) {
-  SnapshotTabHelper::FromWebState(&web_state_)->SetDelegate(nil);
-
-  base::RunLoop run_loop;
-  base::RunLoop* run_loop_ptr = &run_loop;
-
-  __block UIImage* snapshot = nil;
-  SnapshotTabHelper::FromWebState(&web_state_)
-      ->RetrieveGreySnapshot(
-          ^(UIImage* image) {
-            snapshot = image;
-            run_loop_ptr->Quit();
-          },
-          /*generate=*/false);
-
-  run_loop.Run();
-
-  EXPECT_FALSE(snapshot);
-  EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
-}
-
-// Tests that RetrieveGreySnapshot generates the image if there is no
-// image in the cache, and that it is greyscale.
-TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshot_NoCachedSnapshot) {
+// Tests that RetrieveGreySnapshot returns the default snapshot image when
+// there is no cached snapshot and the WebState web usage is disabled.
+TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshotCannotTakeSnapshot) {
+  delegate_.canTakeSnapshot = YES;
   AddDefaultWebStateView();
 
   base::RunLoop run_loop;
@@ -324,12 +314,33 @@
 
   __block UIImage* snapshot = nil;
   SnapshotTabHelper::FromWebState(&web_state_)
-      ->RetrieveGreySnapshot(
-          ^(UIImage* image) {
-            snapshot = image;
-            run_loop_ptr->Quit();
-          },
-          /*generate=*/true);
+      ->RetrieveGreySnapshot(^(UIImage* image) {
+        snapshot = image;
+        run_loop_ptr->Quit();
+      });
+
+  run_loop.Run();
+
+  ASSERT_TRUE(snapshot);
+  EXPECT_TRUE(
+      UIImagesAreEqual(snapshot, GreyImage([delegate_ defaultSnapshotImage])));
+  EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
+}
+
+// Tests that RetrieveGreySnapshot generates the image if there is no
+// image in the cache, and that it is greyscale.
+TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshotGenerate) {
+  AddDefaultWebStateView();
+
+  base::RunLoop run_loop;
+  base::RunLoop* run_loop_ptr = &run_loop;
+
+  __block UIImage* snapshot = nil;
+  SnapshotTabHelper::FromWebState(&web_state_)
+      ->RetrieveGreySnapshot(^(UIImage* image) {
+        snapshot = image;
+        run_loop_ptr->Quit();
+      });
 
   run_loop.Run();
 
@@ -339,29 +350,6 @@
   EXPECT_EQ(delegate_.snapshotTakenCount, 1u);
 }
 
-// Tests that RetrieveGreySnapshot does not generate an image if |generate|
-// is false and there is no cached snapshot.
-TEST_F(SnapshotTabHelperTest, RetrieveGreySnapshot_NoGenerate) {
-  AddDefaultWebStateView();
-
-  base::RunLoop run_loop;
-  base::RunLoop* run_loop_ptr = &run_loop;
-
-  __block UIImage* snapshot = nil;
-  SnapshotTabHelper::FromWebState(&web_state_)
-      ->RetrieveGreySnapshot(
-          ^(UIImage* image) {
-            snapshot = image;
-            run_loop_ptr->Quit();
-          },
-          /*generate=*/false);
-
-  run_loop.Run();
-
-  ASSERT_FALSE(snapshot);
-  EXPECT_EQ(delegate_.snapshotTakenCount, 0u);
-}
-
 // Tests that UpdateSnapshot ignores any cached snapshots, generate a new one
 // and updates the cache.
 TEST_F(SnapshotTabHelperTest, UpdateSnapshot) {
@@ -385,7 +373,7 @@
 
 // Tests that if snapshot coalescing is disabled, each call to UpdateSnapshot
 // will cause a new snapshot to be generated.
-TEST_F(SnapshotTabHelperTest, UpdateSnapshot_NoCoalescing) {
+TEST_F(SnapshotTabHelperTest, UpdateSnapshotNoCoalescing) {
   AddDefaultWebStateView();
 
   for (NSUInteger ii = 0; ii < kCountSnapshotToTake; ++ii) {
@@ -403,7 +391,7 @@
 
 // Tests that if snapshot coalescing is enabled, only the first call to
 // UpdateSnapshot will cause a new snapshot to be generated.
-TEST_F(SnapshotTabHelperTest, UpdateSnapshot_WithCoalescing) {
+TEST_F(SnapshotTabHelperTest, UpdateSnapshotWithCoalescing) {
   AddDefaultWebStateView();
 
   SnapshotTabHelper::FromWebState(&web_state_)
@@ -445,7 +433,7 @@
 
 // Tests that if snapshot coalescing is disabled, each call to GenerateSnapshot
 // will cause a new snapshot to be generated.
-TEST_F(SnapshotTabHelperTest, GenerateSnapshot_NoCoalescing) {
+TEST_F(SnapshotTabHelperTest, GenerateSnapshotNoCoalescing) {
   AddDefaultWebStateView();
 
   for (NSUInteger ii = 0; ii < kCountSnapshotToTake; ++ii) {
@@ -463,7 +451,7 @@
 
 // Tests that if snapshot coalescing is enabled, only the first call to
 // GenerateSnapshot will cause a new snapshot to be generated.
-TEST_F(SnapshotTabHelperTest, GenerateSnapshot_WithCoalescing) {
+TEST_F(SnapshotTabHelperTest, GenerateSnapshotWithCoalescing) {
   AddDefaultWebStateView();
 
   SnapshotTabHelper::FromWebState(&web_state_)
diff --git a/ios/chrome/browser/tabs/tab.h b/ios/chrome/browser/tabs/tab.h
index 98f5819..5f0ac6f0 100644
--- a/ios/chrome/browser/tabs/tab.h
+++ b/ios/chrome/browser/tabs/tab.h
@@ -98,9 +98,6 @@
 // ID associated with this tab.
 @property(nonatomic, readonly) NSString* tabId;
 
-// |YES| if snapshot overlay should load from the grey image cache.
-@property(nonatomic, assign) BOOL useGreyImageCache;
-
 // The Webstate associated with this Tab.
 @property(nonatomic, readonly) web::WebState* webState;
 
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index fadf418..83bff99 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -87,6 +87,7 @@
 #import "ios/chrome/browser/voice/voice_search_navigations_tab_helper.h"
 #import "ios/chrome/browser/web/external_app_launcher_tab_helper.h"
 #import "ios/chrome/browser/web/navigation_manager_util.h"
+#import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #import "ios/chrome/browser/web/passkit_dialog_provider.h"
 #import "ios/chrome/browser/web/tab_id_tab_helper.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -195,7 +196,6 @@
 @implementation Tab
 
 @synthesize browserState = _browserState;
-@synthesize useGreyImageCache = useGreyImageCache_;
 @synthesize overscrollActionsController = _overscrollActionsController;
 @synthesize overscrollActionsControllerDelegate =
     overscrollActionsControllerDelegate_;
@@ -918,23 +918,12 @@
   return YES;
 }
 
-- (void)webController:(CRWWebController*)webController
-    retrievePlaceholderOverlayImage:(void (^)(UIImage*))block {
-  [self getPlaceholderOverlayImageWithCompletionHandler:block];
-}
-
 #pragma mark - PlaceholderOverlay
 
 - (void)getPlaceholderOverlayImageWithCompletionHandler:
     (void (^)(UIImage*))completionHandler {
-  // The snapshot is always grey as this overlay represents an out-of-date
-  // website and is shown only until the load begins. If |useGreyImageCache_|
-  // is YES, the grey image is already cached in memory for swiping, and a
-  // cache miss is acceptable. In other cases, such as during startyp, either
-  // disk access or a greyspace conversion is required as there will be no
-  // grey snapshots in memory.
   SnapshotTabHelper::FromWebState(self.webState)
-      ->RetrieveGreySnapshot(completionHandler, !useGreyImageCache_);
+      ->RetrieveGreySnapshot(completionHandler);
 }
 
 #pragma mark - CRWWebDelegate and CRWWebStateObserver protocol methods
@@ -1055,7 +1044,14 @@
   return [CRWWebController defaultSnapshotImage];
 }
 
-- (UIEdgeInsets)snapshotEdgeInsets {
+- (BOOL)canTakeSnapshotForWebState:(web::WebState*)webState {
+  DCHECK_EQ(_webStateImpl, webState);
+  return !PagePlaceholderTabHelper::FromWebState(webState)
+              ->displaying_placeholder();
+}
+
+- (UIEdgeInsets)snapshotEdgeInsetsForWebState:(web::WebState*)webState {
+  DCHECK_EQ(_webStateImpl, webState);
   if (self.tabSnapshottingDelegate)
     return [self.tabSnapshottingDelegate snapshotEdgeInsetsForTab:self];
 
@@ -1067,7 +1063,9 @@
   return UIEdgeInsetsZero;
 }
 
-- (NSArray<SnapshotOverlay*>*)snapshotOverlays {
+- (NSArray<SnapshotOverlay*>*)snapshotOverlaysForWebState:
+    (web::WebState*)webState {
+  DCHECK_EQ(_webStateImpl, webState);
   return [snapshotOverlayProvider_ snapshotOverlaysForTab:self];
 }
 
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index 279f87cc..be09669 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -173,6 +173,7 @@
     "//base/test:test_support",
     "//components/bookmarks/browser",
     "//components/bookmarks/test",
+    "//components/sync_preferences:test_support",
     "//ios/chrome/browser",
     "//ios/chrome/browser/bookmarks",
     "//ios/chrome/browser/bookmarks:features",
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 36f4ed2..fec1f55 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -254,10 +254,11 @@
 
   if (base::FeatureList::IsEnabled(kBookmarkNewGeneration)) {
     // Cache position for BookmarkTableView in new UI.
-    BookmarkPathCache* cache = [BookmarkPathCache
-        cacheForBookmarkFolder:_rootNode->id()
-                      position:self.bookmarksTableView.contentPosition];
-    bookmark_utils_ios::CacheBookmarkUIPosition(cache);
+    [BookmarkPathCache
+        cacheBookmarkUIPositionWithPrefService:self.browserState->GetPrefs()
+                                      folderId:_rootNode->id()
+                                scrollPosition:(double)self.bookmarksTableView
+                                                   .contentPosition];
     return;
   }
 }
@@ -912,11 +913,18 @@
   if (![self isViewLoaded])
     return;
 
+  int64_t unusedFolderId;
+  double unusedScrollPosition;
   // Bookmark Model is loaded after presenting Bookmarks,  we need to check
   // again here if restoring of cache position is needed.  It is to prevent
   // crbug.com/765503.
   if (base::FeatureList::IsEnabled(kBookmarkNewGeneration) &&
-      bookmark_utils_ios::GetBookmarkUIPositionCache(_bookmarks)) {
+      [BookmarkPathCache
+          getBookmarkUIPositionCacheWithPrefService:self.browserState
+                                                        ->GetPrefs()
+                                              model:self.bookmarks
+                                           folderId:&unusedFolderId
+                                     scrollPosition:&unusedScrollPosition]) {
     self.isReconstructingFromCache = YES;
   }
 
@@ -1043,17 +1051,25 @@
 
 - (void)setupUIStackCacheIfApplicable {
   self.isReconstructingFromCache = NO;
-  BookmarkPathCache* pathCache =
-      bookmark_utils_ios::GetBookmarkUIPositionCache(self.bookmarks);
-  // If pathCache is nil or the cached folder is rootnode, then return.
-  if (!pathCache || pathCache.folderId == _rootNode->id()) {
+
+  int64_t folderId;
+  double scrollPosition;
+  // If folderId is invalid or rootNode reached the cached folderId, stop
+  // stacking and return.
+  if (![BookmarkPathCache
+          getBookmarkUIPositionCacheWithPrefService:self.browserState
+                                                        ->GetPrefs()
+                                              model:self.bookmarks
+                                           folderId:&folderId
+                                     scrollPosition:&scrollPosition] ||
+      folderId == _rootNode->id()) {
     return;
   }
 
   // Otherwise drill down until we recreate the UI stack for the cached bookmark
   // path.
   NSMutableArray* mutablePath = [bookmark_utils_ios::CreateBookmarkPath(
-      self.bookmarks, pathCache.folderId) mutableCopy];
+      self.bookmarks, folderId) mutableCopy];
   if (!mutablePath) {
     return;
   }
@@ -1075,9 +1091,9 @@
   BookmarkHomeViewController* controller =
       [self createControllerWithRootFolder:node];
   // Only scroll to the last viewing position for the leaf node.
-  if (mutablePath.count == 1 && pathCache.position) {
+  if (mutablePath.count == 1 && scrollPosition) {
     [controller
-        setCachedContentPosition:[NSNumber numberWithFloat:pathCache.position]];
+        setCachedContentPosition:[NSNumber numberWithDouble:scrollPosition]];
   }
   controller.isReconstructingFromCache = YES;
   [self.navigationController pushViewController:controller animated:NO];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
index 091ef97..fac3192 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
@@ -25,6 +25,7 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_mediator.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #include "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -181,11 +182,18 @@
 
   if (base::FeatureList::IsEnabled(kBookmarkNewGeneration)) {
     [self.bookmarkBrowser setRootNode:self.bookmarkModel->root_node()];
+    int64_t unusedFolderId;
+    double unusedScrollPosition;
     // If cache is present then reconstruct the last visited bookmark from
     // cache.  If bookmarkModel is not loaded yet, the following checking will
     // be done again at bookmarkModelLoaded in BookmarkHomeViewController to
     // prevent crbug.com/765503.
-    if (bookmark_utils_ios::GetBookmarkUIPositionCache(self.bookmarkModel)) {
+    if ([BookmarkPathCache
+            getBookmarkUIPositionCacheWithPrefService:_currentBrowserState
+                                                          ->GetPrefs()
+                                                model:self.bookmarkModel
+                                             folderId:&unusedFolderId
+                                       scrollPosition:&unusedScrollPosition]) {
       self.bookmarkBrowser.isReconstructingFromCache = YES;
     }
     FormSheetNavigationController* navController =
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h
index a99c843..1ff7931 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h
@@ -5,27 +5,41 @@
 #ifndef IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_PATH_CACHE_H_
 #define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_PATH_CACHE_H_
 
-#import <Foundation/Foundation.h>
 #import <UIKit/UIKit.h>
 
-// Caches the user's position in the bookmark hierarchy navigator, as well as
-// scroll position.
-@interface BookmarkPathCache : NSObject<NSCoding>
+namespace bookmarks {
+class BookmarkModel;
+}  // namespace bookmarks
 
-@property(nonatomic, assign, readonly) CGFloat position;
-@property(nonatomic, assign, readonly) int64_t folderId;
+namespace user_prefs {
+class PrefRegistrySyncable;
+}  // namespace user_prefs
 
-+ (BookmarkPathCache*)cacheForBookmarkFolder:(int64_t)folderId
-                                    position:(CGFloat)position;
+class PrefService;
 
-// This is not the designated initializer. It will return nil if there are
-// problems with the decoding process.
-- (instancetype)initWithCoder:(NSCoder*)coder;
-@end
+// Stores and retrieves the bookmark UI position that the user was last viewing.
+@interface BookmarkPathCache : NSObject
 
-@interface BookmarkPathCache (ExposedForTesting)
-- (instancetype)cacheForBookmarkFolder:(int64_t)folderId
-                              position:(CGFloat)position;
+// Registers the feature preferences.
++ (void)registerBrowserStatePrefs:(user_prefs::PrefRegistrySyncable*)registry;
+
+// Caches the bookmark UI position that the user was last viewing.
++ (void)cacheBookmarkUIPositionWithPrefService:(PrefService*)prefService
+                                      folderId:(int64_t)folderId
+                                scrollPosition:(double)scrollPosition;
+
+// Gets the bookmark UI position that the user was last viewing. Returns YES if
+// a valid cache exists. |folderId| and |scrollPosition| are out variables, only
+// populated if the return is YES.
++ (BOOL)getBookmarkUIPositionCacheWithPrefService:(PrefService*)prefService
+                                            model:
+                                                (bookmarks::BookmarkModel*)model
+                                         folderId:(int64_t*)folderId
+                                   scrollPosition:(double*)scrollPosition;
+
+// Clears the bookmark UI position cache.
++ (void)clearBookmarkUIPositionCacheWithPrefService:(PrefService*)prefService;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_PATH_CACHE_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.mm b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.mm
index 8914f8ff..6e2c6678 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache.mm
@@ -4,100 +4,69 @@
 
 #import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
 
-#include "base/logging.h"
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/bookmark_node.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
+#include "ios/chrome/browser/pref_names.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-namespace {
-// The current version of the cached position. This number should be incremented
-// each time the NSCoding implementation changes.
-const int kVersion = 1;
+using bookmarks::BookmarkModel;
+using bookmarks::BookmarkNode;
 
-NSString* kBookmarkFolderIdKey = @"BookmarkFolderIdKey";
-NSString* kPositionKey = @"PositionKey";
-NSString* kVersionKey = @"VersionKey";
+namespace {
+const int64_t kFolderNone = -1;
 }  // namespace
 
-@interface BookmarkPathCache ()
-
-// This is the designated initializer. It does not perform any validation.
-- (instancetype)initWithBookmarkFolder:(int64_t)folderId
-                              position:(CGFloat)position
-    NS_DESIGNATED_INITIALIZER;
-
-- (instancetype)init NS_UNAVAILABLE;
-
-@end
-
 @implementation BookmarkPathCache
-@synthesize position = _position;
-@synthesize folderId = _folderId;
-
-#pragma mark - Public Constructors
-
-+ (BookmarkPathCache*)cacheForBookmarkFolder:(int64_t)folderId
-                                    position:(CGFloat)position {
-  return [[BookmarkPathCache alloc] initWithBookmarkFolder:folderId
-                                                  position:position];
+// Registers the feature preferences.
++ (void)registerBrowserStatePrefs:(user_prefs::PrefRegistrySyncable*)registry {
+  registry->RegisterInt64Pref(prefs::kIosBookmarkCachedFolderId, kFolderNone);
+  registry->RegisterDoublePref(prefs::kIosBookmarkCachedScrollPosition, 0);
 }
 
-#pragma mark - Designated Initializer
-
-- (instancetype)initWithBookmarkFolder:(int64_t)folderId
-                              position:(CGFloat)position {
-  self = [super init];
-  if (self) {
-    _folderId = folderId;
-    _position = position;
-  }
-  return self;
+// Caches the bookmark UI position that the user was last viewing.
++ (void)cacheBookmarkUIPositionWithPrefService:(PrefService*)prefService
+                                      folderId:(int64_t)folderId
+                                scrollPosition:(double)scrollPosition {
+  prefService->SetInt64(prefs::kIosBookmarkCachedFolderId, folderId);
+  prefService->SetDouble(prefs::kIosBookmarkCachedScrollPosition,
+                         scrollPosition);
 }
 
-#pragma mark - Superclass Overrides
+// Gets the bookmark UI position that the user was last viewing. Returns YES if
+// a valid cache exists. |folderId| and |scrollPosition| are out variables, only
+// populated if the return is YES.
++ (BOOL)getBookmarkUIPositionCacheWithPrefService:(PrefService*)prefService
+                                            model:
+                                                (bookmarks::BookmarkModel*)model
+                                         folderId:(int64_t*)folderId
+                                   scrollPosition:(double*)scrollPosition {
+  *folderId = prefService->GetInt64(prefs::kIosBookmarkCachedFolderId);
 
-- (instancetype)init {
-  NOTREACHED();
-  return nil;
-}
-
-- (BOOL)isEqual:(id)object {
-  if (self == object)
-    return YES;
-  if (![object isKindOfClass:[BookmarkPathCache class]])
-    return NO;
-  BookmarkPathCache* other = static_cast<BookmarkPathCache*>(object);
-  if (fabs(self.position - other.position) > 0.01)
-    return NO;
-  if (self.folderId != other.folderId)
+  // If the cache was at root node, consider it as nothing was cached.
+  if (*folderId == kFolderNone || *folderId == model->root_node()->id())
     return NO;
 
+  // Create bookmark Path.
+  const BookmarkNode* bookmark =
+      bookmark_utils_ios::FindFolderById(model, *folderId);
+  // The bookmark node is gone from model, maybe deleted remotely.
+  if (!bookmark)
+    return NO;
+
+  *scrollPosition =
+      prefService->GetDouble(prefs::kIosBookmarkCachedScrollPosition);
   return YES;
 }
 
-- (NSUInteger)hash {
-  return static_cast<NSUInteger>(self.folderId) ^
-         static_cast<NSUInteger>(self.position);
-}
-
-#pragma mark - NSCoding
-
-- (instancetype)initWithCoder:(NSCoder*)coder {
-  int version = [coder decodeIntForKey:kVersionKey];
-  if (version != kVersion) {
-    return nil;
-  }
-
-  return [self
-      initWithBookmarkFolder:[coder decodeInt64ForKey:kBookmarkFolderIdKey]
-                    position:[coder decodeFloatForKey:kPositionKey]];
-}
-
-- (void)encodeWithCoder:(NSCoder*)coder {
-  [coder encodeInt:kVersion forKey:kVersionKey];
-  [coder encodeFloat:self.position forKey:kPositionKey];
-  [coder encodeInt64:self.folderId forKey:kBookmarkFolderIdKey];
+// Clears the bookmark UI position cache.
++ (void)clearBookmarkUIPositionCacheWithPrefService:(PrefService*)prefService {
+  prefService->SetInt64(prefs::kIosBookmarkCachedFolderId, kFolderNone);
 }
 
 @end
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm
index 478e4d1..39d7e46 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_path_cache_unittest.mm
@@ -3,6 +3,10 @@
 // found in the LICENSE file.
 
 #include "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
+
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -11,16 +15,61 @@
 #error "This file requires ARC support."
 #endif
 
+using bookmarks::BookmarkNode;
+
 namespace {
 
-using BookmarkPathCacheTest = PlatformTest;
+class BookmarkPathCacheTest : public BookmarkIOSUnitTest {
+ protected:
+  void SetUp() override {
+    BookmarkIOSUnitTest::SetUp();
+    [BookmarkPathCache registerBrowserStatePrefs:prefs_.registry()];
+  }
 
-TEST_F(BookmarkPathCacheTest, TestEquality) {
-  BookmarkPathCache* cache =
-      [BookmarkPathCache cacheForBookmarkFolder:57 position:200];
+  sync_preferences::TestingPrefServiceSyncable prefs_;
+};
 
-  NSData* data = [NSKeyedArchiver archivedDataWithRootObject:cache];
-  BookmarkPathCache* cache2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
-  EXPECT_NSEQ(cache, cache2);
+TEST_F(BookmarkPathCacheTest, TestPathCache) {
+  // Try to store and retrieve a cache.
+  const BookmarkNode* mobileNode = _bookmarkModel->mobile_node();
+  const BookmarkNode* f1 = AddFolder(mobileNode, @"f1");
+  int64_t folderId = f1->id();
+  double position = 23;
+  [BookmarkPathCache cacheBookmarkUIPositionWithPrefService:&prefs_
+                                                   folderId:folderId
+                                             scrollPosition:position];
+
+  int64_t resultFolderId;
+  double resultPosition;
+  [BookmarkPathCache getBookmarkUIPositionCacheWithPrefService:&prefs_
+                                                         model:_bookmarkModel
+                                                      folderId:&resultFolderId
+                                                scrollPosition:&resultPosition];
+  EXPECT_EQ(folderId, resultFolderId);
+  EXPECT_EQ(position, resultPosition);
 }
+
+TEST_F(BookmarkPathCacheTest, TestPathCacheWhenFolderDeleted) {
+  // Try to store and retrieve a cache after the cached path is deleted.
+  const BookmarkNode* mobileNode = _bookmarkModel->mobile_node();
+  const BookmarkNode* f1 = AddFolder(mobileNode, @"f1");
+  int64_t folderId = f1->id();
+  double position = 23;
+  [BookmarkPathCache cacheBookmarkUIPositionWithPrefService:&prefs_
+                                                   folderId:folderId
+                                             scrollPosition:position];
+
+  // Delete the folder.
+  _bookmarkModel->Remove(f1);
+
+  int64_t unusedFolderId;
+  double unusedPosition;
+  BOOL result = [BookmarkPathCache
+      getBookmarkUIPositionCacheWithPrefService:&prefs_
+                                          model:_bookmarkModel
+                                       folderId:&unusedFolderId
+                                 scrollPosition:&unusedPosition];
+  ASSERT_FALSE(result);
+}
+
 }  // anonymous namespace
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
index 9786a1e0..c3a7bd4e 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
@@ -193,30 +193,29 @@
 #pragma mark - Cache position in collection view.
 
 // Caches the active menu item, and the position in the collection view.
+// TODO(crbug.com/753599): This function is used in old bookmarks only.  Remove
+// it when cleanup old bookmarks.
 void CachePosition(CGFloat position, BookmarkMenuItem* item);
+
 // Returns YES if a valid cache exists.
 // |model| must be loaded.
 // |item| and |position| are out variables, only populated if the return is YES.
+// TODO(crbug.com/753599): This function is used in old bookmarks only.  Remove
+// it when cleanup old bookmarks.
 BOOL GetPositionCache(bookmarks::BookmarkModel* model,
                       BookmarkMenuItem* __autoreleasing* item,
                       CGFloat* position);
+
 // Method exists for testing.
+// TODO(crbug.com/753599): This function is used in old bookmarks only.  Remove
+// it when cleanup old bookmarks.
 void ClearPositionCache();
 
-// Caches the bookmark UI position that the user was last viewing.
-void CacheBookmarkUIPosition(BookmarkPathCache* cache);
-
-// Returns the bookmark UI position that the user was last viewing.
-BookmarkPathCache* GetBookmarkUIPositionCache(bookmarks::BookmarkModel* model);
-
 // Creates bookmark path for |folderId| passed in. For eg: for folderId = 76,
 // Root node(0) --> MobileBookmarks (3) --> Test1(76) will be returned as [0, 3,
 // 76].
 NSArray* CreateBookmarkPath(bookmarks::BookmarkModel* model, int64_t folderId);
 
-// Clears the bookmark UI position cache.
-void ClearBookmarkUIPositionCache();
-
 }  // namespace bookmark_utils_ios
 
 #endif  // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_UTILS_IOS_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
index 57d8c0a..25cd0bc 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -23,7 +23,6 @@
 #include "ios/chrome/browser/experimental_flags.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h"
-#import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_position_cache.h"
 #include "ios/chrome/browser/ui/bookmarks/undo_manager_wrapper.h"
 #include "ios/chrome/browser/ui/ui_util.h"
@@ -64,8 +63,8 @@
 const CGFloat titleMargin = 73;
 const CGFloat titleToIconDistance = 33;
 const CGFloat menuAnimationDuration = 0.2;
+// TODO(crbug.com/753599): Remove kPositionCacheKey when cleanup old bookmarks.
 NSString* const kPositionCacheKey = @"BookmarksStarsPositionCacheKey";
-NSString* const kUIPositionCacheKey = @"BookmarksUIPositionCacheKey";
 NSString* const kBookmarksSnackbarCategory = @"BookmarksSnackbarCategory";
 
 const BookmarkNode* FindFolderById(bookmarks::BookmarkModel* model,
@@ -657,6 +656,8 @@
 
 #pragma mark - Cache position in collection view.
 
+// TODO(crbug.com/753599): This function is used in old bookmarks only.  Remove
+// it when cleanup old bookmarks.
 void CachePosition(CGFloat position, BookmarkMenuItem* item) {
   BookmarkPositionCache* cache = nil;
   switch (item.type) {
@@ -677,34 +678,6 @@
                                             forKey:kPositionCacheKey];
 }
 
-void CacheBookmarkUIPosition(BookmarkPathCache* cache) {
-  NSData* data = [NSKeyedArchiver archivedDataWithRootObject:cache];
-  [[NSUserDefaults standardUserDefaults] setObject:data
-                                            forKey:kUIPositionCacheKey];
-}
-
-BookmarkPathCache* GetBookmarkUIPositionCache(bookmarks::BookmarkModel* model) {
-  NSData* data =
-      [[NSUserDefaults standardUserDefaults] objectForKey:kUIPositionCacheKey];
-  if (!data || ![data isKindOfClass:[NSData class]])
-    return nil;
-  BookmarkPathCache* cache = [NSKeyedUnarchiver unarchiveObjectWithData:data];
-  if (!cache)
-    return nil;
-
-  // If the cache was at root node, consider it as nothing was cached.
-  if (cache.folderId == model->root_node()->id())
-    return nil;
-
-  // Create bookmark Path.
-  const BookmarkNode* bookmark = FindFolderById(model, cache.folderId);
-  // The bookmark node is gone from model, maybe deleted remotely.
-  if (!bookmark)
-    return nil;
-
-  return cache;
-}
-
 NSArray* CreateBookmarkPath(bookmarks::BookmarkModel* model, int64_t folderId) {
   // Create an array with root node id, if folderId == root node.
   if (model->root_node()->id() == folderId) {
@@ -725,6 +698,8 @@
   return [[bookmarkPath reverseObjectEnumerator] allObjects];
 }
 
+// TODO(crbug.com/753599): This function is used in old bookmarks only.  Remove
+// it when cleanup old bookmarks.
 BOOL GetPositionCache(bookmarks::BookmarkModel* model,
                       BookmarkMenuItem** item,
                       CGFloat* position) {
@@ -764,12 +739,10 @@
   return YES;
 }
 
+// TODO(crbug.com/753599): This function is used in old bookmarks only.  Remove
+// it when cleanup old bookmarks.
 void ClearPositionCache() {
   [[NSUserDefaults standardUserDefaults] removeObjectForKey:kPositionCacheKey];
 }
 
-void ClearBookmarkUIPositionCache() {
-  [[NSUserDefaults standardUserDefaults]
-      removeObjectForKey:kUIPositionCacheKey];
-}
 }  // namespace bookmark_utils_ios
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
index 9d60d69f..7216b218 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
@@ -14,7 +14,6 @@
 #include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h"
-#import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
 #include "testing/gtest_mac.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -36,10 +35,12 @@
 
   void SetUp() override {
     BookmarkIOSUnitTest::SetUp();
+    // TODO(crbug.com/753599): Remove following line when cleanup old bookmarks.
     bookmark_utils_ios::ClearPositionCache();
   }
 
   void TearDown() override {
+    // TODO(crbug.com/753599): Remove following line when cleanup old bookmarks.
     bookmark_utils_ios::ClearPositionCache();
     BookmarkIOSUnitTest::TearDown();
   }
@@ -183,6 +184,7 @@
   EXPECT_EQ(folder, f2);
 }
 
+// TODO(crbug.com/753599): Remove this test when cleanup old bookmarks.
 TEST_F(BookmarkIOSUtilsUnitTest, TestPositionCache) {
   // Try to store and retrieve a cache for the folderMenuItem.
   const BookmarkNode* mobileNode = _bookmarkModel->mobile_node();
@@ -202,33 +204,6 @@
   EXPECT_EQ(bookmarks::MenuItemFolder, outItem.type);
 }
 
-TEST_F(BookmarkIOSUtilsUnitTest, TestPathCache) {
-  // Try to store and retrieve a cache for the folderMenuItem.
-  const BookmarkNode* mobileNode = _bookmarkModel->mobile_node();
-  const BookmarkNode* f1 = AddFolder(mobileNode, @"f1");
-  CGFloat position = 23;
-  BookmarkPathCache* cache =
-      [BookmarkPathCache cacheForBookmarkFolder:f1->id() position:position];
-  bookmark_utils_ios::CacheBookmarkUIPosition(cache);
-  BookmarkPathCache* resultCache =
-      bookmark_utils_ios::GetBookmarkUIPositionCache(_bookmarkModel);
-  EXPECT_NSEQ(cache, resultCache);
-}
-
-TEST_F(BookmarkIOSUtilsUnitTest, TestNilPathCache) {
-  // Try to store and retrieve a cache for the folderMenuItem.
-  const BookmarkNode* mobileNode = _bookmarkModel->mobile_node();
-  const BookmarkNode* f1 = AddFolder(mobileNode, @"f1");
-  CGFloat position = 23;
-  BookmarkPathCache* cache =
-      [BookmarkPathCache cacheForBookmarkFolder:f1->id() position:position];
-  bookmark_utils_ios::CacheBookmarkUIPosition(cache);
-  _bookmarkModel->Remove(f1);
-  BookmarkPathCache* resultCache =
-      bookmark_utils_ios::GetBookmarkUIPositionCache(_bookmarkModel);
-  EXPECT_TRUE(resultCache == nil);
-}
-
 TEST_F(BookmarkIOSUtilsUnitTest, TestCreateBookmarkPath) {
   const BookmarkNode* mobileNode = _bookmarkModel->mobile_node();
   const BookmarkNode* f1 = AddFolder(mobileNode, @"f1");
@@ -246,6 +221,7 @@
   EXPECT_TRUE(path == nil);
 }
 
+// TODO(crbug.com/753599): Remove this test when cleanup old bookmarks.
 TEST_F(BookmarkIOSUtilsUnitTest, TestBookmarkModelChangesPositionCache) {
   // Try to store and retrieve a cache for the folderMenuItem
   const BookmarkNode* mobileNode = _bookmarkModel->mobile_node();
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 0993d7e..642a328 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmarks_new_generation_egtest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmarks_new_generation_egtest.mm
@@ -20,6 +20,7 @@
 #include "ios/chrome/browser/pref_names.h"
 #import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h"
 #import "ios/chrome/browser/ui/authentication/signin_promo_view.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -143,7 +144,10 @@
              @"Not all bookmarks were removed.");
   // Clear position cache so that Bookmarks starts at the root folder in next
   // test.
-  bookmark_utils_ios::ClearBookmarkUIPositionCache();
+  ios::ChromeBrowserState* browser_state =
+      chrome_test_util::GetOriginalBrowserState();
+  [BookmarkPathCache
+      clearBookmarkUIPositionCacheWithPrefService:browser_state->GetPrefs()];
 }
 
 #pragma mark - Tests
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 30772dab..2ade742 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -213,6 +213,7 @@
 #import "ios/chrome/browser/web/blocked_popup_tab_helper.h"
 #import "ios/chrome/browser/web/error_page_content.h"
 #import "ios/chrome/browser/web/load_timing_tab_helper.h"
+#import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #import "ios/chrome/browser/web/passkit_dialog_provider.h"
 #include "ios/chrome/browser/web/print_tab_helper.h"
 #import "ios/chrome/browser/web/repost_form_tab_helper.h"
@@ -1086,8 +1087,10 @@
     Tab* currentTab = [_model currentTab];
     // Force loading the view in case it was not loaded yet.
     [self loadViewIfNeeded];
-    if (_expectingForegroundTab)
-      [currentTab.webController setOverlayPreviewMode:YES];
+    if (_expectingForegroundTab) {
+      PagePlaceholderTabHelper::FromWebState(currentTab.webState)
+          ->AddPlaceholderForNextNavigation();
+    }
     if (currentTab)
       [self displayTab:currentTab isNewSelection:YES];
   } else {
@@ -1596,10 +1599,9 @@
 }
 
 - (BOOL)shouldAutorotate {
-  if (_voiceSearchController && _voiceSearchController->IsVisible()) {
-    // Don't rotate if a voice search is being presented or dismissed.  Once the
-    // transition animations finish, only the Voice Search UIViewController's
-    // |-shouldAutorotate| will be called.
+  if (self.presentedViewController.beingPresented ||
+      self.presentedViewController.beingDismissed) {
+    // Don't rotate while a presentation or dismissal animation is occurring.
     return NO;
   } else if (_sideSwipeController && ![_sideSwipeController shouldAutorotate]) {
     // Don't auto rotate if side swipe controller view says not to.
@@ -2736,7 +2738,8 @@
     // tabs (since doing so is a no-op for the tabs that don't have it set).
     _expectingForegroundTab = NO;
     for (Tab* tab in _model) {
-      [tab.webController setOverlayPreviewMode:NO];
+      PagePlaceholderTabHelper::FromWebState(tab.webState)
+          ->CancelPlaceholderForNextNavigation();
     }
   }
 }
@@ -5156,21 +5159,9 @@
     _infoBarContainer->ChangeInfoBarManager(infoBarManager);
   }
 
-  if (self.active && model.currentTab == newTab) {
-    // Add |newTab|'s view to the hierarchy if it's the current Tab.
+  // Add |newTab|'s view to the hierarchy if it's the current Tab.
+  if (self.active && model.currentTab == newTab)
     [self displayTab:newTab isNewSelection:NO];
-    // Reset the temporary native controller since the current tab is replaced.
-    _temporaryNativeController = nil;
-    // If this is occurring for an inserted prerender tab, update its content
-    // offset so that it's below the toolbar.
-    if (_insertedTabWasPrerenderedTab) {
-      CRWWebViewProxyType webViewProxy = newTab.webState->GetWebViewProxy();
-      CRWWebViewScrollViewProxy* scrollProxy = webViewProxy.scrollViewProxy;
-      CGFloat toolbarHeight = [self toolbarHeight];
-      scrollProxy.contentOffset = CGPointMake(0, -toolbarHeight);
-      webViewProxy.topContentPadding = toolbarHeight;
-    }
-  }
 
   if (newTab)
     [_paymentRequestManager setActiveWebState:newTab.webState];
diff --git a/ios/chrome/browser/ui/fullscreen/BUILD.gn b/ios/chrome/browser/ui/fullscreen/BUILD.gn
index 8186228..eea00f6 100644
--- a/ios/chrome/browser/ui/fullscreen/BUILD.gn
+++ b/ios/chrome/browser/ui/fullscreen/BUILD.gn
@@ -65,10 +65,14 @@
     "fullscreen_model.mm",
     "fullscreen_model_observer.h",
     "fullscreen_ui_updater.mm",
+    "fullscreen_web_scroll_view_replacement_handler.h",
+    "fullscreen_web_scroll_view_replacement_handler.mm",
     "fullscreen_web_state_list_observer.h",
     "fullscreen_web_state_list_observer.mm",
     "fullscreen_web_state_observer.h",
     "fullscreen_web_state_observer.mm",
+    "fullscreen_web_view_scroll_view_replacement_util.h",
+    "fullscreen_web_view_scroll_view_replacement_util.mm",
     "system_notification_fullscreen_disabler.h",
     "system_notification_fullscreen_disabler.mm",
   ]
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.h b/ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.h
new file mode 100644
index 0000000..7d97254
--- /dev/null
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.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 IOS_CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_WEB_SCROLL_VIEW_REPLACEMENT_HANDLER_H_
+#define IOS_CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_WEB_SCROLL_VIEW_REPLACEMENT_HANDLER_H_
+
+#import <Foundation/Foundation.h>
+
+@protocol CRWWebViewProxy;
+class FullscreenModel;
+
+// Helper object that listens for scroll view replacements on the web view proxy
+// and updates the content offset of the new scroll view so that its content is
+// below the toolbar.
+@interface FullscreenWebScrollViewReplacementHandler : NSObject
+
+// The proxy being observed.
+@property(nonatomic, weak, nullable) id<CRWWebViewProxy> proxy;
+
+// Designated initializer for an observer that uses |model| to update its proxy.
+- (nullable instancetype)initWithModel:(nonnull FullscreenModel*)model
+    NS_DESIGNATED_INITIALIZER;
+- (nullable instancetype)init NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_WEB_SCROLL_VIEW_REPLACEMENT_HANDLER_H_
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.mm
new file mode 100644
index 0000000..4b5e633
--- /dev/null
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.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.
+
+#import "ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.h"
+
+#include "base/logging.h"
+#import "ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.h"
+#import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
+#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface FullscreenWebScrollViewReplacementHandler ()<
+    CRWWebViewScrollViewProxyObserver>
+// The model passed on initialization.
+@property(nonatomic, assign) FullscreenModel* model;
+@end
+
+@implementation FullscreenWebScrollViewReplacementHandler
+@synthesize proxy = _proxy;
+@synthesize model = _model;
+
+- (instancetype)initWithModel:(FullscreenModel*)model {
+  if (self = [super init]) {
+    _model = model;
+    DCHECK(_model);
+  }
+  return self;
+}
+
+#pragma mark - Accessors
+
+- (void)setProxy:(id<CRWWebViewProxy>)proxy {
+  if (_proxy == proxy)
+    return;
+  [_proxy.scrollViewProxy removeObserver:self];
+  _proxy = proxy;
+  [_proxy.scrollViewProxy addObserver:self];
+}
+
+#pragma mark - CRWWebViewScrollViewProxyObserver
+
+- (void)webViewScrollViewProxyDidSetScrollView:
+    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
+  UpdateFullscreenWebViewProxyForReplacedScrollView(self.proxy, self.model);
+}
+
+@end
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.mm
index 95f1820..01eefab 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.mm
@@ -6,7 +6,9 @@
 
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_model.h"
+#import "ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/web/public/web_state/web_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -45,6 +47,10 @@
     // Reset the model if the active WebState is replaced.
     web_state_observer_.SetWebState(new_web_state);
     model_->ResetForNavigation();
+    if (new_web_state) {
+      UpdateFullscreenWebViewProxyForReplacedScrollView(
+          new_web_state->GetWebViewProxy(), model_);
+    }
   }
 }
 
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h
index 78a6fcb..0f27ac8 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h
@@ -11,6 +11,7 @@
 
 class FullscreenController;
 class FullscreenModel;
+@class FullscreenWebScrollViewReplacementHandler;
 class ScopedFullscreenDisabler;
 
 // A WebStateObserver that updates a FullscreenModel for navigation events.
@@ -43,6 +44,9 @@
   FullscreenController* controller_;
   // The model passed on construction.
   FullscreenModel* model_;
+  // Observer for |web_state_|'s scroll view proxy.
+  __strong FullscreenWebScrollViewReplacementHandler*
+      scroll_view_replacement_handler_;
   // The disabler for broken SSL.
   std::unique_ptr<ScopedFullscreenDisabler> ssl_disabler_;
   // The disabler for loading.
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm
index 5f16be93..23b6056 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_model.h"
+#import "ios/chrome/browser/ui/fullscreen/fullscreen_web_scroll_view_replacement_handler.h"
 #import "ios/chrome/browser/ui/fullscreen/scoped_fullscreen_disabler.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
@@ -36,7 +37,11 @@
 FullscreenWebStateObserver::FullscreenWebStateObserver(
     FullscreenController* controller,
     FullscreenModel* model)
-    : controller_(controller), model_(model) {
+    : controller_(controller),
+      model_(model),
+      scroll_view_replacement_handler_(
+          [[FullscreenWebScrollViewReplacementHandler alloc]
+              initWithModel:model_]) {
   DCHECK(controller_);
   DCHECK(model_);
 }
@@ -52,8 +57,11 @@
   if (web_state_)
     web_state_->AddObserver(this);
   // Update the model according to the new WebState.
-  SetIsLoading(web_state ? web_state->IsLoading() : false);
-  SetIsSSLBroken(web_state ? IsWebStateSSLBroken(web_state) : false);
+  SetIsLoading(web_state_ ? web_state->IsLoading() : false);
+  SetIsSSLBroken(web_state_ ? IsWebStateSSLBroken(web_state_) : false);
+  // Update the scroll view replacement handler's proxy.
+  scroll_view_replacement_handler_.proxy =
+      web_state_ ? web_state_->GetWebViewProxy() : nil;
 }
 
 void FullscreenWebStateObserver::DidFinishNavigation(
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.h b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.h
new file mode 100644
index 0000000..d385d8d
--- /dev/null
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.h
@@ -0,0 +1,19 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_WEB_VIEW_SCROLL_VIEW_REPLACEMENT_UTIL_H_
+#define IOS_CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_WEB_VIEW_SCROLL_VIEW_REPLACEMENT_UTIL_H_
+
+#import <Foundation/Foundation.h>
+
+@protocol CRWWebViewProxy;
+class FullscreenModel;
+
+// Updates |proxy|'s content offset and top padding to ensure that the content
+// is fully visible under the toolbar when its scroll view is replaced.
+void UpdateFullscreenWebViewProxyForReplacedScrollView(
+    id<CRWWebViewProxy> proxy,
+    FullscreenModel* model);
+
+#endif  // IOS_CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_WEB_VIEW_SCROLL_VIEW_REPLACEMENT_UTIL_H_
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.mm
new file mode 100644
index 0000000..dbe01d90
--- /dev/null
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.mm
@@ -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.
+
+#import "ios/chrome/browser/ui/fullscreen/fullscreen_web_view_scroll_view_replacement_util.h"
+
+#include "base/logging.h"
+#import "ios/chrome/browser/ui/fullscreen/fullscreen_model.h"
+#import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
+#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+void UpdateFullscreenWebViewProxyForReplacedScrollView(
+    id<CRWWebViewProxy> proxy,
+    FullscreenModel* model) {
+  DCHECK(proxy);
+  DCHECK(model);
+  CGFloat padding = model->progress() * model->GetToolbarHeight();
+  proxy.scrollViewProxy.contentOffset = CGPointMake(0, -padding);
+  proxy.topContentPadding = padding;
+}
diff --git a/ios/chrome/browser/ui/side_swipe/DEPS b/ios/chrome/browser/ui/side_swipe/DEPS
index ff99d1a..f363547 100644
--- a/ios/chrome/browser/ui/side_swipe/DEPS
+++ b/ios/chrome/browser/ui/side_swipe/DEPS
@@ -8,7 +8,4 @@
   "^card_side_swipe_view\.mm$": [
     "+ios/web/web_state/ui/crw_web_controller.h",
   ],
-  "^side_swipe_controller\.mm$": [
-    "+ios/web/web_state/ui/crw_web_controller.h",
-  ],
 }
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
index 20a2a93..d48d14c5 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
@@ -33,7 +33,6 @@
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.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."
@@ -285,16 +284,10 @@
   }
   [SnapshotCacheFactory::GetForBrowserState(browserState_)
       createGreyCache:sessionIDs];
-  for (Tab* tab in model_) {
-    tab.useGreyImageCache = YES;
-  }
 }
 
 - (void)deleteGreyCache {
   [SnapshotCacheFactory::GetForBrowserState(browserState_) removeGreyCache];
-  for (Tab* tab in model_) {
-    tab.useGreyImageCache = NO;
-  }
 }
 
 - (void)handlePan:(SideSwipeGestureRecognizer*)gesture {
@@ -376,19 +369,24 @@
       if (newIndex != currentIndex) {
         Tab* tab = [model_ tabAtIndex:newIndex];
         // Toggle overlay preview mode for selected tab.
-        [tab.webController setOverlayPreviewMode:YES];
+        PagePlaceholderTabHelper::FromWebState(tab.webState)
+            ->AddPlaceholderForNextNavigation();
         [model_ setCurrentTab:tab];
+
         // And disable overlay preview mode for last selected tab.
-        [currentTab.webController setOverlayPreviewMode:NO];
+        PagePlaceholderTabHelper::FromWebState(currentTab.webState)
+            ->CancelPlaceholderForNextNavigation();
       }
     }
   } else {
     if (gesture.state == UIGestureRecognizerStateCancelled) {
       Tab* tab = [model_ tabAtIndex:startingTabIndex_];
-      [[model_ currentTab].webController setOverlayPreviewMode:NO];
+      PagePlaceholderTabHelper::FromWebState(tab.webState)
+          ->CancelPlaceholderForNextNavigation();
       [model_ setCurrentTab:tab];
     }
-    [[model_ currentTab].webController setOverlayPreviewMode:NO];
+    PagePlaceholderTabHelper::FromWebState([model_ currentTab].webState)
+        ->CancelPlaceholderForNextNavigation();
 
     // Redisplay the view if it was in overlay preview mode.
     [swipeDelegate_ displayTab:[model_ currentTab] isNewSelection:YES];
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
index c29d246..948bfed7 100644
--- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
+++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
@@ -174,8 +174,7 @@
 
 // Tests that switching from a managed account to a non-managed account works
 // correctly and displays the expected warnings.
-// TODO(crbug.com/796842): Reenable this test.
-- (void)DISABLED_testSignInSwitchManagedAccount {
+- (void)testSignInSwitchManagedAccount {
   // Set up the fake identities.
   ios::FakeChromeIdentityService* identity_service =
       ios::FakeChromeIdentityService::GetInstanceFromChromeProvider();
@@ -255,8 +254,7 @@
 
 // Tests that signing out of a managed account from the Settings works
 // correctly.
-// TODO(crbug.com/796842): Reenable this test.
-- (void)DISABLED_testSignInDisconnectFromChromeManaged {
+- (void)testSignInDisconnectFromChromeManaged {
   ChromeIdentity* identity = [SigninEarlGreyUtils fakeManagedIdentity];
   ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
       identity);
@@ -403,8 +401,7 @@
 // Starts an authentication flow and cancel it by opening a new tab. Ensures
 // that the authentication flow is correctly canceled and dismissed.
 // crbug.com/462202
-// TODO(crbug.com/796842): Reenable this test.
-- (void)DISABLED_testSignInCancelAuthenticationFlow {
+- (void)testSignInCancelAuthenticationFlow {
   // Set up the fake identities.
   ios::FakeChromeIdentityService* identity_service =
       ios::FakeChromeIdentityService::GetInstanceFromChromeProvider();
diff --git a/ios/chrome/browser/ui/tab_switcher/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/BUILD.gn
index a8b863e1..b50cfdf 100644
--- a/ios/chrome/browser/ui/tab_switcher/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/BUILD.gn
@@ -87,6 +87,7 @@
     "//ios/chrome/browser/ui/signin_interaction/public",
     "//ios/chrome/browser/ui/tabs/requirements",
     "//ios/chrome/browser/ui/toolbar:toolbar_ui",
+    "//ios/chrome/browser/web",
     "//ios/chrome/browser/web_state_list",
     "//ios/chrome/common:ios_app_bundle_id_prefix_header",
     "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.mm
index a63d4e5..fc575ce 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/browser/tabs/tab.h"
 #import "ios/chrome/browser/tabs/tab_model.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
+#import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #include "ios/chrome/common/ios_app_bundle_id_prefix.h"
 #include "ios/web/public/navigation_item.h"
 #import "ios/web/public/web_state/web_state.h"
@@ -91,13 +92,16 @@
   UIImage* snapshot = [_cache objectForKey:[self keyForTab:tab]];
   if (snapshot && [snapshot size].width >= size.width) {
     // If tab is not in a state to take a snapshot, use the cached snapshot.
-    if (!tab.webState || !tab.webState->CanTakeSnapshot()) {
+    if (!tab.webState || !tab.webState->IsWebUsageEnabled() ||
+        PagePlaceholderTabHelper::FromWebState(tab.webState)
+            ->displaying_placeholder()) {
       completionBlock(snapshot);
       return currentRequest;
     }
 
-    CGRect tabContentArea = UIEdgeInsetsInsetRect(
-        [tab.webState->GetView() bounds], [tab snapshotEdgeInsets]);
+    CGRect tabContentArea =
+        UIEdgeInsetsInsetRect([tab.webState->GetView() bounds],
+                              [tab snapshotEdgeInsetsForWebState:tab.webState]);
     CGFloat tabContentAreaRatio =
         tabContentArea.size.width / tabContentArea.size.height;
     CGFloat cachedSnapshotRatio =
diff --git a/ios/chrome/browser/web/page_placeholder_tab_helper.h b/ios/chrome/browser/web/page_placeholder_tab_helper.h
index f0aa304..67515c9 100644
--- a/ios/chrome/browser/web/page_placeholder_tab_helper.h
+++ b/ios/chrome/browser/web/page_placeholder_tab_helper.h
@@ -29,9 +29,16 @@
   // will be removed before navigation is finished.
   void AddPlaceholderForNextNavigation();
 
+  // Cancels displaying placeholder during the next navigation. If placeholder
+  // is displayed, then it is removed.
+  void CancelPlaceholderForNextNavigation();
+
+  // true if placeholder is currently being displayed.
+  bool displaying_placeholder() const { return displaying_placeholder_; }
+
   // true if placeholder will be displayed between DidStartNavigation and
   // PageLoaded WebStateObserver callbacks.
-  bool will_add_placeholder_for_next_navigation() {
+  bool will_add_placeholder_for_next_navigation() const {
     return add_placeholder_for_next_navigation_;
   }
 
@@ -57,6 +64,7 @@
   // true if placeholder is currently being displayed.
   bool displaying_placeholder_ = false;
 
+  // true if placeholder must be displayed during the next navigation.
   bool add_placeholder_for_next_navigation_ = false;
 
   base::WeakPtrFactory<PagePlaceholderTabHelper> weak_factory_;
diff --git a/ios/chrome/browser/web/page_placeholder_tab_helper.mm b/ios/chrome/browser/web/page_placeholder_tab_helper.mm
index 22b9163..bc0f3f02 100644
--- a/ios/chrome/browser/web/page_placeholder_tab_helper.mm
+++ b/ios/chrome/browser/web/page_placeholder_tab_helper.mm
@@ -12,7 +12,7 @@
 #endif
 
 // Placeholder will not be displayed longer than this time.
-const double kPlaceholderMaxDisplayTimeInSecounds = 1.5;
+const double kPlaceholderMaxDisplayTimeInSeconds = 1.5;
 
 DEFINE_WEB_STATE_USER_DATA_KEY(PagePlaceholderTabHelper);
 
@@ -43,6 +43,13 @@
   add_placeholder_for_next_navigation_ = true;
 }
 
+void PagePlaceholderTabHelper::CancelPlaceholderForNextNavigation() {
+  add_placeholder_for_next_navigation_ = false;
+  if (displaying_placeholder_) {
+    RemovePlaceholder();
+  }
+}
+
 void PagePlaceholderTabHelper::DidStartNavigation(
     web::WebState* web_state,
     web::NavigationContext* navigation_context) {
@@ -74,7 +81,7 @@
       FROM_HERE,
       base::Bind(&PagePlaceholderTabHelper::RemovePlaceholder,
                  weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromSecondsD(kPlaceholderMaxDisplayTimeInSecounds));
+      base::TimeDelta::FromSecondsD(kPlaceholderMaxDisplayTimeInSeconds));
 }
 
 void PagePlaceholderTabHelper::RemovePlaceholder() {
diff --git a/ios/chrome/browser/web/page_placeholder_tab_helper_unittest.mm b/ios/chrome/browser/web/page_placeholder_tab_helper_unittest.mm
index f6a0533..fd5be1b 100644
--- a/ios/chrome/browser/web/page_placeholder_tab_helper_unittest.mm
+++ b/ios/chrome/browser/web/page_placeholder_tab_helper_unittest.mm
@@ -8,13 +8,11 @@
 
 #include <memory>
 
-#include "base/mac/foundation_util.h"
-#include "base/memory/ptr_util.h"
-#include "base/test/ios/wait_util.h"
+#include "base/test/scoped_task_environment.h"
 #import "ios/chrome/browser/web/page_placeholder_tab_helper_delegate.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
-#include "ios/web/public/test/web_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -55,11 +53,11 @@
 @end
 
 // Test fixture for PagePlaceholderTabHelper class.
-class PagePlaceholderTabHelperTest : public web::WebTest {
+class PagePlaceholderTabHelperTest : public PlatformTest {
  protected:
   PagePlaceholderTabHelperTest()
       : delegate_([[PagePlaceholderTabHelperTestDelegate alloc] init]),
-        web_state_(base::MakeUnique<web::TestWebState>()) {
+        web_state_(std::make_unique<web::TestWebState>()) {
     PagePlaceholderTabHelper::CreateForWebState(web_state_.get(), delegate_);
     delegate_.tabHelper = tab_helper();
   }
@@ -68,6 +66,7 @@
     return PagePlaceholderTabHelper::FromWebState(web_state_.get());
   }
 
+  base::test::ScopedTaskEnvironment environement_;
   PagePlaceholderTabHelperTestDelegate* delegate_;
   std::unique_ptr<web::TestWebState> web_state_;
 };
@@ -76,9 +75,29 @@
 // requested.
 TEST_F(PagePlaceholderTabHelperTest, NotShown) {
   ASSERT_FALSE(delegate_.displayingPlaceholder);
+  ASSERT_FALSE(tab_helper()->displaying_placeholder());
   ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
   web_state_->OnNavigationStarted(nullptr);
   EXPECT_FALSE(delegate_.displayingPlaceholder);
+  EXPECT_FALSE(tab_helper()->displaying_placeholder());
+  EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
+}
+
+// Tests that placehold is not shown after DidStartNavigation if it was
+// cancelled before the navigation.
+TEST_F(PagePlaceholderTabHelperTest, NotShownIfCancelled) {
+  ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
+  tab_helper()->AddPlaceholderForNextNavigation();
+  ASSERT_FALSE(delegate_.displayingPlaceholder);
+  ASSERT_FALSE(tab_helper()->displaying_placeholder());
+  EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation());
+  tab_helper()->CancelPlaceholderForNextNavigation();
+  ASSERT_FALSE(delegate_.displayingPlaceholder);
+  ASSERT_FALSE(tab_helper()->displaying_placeholder());
+  EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
+  web_state_->OnNavigationStarted(nullptr);
+  EXPECT_FALSE(delegate_.displayingPlaceholder);
+  EXPECT_FALSE(tab_helper()->displaying_placeholder());
   EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
 }
 
@@ -88,14 +107,34 @@
   ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
   tab_helper()->AddPlaceholderForNextNavigation();
   ASSERT_FALSE(delegate_.displayingPlaceholder);
-
+  ASSERT_FALSE(tab_helper()->displaying_placeholder());
   EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation());
   web_state_->OnNavigationStarted(nullptr);
   EXPECT_TRUE(delegate_.displayingPlaceholder);
+  EXPECT_TRUE(tab_helper()->displaying_placeholder());
   EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
 
   web_state_->OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS);
   EXPECT_FALSE(delegate_.displayingPlaceholder);
+  EXPECT_FALSE(tab_helper()->displaying_placeholder());
+  EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
+}
+
+// Tests that placeholder is removed if cancelled while presented.
+TEST_F(PagePlaceholderTabHelperTest, RemovedIfCancelledWhileShown) {
+  ASSERT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
+  tab_helper()->AddPlaceholderForNextNavigation();
+  ASSERT_FALSE(delegate_.displayingPlaceholder);
+  ASSERT_FALSE(tab_helper()->displaying_placeholder());
+  EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation());
+  web_state_->OnNavigationStarted(nullptr);
+  EXPECT_TRUE(delegate_.displayingPlaceholder);
+  EXPECT_TRUE(tab_helper()->displaying_placeholder());
+  EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
+
+  tab_helper()->CancelPlaceholderForNextNavigation();
+  EXPECT_FALSE(delegate_.displayingPlaceholder);
+  EXPECT_FALSE(tab_helper()->displaying_placeholder());
   EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
 }
 
@@ -108,8 +147,11 @@
   EXPECT_TRUE(tab_helper()->will_add_placeholder_for_next_navigation());
   web_state_->OnNavigationStarted(nullptr);
   EXPECT_TRUE(delegate_.displayingPlaceholder);
+  EXPECT_TRUE(tab_helper()->displaying_placeholder());
   EXPECT_FALSE(tab_helper()->will_add_placeholder_for_next_navigation());
 
   web_state_.reset();
   EXPECT_FALSE(delegate_.displayingPlaceholder);
+  // The tab helper has been deleted at this point, so do not check the value
+  // of displaying_placeholder().
 }
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
index f872a29..a4422f8 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
@@ -167,7 +167,6 @@
       performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:AccountConsistencySetupSigninButton()]
       performAction:grey_tap()];
-  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
 }
 
 + (void)confirmSigninConfirmationDialog {
@@ -177,6 +176,8 @@
   // Cannot directly scroll on |kSignInConfirmationCollectionViewId| because it
   // is a MDC collection view, not a UICollectionView, so itself is not
   // scrollable.
+  // Wait until the sync confirmation is displayed.
+  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
   id<GREYMatcher> signinUICollectionViewMatcher = grey_allOf(
       grey_ancestor(grey_accessibilityID(kSigninConfirmationCollectionViewId)),
       grey_kindOfClass([UICollectionView class]), nil);
diff --git a/ios/web/public/web_state/ui/crw_web_delegate.h b/ios/web/public/web_state/ui/crw_web_delegate.h
index 42dbf17..e6e9e94f 100644
--- a/ios/web/public/web_state/ui/crw_web_delegate.h
+++ b/ios/web/public/web_state/ui/crw_web_delegate.h
@@ -33,12 +33,12 @@
               sourceURL:(const GURL&)sourceURL
             linkClicked:(BOOL)linkClicked;
 
+@optional
+
 // Called when a placeholder image should be displayed instead of the WebView.
 - (void)webController:(CRWWebController*)webController
     retrievePlaceholderOverlayImage:(void (^)(UIImage*))block;
 
-@optional
-
 // Called to ask CRWWebDelegate if |CRWWebController| should open the given URL.
 // CRWWebDelegate can intercept the request by returning NO and processing URL
 // in its own way.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index f70ae43..3d3c6fa 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -266,7 +266,7 @@
 // Enables the Unified Autoplay policy by overriding the platform's default
 // autoplay policy.
 const base::Feature kUnifiedAutoplay{"UnifiedAutoplay",
-                                     base::FEATURE_DISABLED_BY_DEFAULT};
+                                     base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Use SurfaceLayer instead of VideoLayer.
 const base::Feature kUseSurfaceLayerForVideo{"UseSurfaceLayerForVideo",
@@ -302,7 +302,7 @@
 // Enables the Media Engagement Index to override autoplay policies if an
 // origins engagement score is high enough.
 const base::Feature kMediaEngagementBypassAutoplayPolicies{
-    "MediaEngagementBypassAutoplayPolicies", base::FEATURE_DISABLED_BY_DEFAULT};
+    "MediaEngagementBypassAutoplayPolicies", base::FEATURE_ENABLED_BY_DEFAULT};
 
 #if defined(OS_ANDROID)
 // Lock the screen orientation when a video goes fullscreen.
diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
index d36f469e..2e25b93b 100644
--- a/media/gpu/v4l2/generic_v4l2_device.cc
+++ b/media/gpu/v4l2/generic_v4l2_device.cc
@@ -46,6 +46,10 @@
     FILE_PATH_LITERAL("/usr/lib/libv4l2.so");
 #endif
 
+#define DVLOGF(level) DVLOG(level) << __func__ << "(): "
+#define VLOGF(level) VLOG(level) << __func__ << "(): "
+#define VPLOGF(level) VPLOG(level) << __func__ << "(): "
+
 namespace media {
 
 GenericV4L2Device::GenericV4L2Device() {
@@ -77,7 +81,7 @@
   nfds = 1;
 
   if (poll_device) {
-    DVLOG(3) << "Poll(): adding device fd to poll() set";
+    DVLOGF(5) << "adding device fd to poll() set";
     pollfds[nfds].fd = device_fd_.get();
     pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI;
     pollfd = nfds;
@@ -85,7 +89,7 @@
   }
 
   if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) {
-    DPLOG(ERROR) << "poll() failed";
+    VPLOGF(1) << "poll() failed";
     return false;
   }
   *event_pending = (pollfd != -1 && pollfds[pollfd].revents & POLLPRI);
@@ -106,19 +110,19 @@
 }
 
 bool GenericV4L2Device::SetDevicePollInterrupt() {
-  DVLOG(3) << "SetDevicePollInterrupt()";
+  DVLOGF(4);
 
   const uint64_t buf = 1;
   if (HANDLE_EINTR(write(device_poll_interrupt_fd_.get(), &buf, sizeof(buf))) ==
       -1) {
-    DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed";
+    VPLOGF(1) << "write() failed";
     return false;
   }
   return true;
 }
 
 bool GenericV4L2Device::ClearDevicePollInterrupt() {
-  DVLOG(3) << "ClearDevicePollInterrupt()";
+  DVLOGF(5);
 
   uint64_t buf;
   if (HANDLE_EINTR(read(device_poll_interrupt_fd_.get(), &buf, sizeof(buf))) ==
@@ -127,7 +131,7 @@
       // No interrupt flag set, and we're reading nonblocking.  Not an error.
       return true;
     } else {
-      DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed";
+      VPLOGF(1) << "read() failed";
       return false;
     }
   }
@@ -135,9 +139,10 @@
 }
 
 bool GenericV4L2Device::Initialize() {
+  VLOGF(2);
   static bool v4l2_functions_initialized = PostSandboxInitialization();
   if (!v4l2_functions_initialized) {
-    LOG(ERROR) << "Failed to initialize LIBV4L2 libs";
+    VLOGF(1) << "Failed to initialize LIBV4L2 libs";
     return false;
   }
 
@@ -145,22 +150,23 @@
 }
 
 bool GenericV4L2Device::Open(Type type, uint32_t v4l2_pixfmt) {
+  VLOGF(2);
   std::string path = GetDevicePathFor(type, v4l2_pixfmt);
 
   if (path.empty()) {
-    DVLOG(1) << "No devices supporting " << std::hex << "0x" << v4l2_pixfmt
+    VLOGF(1) << "No devices supporting " << std::hex << "0x" << v4l2_pixfmt
              << " for type: " << static_cast<int>(type);
     return false;
   }
 
   if (!OpenDevicePath(path, type)) {
-    LOG(ERROR) << "Failed opening " << path;
+    VLOGF(1) << "Failed opening " << path;
     return false;
   }
 
   device_poll_interrupt_fd_.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
   if (!device_poll_interrupt_fd_.is_valid()) {
-    LOG(ERROR) << "Failed creating a poll interrupt fd";
+    VLOGF(1) << "Failed creating a poll interrupt fd";
     return false;
   }
 
@@ -171,6 +177,7 @@
     int index,
     size_t num_planes,
     enum v4l2_buf_type buf_type) {
+  VLOGF(2);
   DCHECK(V4L2_TYPE_IS_MULTIPLANAR(buf_type));
 
   std::vector<base::ScopedFD> dmabuf_fds;
@@ -216,9 +223,9 @@
     unsigned int buffer_index,
     uint32_t v4l2_pixfmt,
     const std::vector<base::ScopedFD>& dmabuf_fds) {
-  DVLOG(3) << "CreateEGLImage()";
+  DVLOGF(3);
   if (!CanCreateEGLImageFrom(v4l2_pixfmt)) {
-    LOG(ERROR) << "Unsupported V4L2 pixel format";
+    VLOGF(1) << "Unsupported V4L2 pixel format";
     return EGL_NO_IMAGE_KHR;
   }
 
@@ -271,7 +278,7 @@
   EGLImageKHR egl_image = eglCreateImageKHR(
       egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, &attrs[0]);
   if (egl_image == EGL_NO_IMAGE_KHR) {
-    LOG(ERROR) << "Failed creating EGL image: " << ui::GetLastEGLErrorString();
+    VLOGF(1) << "Failed creating EGL image: " << ui::GetLastEGLErrorString();
     return egl_image;
   }
   glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
@@ -284,6 +291,7 @@
     const gfx::Size& size,
     uint32_t fourcc,
     const std::vector<base::ScopedFD>& dmabuf_fds) {
+  DVLOGF(3);
   DCHECK(CanCreateEGLImageFrom(fourcc));
   VideoPixelFormat vf_format = V4L2PixFmtToVideoPixelFormat(fourcc);
   size_t num_planes = VideoFrame::NumPlanes(vf_format);
@@ -296,7 +304,7 @@
   for (const auto& fd : dmabuf_fds) {
     duped_fds.emplace_back(HANDLE_EINTR(dup(fd.get())));
     if (!duped_fds.back().is_valid()) {
-      PLOG(ERROR) << "Failed duplicating a dmabuf fd";
+      VPLOGF(1) << "Failed duplicating a dmabuf fd";
       return nullptr;
     }
   }
@@ -361,6 +369,7 @@
 
 EGLBoolean GenericV4L2Device::DestroyEGLImage(EGLDisplay egl_display,
                                               EGLImageKHR egl_image) {
+  DVLOGF(3);
   EGLBoolean result = eglDestroyImageKHR(egl_display, egl_image);
   if (result != EGL_TRUE) {
     LOG(WARNING) << "Destroy EGLImage failed.";
@@ -387,7 +396,7 @@
   const auto& devices = GetDevicesForType(type);
   for (const auto& device : devices) {
     if (!OpenDevicePath(device.first, type)) {
-      LOG(ERROR) << "Failed opening " << device.first;
+      VLOGF(1) << "Failed opening " << device.first;
       continue;
     }
 
@@ -411,7 +420,7 @@
   const auto& devices = GetDevicesForType(type);
   for (const auto& device : devices) {
     if (!OpenDevicePath(device.first, type)) {
-      LOG(ERROR) << "Failed opening " << device.first;
+      VLOGF(1) << "Failed opening " << device.first;
       continue;
     }
 
@@ -433,7 +442,7 @@
   const auto& devices = GetDevicesForType(type);
   for (const auto& device : devices) {
     if (!OpenDevicePath(device.first, type)) {
-      LOG(ERROR) << "Failed opening " << device.first;
+      VLOGF(1) << "Failed opening " << device.first;
       continue;
     }
 
@@ -468,7 +477,7 @@
   if (type == Type::kEncoder &&
       HANDLE_EINTR(v4l2_fd_open(device_fd_.get(), V4L2_DISABLE_CONVERSION)) !=
           -1) {
-    DVLOG(2) << "Using libv4l2 for " << path;
+    VLOGF(2) << "Using libv4l2 for " << path;
     use_libv4l2_ = true;
   }
 #endif
@@ -476,6 +485,7 @@
 }
 
 void GenericV4L2Device::CloseDevice() {
+  VLOGF(2);
 #if BUILDFLAG(USE_LIBV4L2)
   if (use_libv4l2_ && device_fd_.is_valid())
     v4l2_close(device_fd_.release());
@@ -544,7 +554,7 @@
     const auto& supported_pixelformats =
         EnumerateSupportedPixelformats(buf_type);
     if (!supported_pixelformats.empty()) {
-      DVLOG(1) << "Found device: " << path;
+      DVLOGF(3) << "Found device: " << path;
       devices.push_back(std::make_pair(path, supported_pixelformats));
     }
 
diff --git a/media/gpu/v4l2/tegra_v4l2_device.cc b/media/gpu/v4l2/tegra_v4l2_device.cc
index 43e0075d..c48988b 100644
--- a/media/gpu/v4l2/tegra_v4l2_device.cc
+++ b/media/gpu/v4l2/tegra_v4l2_device.cc
@@ -11,6 +11,9 @@
 #include "media/gpu/v4l2/tegra_v4l2_device.h"
 #include "ui/gl/gl_bindings.h"
 
+#define DVLOGF(level) DVLOG(level) << __func__ << "(): "
+#define VLOGF(level) VLOG(level) << __func__ << "(): "
+
 namespace media {
 
 namespace {
@@ -64,7 +67,7 @@
 bool TegraV4L2Device::Poll(bool poll_device, bool* event_pending) {
   if (HANDLE_EINTR(TegraV4L2_Poll(device_fd_, poll_device, event_pending)) ==
       -1) {
-    LOG(ERROR) << "TegraV4L2Poll returned -1 ";
+    VLOGF(1) << "TegraV4L2Poll returned -1 ";
     return false;
   }
   return true;
@@ -83,22 +86,25 @@
 }
 
 bool TegraV4L2Device::SetDevicePollInterrupt() {
+  DVLOGF(4);
   if (HANDLE_EINTR(TegraV4L2_SetDevicePollInterrupt(device_fd_)) == -1) {
-    LOG(ERROR) << "Error in calling TegraV4L2SetDevicePollInterrupt";
+    VLOGF(1) << "Error in calling TegraV4L2SetDevicePollInterrupt";
     return false;
   }
   return true;
 }
 
 bool TegraV4L2Device::ClearDevicePollInterrupt() {
+  DVLOGF(5);
   if (HANDLE_EINTR(TegraV4L2_ClearDevicePollInterrupt(device_fd_)) == -1) {
-    LOG(ERROR) << "Error in calling TegraV4L2ClearDevicePollInterrupt";
+    VLOGF(1) << "Error in calling TegraV4L2ClearDevicePollInterrupt";
     return false;
   }
   return true;
 }
 
 bool TegraV4L2Device::Initialize() {
+  VLOGF(2);
   static bool initialized = []() {
     if (!dlopen("/usr/lib/libtegrav4l2.so",
                 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE)) {
@@ -109,7 +115,7 @@
     TegraV4L2_##name = reinterpret_cast<TegraV4L2##name>( \
         dlsym(RTLD_DEFAULT, "TegraV4L2_" #name));         \
     if (TegraV4L2_##name == NULL) {                       \
-      LOG(ERROR) << "Failed to dlsym TegraV4L2_" #name;   \
+      VLOGF(1) << "Failed to dlsym TegraV4L2_" #name;     \
       return false;                                       \
     }                                                     \
   } while (0)
@@ -131,6 +137,7 @@
 }
 
 bool TegraV4L2Device::Open(Type type, uint32_t /* v4l2_pixfmt */) {
+  VLOGF(2);
   return OpenInternal(type);
 }
 
@@ -145,8 +152,8 @@
       device_path = kEncoderDevice;
       break;
     default:
-      DVLOG(1) << "Device type " << static_cast<int>(type)
-               << " not supported on this platform";
+      DVLOGF(1) << "Device type " << static_cast<int>(type)
+                << " not supported on this platform";
       return false;
   }
 
@@ -154,13 +161,14 @@
   device_fd_ = HANDLE_EINTR(
       TegraV4L2_Open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC));
   if (device_fd_ == -1) {
-    DLOG(ERROR) << "Unable to open device " << device_path;
+    VLOGF(1) << "Unable to open device " << device_path;
     return false;
   }
   return true;
 }
 
 void TegraV4L2Device::Close() {
+  VLOGF(2) << "device_fd= " << device_fd_;
   if (device_fd_ != -1) {
     TegraV4L2_Close(device_fd_);
     device_fd_ = -1;
@@ -171,6 +179,7 @@
     int /* index */,
     size_t num_planes,
     enum v4l2_buf_type /* buf_type */) {
+  VLOGF(2);
   std::vector<base::ScopedFD> dmabuf_fds;
   // Tegra does not actually provide dmabuf fds currently. Fill the vector with
   // invalid descriptors to prevent the caller from failing on an empty vector
@@ -192,7 +201,7 @@
     unsigned int buffer_index,
     uint32_t v4l2_pixfmt,
     const std::vector<base::ScopedFD>& /* dmabuf_fds */) {
-  DVLOG(3) << "CreateEGLImage()";
+  DVLOGF(3);
   if (!CanCreateEGLImageFrom(v4l2_pixfmt)) {
     LOG(ERROR) << "Unsupported V4L2 pixel format";
     return EGL_NO_IMAGE_KHR;
@@ -203,11 +212,11 @@
       eglCreateImageKHR(egl_display, egl_context, EGL_GL_TEXTURE_2D_KHR,
                         reinterpret_cast<EGLClientBuffer>(texture_id), &attr);
   if (egl_image == EGL_NO_IMAGE_KHR) {
-    LOG(ERROR) << "Unable to create EGL image";
+    VLOGF(1) << "Unable to create EGL image";
     return egl_image;
   }
   if (TegraV4L2_UseEglImage(device_fd_, buffer_index, egl_image) != 0) {
-    LOG(ERROR) << "Unable to use EGL image";
+    VLOGF(1) << "Unable to use EGL image";
     eglDestroyImageKHR(egl_display, egl_image);
     egl_image = EGL_NO_IMAGE_KHR;
   }
@@ -223,6 +232,7 @@
 
 EGLBoolean TegraV4L2Device::DestroyEGLImage(EGLDisplay egl_display,
                                             EGLImageKHR egl_image) {
+  DVLOGF(3);
   return eglDestroyImageKHR(egl_display, egl_image);
 }
 
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index 8684eaf..6b323b0 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -13,6 +13,9 @@
 #include "media/gpu/v4l2/tegra_v4l2_device.h"
 #endif
 
+#define DVLOGF(level) DVLOG(level) << __func__ << "(): "
+#define VLOGF(level) VLOG(level) << __func__ << "(): "
+
 namespace media {
 
 V4L2Device::V4L2Device() {}
@@ -21,7 +24,7 @@
 
 // static
 scoped_refptr<V4L2Device> V4L2Device::Create() {
-  DVLOG(3) << __PRETTY_FUNCTION__;
+  VLOGF(2);
 
   scoped_refptr<V4L2Device> device;
 
@@ -35,7 +38,7 @@
   if (device->Initialize())
     return device;
 
-  DVLOG(1) << "Failed to create a V4L2Device";
+  VLOGF(1) << "Failed to create a V4L2Device";
   return nullptr;
 }
 
@@ -63,7 +66,7 @@
       return PIXEL_FORMAT_ARGB;
 
     default:
-      DVLOG(1) << "Add more cases as needed";
+      DVLOGF(1) << "Add more cases as needed";
       return PIXEL_FORMAT_UNKNOWN;
   }
 }
@@ -147,7 +150,7 @@
       break;
 
     default:
-      DVLOG(1) << "Unhandled pixelformat " << std::hex << "0x" << pix_fmt;
+      VLOGF(1) << "Unhandled pixelformat " << std::hex << "0x" << pix_fmt;
       return profiles;
   }
 
@@ -178,7 +181,7 @@
       return DRM_FORMAT_MT21;
 
     default:
-      DVLOG(1) << "Unrecognized format " << std::hex << "0x" << format;
+      DVLOGF(1) << "Unrecognized format " << std::hex << "0x" << format;
       return 0;
   }
 }
@@ -234,7 +237,7 @@
 
   if (sizeimage == 0 || bytesperline == 0 || plane_horiz_bits_per_pixel == 0 ||
       total_bpp == 0 || (bytesperline * 8) % plane_horiz_bits_per_pixel != 0) {
-    LOG(ERROR) << "Invalid format provided";
+    VLOGF(1) << "Invalid format provided";
     return coded_size;
   }
 
@@ -253,7 +256,7 @@
   // aligning to next full row.
   if (sizeimage > VideoFrame::AllocationSize(frame_format, coded_size))
     coded_size.SetSize(coded_width, coded_height + 1);
-  DVLOG(3) << "coded_size=" << coded_size.ToString();
+  DVLOGF(3) << "coded_size=" << coded_size.ToString();
 
   // Sanity checks. Calculated coded size has to contain given visible size
   // and fulfill buffer byte size requirements.
@@ -299,15 +302,15 @@
   }
   if (max_resolution->IsEmpty()) {
     max_resolution->SetSize(1920, 1088);
-    LOG(ERROR) << "GetSupportedResolution failed to get maximum resolution for "
-               << "fourcc " << std::hex << pixelformat
-               << ", fall back to " << max_resolution->ToString();
+    VLOGF(1) << "GetSupportedResolution failed to get maximum resolution for "
+             << "fourcc " << std::hex << pixelformat << ", fall back to "
+             << max_resolution->ToString();
   }
   if (min_resolution->IsEmpty()) {
     min_resolution->SetSize(16, 16);
-    LOG(ERROR) << "GetSupportedResolution failed to get minimum resolution for "
-               << "fourcc " << std::hex << pixelformat
-               << ", fall back to " << min_resolution->ToString();
+    VLOGF(1) << "GetSupportedResolution failed to get minimum resolution for "
+             << "fourcc " << std::hex << pixelformat << ", fall back to "
+             << min_resolution->ToString();
   }
 }
 
@@ -320,8 +323,8 @@
   fmtdesc.type = buf_type;
 
   for (; Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) {
-    DVLOG(1) << "Found " << fmtdesc.description << std::hex << " (0x"
-             << fmtdesc.pixelformat << ")";
+    DVLOGF(3) << "Found " << fmtdesc.description << std::hex << " (0x"
+              << fmtdesc.pixelformat << ")";
     pixelformats.push_back(fmtdesc.pixelformat);
   }
 
@@ -352,9 +355,9 @@
       profile.profile = video_codec_profile;
       profiles.push_back(profile);
 
-      DVLOG(1) << "Found decoder profile " << GetProfileName(profile.profile)
-               << ", resolutions: " << profile.min_resolution.ToString() << " "
-               << profile.max_resolution.ToString();
+      DVLOGF(3) << "Found decoder profile " << GetProfileName(profile.profile)
+                << ", resolutions: " << profile.min_resolution.ToString() << " "
+                << profile.max_resolution.ToString();
     }
   }
 
@@ -383,8 +386,8 @@
       profile.profile = video_codec_profile;
       profiles.push_back(profile);
 
-      DVLOG(1) << "Found encoder profile " << GetProfileName(profile.profile)
-               << ", max resolution: " << profile.max_resolution.ToString();
+      DVLOGF(3) << "Found encoder profile " << GetProfileName(profile.profile)
+                << ", max resolution: " << profile.max_resolution.ToString();
     }
   }
 
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 8b145b7..85564a5 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -30,22 +30,20 @@
 #include "ui/gl/gl_context.h"
 #include "ui/gl/scoped_binders.h"
 
-#define LOGF(level) LOG(level) << __func__ << "(): "
-#define DLOGF(level) DLOG(level) << __func__ << "(): "
 #define DVLOGF(level) DVLOG(level) << __func__ << "(): "
 #define VLOGF(level) VLOG(level) << __func__ << "(): "
-#define PLOGF(level) PLOG(level) << __func__ << "(): "
+#define VPLOGF(level) VPLOG(level) << __func__ << "(): "
 
-#define NOTIFY_ERROR(x)                         \
-  do {                                          \
-    LOGF(ERROR) << "Setting error state:" << x; \
-    SetErrorState(x);                           \
+#define NOTIFY_ERROR(x)                      \
+  do {                                       \
+    VLOGF(1) << "Setting error state:" << x; \
+    SetErrorState(x);                        \
   } while (0)
 
 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
   do {                                                          \
     if (device_->Ioctl(type, arg) != 0) {                       \
-      PLOGF(ERROR) << "ioctl() failed: " << type_str;           \
+      VPLOGF(1) << "ioctl() failed: " << type_str;              \
       NOTIFY_ERROR(PLATFORM_FAILURE);                           \
       return value;                                             \
     }                                                           \
@@ -57,10 +55,10 @@
 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
   IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
 
-#define IOCTL_OR_LOG_ERROR(type, arg)              \
-  do {                                             \
-    if (device_->Ioctl(type, arg) != 0)            \
-      PLOGF(ERROR) << "ioctl() failed: " << #type; \
+#define IOCTL_OR_LOG_ERROR(type, arg)           \
+  do {                                          \
+    if (device_->Ioctl(type, arg) != 0)         \
+      VPLOGF(1) << "ioctl() failed: " << #type; \
   } while (0)
 
 namespace media {
@@ -185,6 +183,7 @@
 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() {
   DCHECK(!decoder_thread_.IsRunning());
   DCHECK(!device_poll_thread_.IsRunning());
+  DVLOGF(2);
 
   // These maps have members that should be manually destroyed, e.g. file
   // descriptors, mmap() segments, etc.
@@ -224,26 +223,26 @@
   video_profile_ = config.profile;
 
   if (egl_display_ == EGL_NO_DISPLAY) {
-    LOGF(ERROR) << "could not get EGLDisplay";
+    VLOGF(1) << "could not get EGLDisplay";
     return false;
   }
 
   // We need the context to be initialized to query extensions.
   if (!make_context_current_cb_.is_null()) {
     if (!make_context_current_cb_.Run()) {
-      LOGF(ERROR) << "could not make context current";
+      VLOGF(1) << "could not make context current";
       return false;
     }
 
 // TODO(posciak): https://crbug.com/450898.
 #if defined(ARCH_CPU_ARMEL)
     if (!gl::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
-      LOGF(ERROR) << "context does not have EGL_KHR_fence_sync";
+      VLOGF(1) << "context does not have EGL_KHR_fence_sync";
       return false;
     }
 #endif
   } else {
-    VLOGF(2) << "No GL callbacks provided, initializing without GL support";
+    DVLOGF(2) << "No GL callbacks provided, initializing without GL support";
   }
 
   input_format_fourcc_ =
@@ -260,8 +259,8 @@
   const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
-    LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP"
-                << ", caps check failed: 0x" << std::hex << caps.capabilities;
+    VLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP"
+             << ", caps check failed: 0x" << std::hex << caps.capabilities;
     return false;
   }
 
@@ -273,7 +272,7 @@
   }
 
   if (!decoder_thread_.Start()) {
-    LOGF(ERROR) << "decoder thread failed to start";
+    VLOGF(1) << "decoder thread failed to start";
     return false;
   }
 
@@ -317,7 +316,7 @@
   DCHECK(decode_task_runner_->BelongsToCurrentThread());
 
   if (bitstream_buffer.id() < 0) {
-    LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
+    VLOGF(1) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
     if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
       base::SharedMemory::CloseHandle(bitstream_buffer.handle());
     NOTIFY_ERROR(INVALID_ARGUMENT);
@@ -352,8 +351,8 @@
     req_buffer_count += kDpbOutputBufferExtraCountForImageProcessor;
 
   if (buffers.size() < req_buffer_count) {
-    LOGF(ERROR) << "Failed to provide requested picture buffers. (Got "
-                << buffers.size() << ", requested " << req_buffer_count << ")";
+    VLOGF(1) << "Failed to provide requested picture buffers. (Got "
+             << buffers.size() << ", requested " << req_buffer_count << ")";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -367,7 +366,7 @@
   IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs);
 
   if (reqbufs.count != buffers.size()) {
-    DLOGF(ERROR) << "Could not allocate enough output buffers";
+    VLOGF(1) << "Could not allocate enough output buffers";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -404,7 +403,7 @@
       std::vector<base::ScopedFD> dmabuf_fds = device_->GetDmabufsForV4L2Buffer(
           i, output_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
       if (dmabuf_fds.empty()) {
-        LOGF(ERROR) << "Failed to get DMABUFs of decoder.";
+        VLOGF(1) << "Failed to get DMABUFs of decoder.";
         NOTIFY_ERROR(PLATFORM_FAILURE);
         return;
       }
@@ -416,7 +415,7 @@
       dmabuf_fds = egl_image_device_->GetDmabufsForV4L2Buffer(
           i, egl_image_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
       if (dmabuf_fds.empty()) {
-        LOGF(ERROR) << "Failed to get DMABUFs for EGLImage.";
+        VLOGF(1) << "Failed to get DMABUFs for EGLImage.";
         NOTIFY_ERROR(PLATFORM_FAILURE);
         return;
       }
@@ -455,14 +454,14 @@
   DCHECK_NE(texture_id, 0u);
 
   if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
-    DLOGF(ERROR) << "GL callbacks required for binding to EGLImages";
+    VLOGF(1) << "GL callbacks required for binding to EGLImages";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
 
   gl::GLContext* gl_context = get_gl_context_cb_.Run();
   if (!gl_context || !make_context_current_cb_.Run()) {
-    DLOGF(ERROR) << "No GL context";
+    VLOGF(1) << "No GL context";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -473,8 +472,8 @@
       egl_display_, gl_context->GetHandle(), texture_id, size, buffer_index,
       fourcc, dmabuf_fds);
   if (egl_image == EGL_NO_IMAGE_KHR) {
-    LOGF(ERROR) << "could not create EGLImageKHR,"
-                << " index=" << buffer_index << " texture_id=" << texture_id;
+    VLOGF(1) << "could not create EGLImageKHR,"
+             << " index=" << buffer_index << " texture_id=" << texture_id;
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -503,7 +502,7 @@
   // just discard this image, we will get the one we are waiting for later.
   if (buffer_index >= output_buffer_map_.size() ||
       output_buffer_map_[buffer_index].picture_id != picture_buffer_id) {
-    DVLOGF(3) << "Picture set already changed, dropping EGLImage";
+    DVLOGF(4) << "Picture set already changed, dropping EGLImage";
     child_task_runner_->PostTask(
         FROM_HERE, base::Bind(base::IgnoreResult(&V4L2Device::DestroyEGLImage),
                               device_, egl_display_, egl_image));
@@ -532,7 +531,7 @@
   DCHECK(child_task_runner_->BelongsToCurrentThread());
 
   if (output_mode_ != Config::OutputMode::IMPORT) {
-    LOGF(ERROR) << "Cannot import in non-import mode";
+    VLOGF(1) << "Cannot import in non-import mode";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -583,7 +582,7 @@
   }
 
   if (iter->state != kAtClient) {
-    LOGF(ERROR) << "Cannot import buffer not owned by client";
+    VLOGF(1) << "Cannot import buffer not owned by client";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -592,8 +591,8 @@
       V4L2Device::V4L2PixFmtToVideoPixelFormat(egl_image_format_fourcc_), 0);
   if (plane_horiz_bits_per_pixel == 0 ||
       (stride * 8) % plane_horiz_bits_per_pixel != 0) {
-    LOG(ERROR) << "Invalid format " << egl_image_format_fourcc_ << " or stride "
-               << stride;
+    VLOGF(1) << "Invalid format " << egl_image_format_fourcc_ << " or stride "
+             << stride;
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -605,13 +604,13 @@
     // the final coded size in AssignPictureBuffers yet. Use the adjusted coded
     // width to create the image processor.
     VLOGF(2) << "Original egl_image_size=" << egl_image_size_.ToString()
-              << ", adjusted coded width=" << adjusted_coded_width;
+             << ", adjusted coded width=" << adjusted_coded_width;
     DCHECK_GE(adjusted_coded_width, egl_image_size_.width());
     egl_image_size_.set_width(adjusted_coded_width);
     if (!CreateImageProcessor())
       return;
     DCHECK_EQ(kAwaitingPictureBuffers, decoder_state_);
-    VLOGF(2) << "Change state to kDecoding";
+    DVLOGF(3) << "Change state to kDecoding";
     decoder_state_ = kDecoding;
     if (reset_pending_) {
       FinishReset();
@@ -660,7 +659,7 @@
 
   if (!make_context_current_cb_.is_null()) {
     if (!make_context_current_cb_.Run()) {
-      LOGF(ERROR) << "could not make context current";
+      VLOGF(1) << "could not make context current";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -670,7 +669,7 @@
 #if defined(ARCH_CPU_ARMEL)
     egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
     if (egl_sync == EGL_NO_SYNC_KHR) {
-      LOGF(ERROR) << "eglCreateSyncKHR() failed";
+      VLOGF(1) << "eglCreateSyncKHR() failed";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -722,6 +721,7 @@
   }
 
   delete this;
+  VLOGF(2) << "Destroyed.";
 }
 
 bool V4L2VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
@@ -763,7 +763,7 @@
     return;
 
   if (!bitstream_record->shm->Map()) {
-    LOGF(ERROR) << "could not map bitstream_buffer";
+    VLOGF(1) << "could not map bitstream_buffer";
     NOTIFY_ERROR(UNREADABLE_INPUT);
     return;
   }
@@ -797,7 +797,7 @@
   decoder_decode_buffer_tasks_scheduled_--;
 
   if (decoder_state_ != kInitialized && decoder_state_ != kDecoding) {
-    VLOGF(2) << "early out: state=" << decoder_state_;
+    DVLOGF(3) << "early out: state=" << decoder_state_;
     return;
   }
 
@@ -1003,7 +1003,7 @@
 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(const void* data,
                                                      size_t size,
                                                      size_t* endpos) {
-  DVLOGF(4) << "data=" << data << ", size=" << size;
+  DVLOGF(3) << "data=" << data << ", size=" << size;
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
   DCHECK_EQ(decoder_state_, kInitialized);
   // Initial decode.  We haven't been able to get output stream format info yet.
@@ -1080,7 +1080,7 @@
       Dequeue();
       if (free_input_buffers_.empty()) {
         // Nope!
-        DVLOGF(3) << "stalled for input buffers";
+        DVLOGF(4) << "stalled for input buffers";
         return false;
       }
     }
@@ -1105,7 +1105,7 @@
   // Copy in to the buffer.
   InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_];
   if (size > input_record.length - input_record.bytes_used) {
-    LOGF(ERROR) << "over-size frame, erroring";
+    VLOGF(1) << "over-size frame, erroring";
     NOTIFY_ERROR(UNREADABLE_INPUT);
     return false;
   }
@@ -1154,7 +1154,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) {
-  DVLOGF(3);
+  DVLOGF(4);
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
   DCHECK_NE(decoder_state_, kUninitialized);
   TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask");
@@ -1219,17 +1219,17 @@
       FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::DevicePollTask,
                             base::Unretained(this), poll_device));
 
-  DVLOG(3) << "ServiceDeviceTask(): buffer counts: DEC["
-           << decoder_input_queue_.size() << "->"
-           << input_ready_queue_.size() << "] => DEVICE["
-           << free_input_buffers_.size() << "+"
-           << input_buffer_queued_count_ << "/"
-           << input_buffer_map_.size() << "->"
-           << free_output_buffers_.size() << "+"
-           << output_buffer_queued_count_ << "/"
-           << output_buffer_map_.size() << "] => PROCESSOR["
-           << image_processor_bitstream_buffer_ids_.size() << "] => CLIENT["
-           << decoder_frames_at_client_ << "]";
+  DVLOGF(3) << "ServiceDeviceTask(): buffer counts: DEC["
+            << decoder_input_queue_.size() << "->"
+            << input_ready_queue_.size() << "] => DEVICE["
+            << free_input_buffers_.size() << "+"
+            << input_buffer_queued_count_ << "/"
+            << input_buffer_map_.size() << "->"
+            << free_output_buffers_.size() << "+"
+            << output_buffer_queued_count_ << "/"
+            << output_buffer_map_.size() << "] => PROCESSOR["
+            << image_processor_bitstream_buffer_ids_.size() << "] => CLIENT["
+            << decoder_frames_at_client_ << "]";
 
   ScheduleDecodeBufferTaskIfNeeded();
   if (resolution_change_pending)
@@ -1274,7 +1274,7 @@
     // We just started up a previously empty queue.
     // Queue state changed; signal interrupt.
     if (!device_->SetDevicePollInterrupt()) {
-      PLOGF(ERROR) << "SetDevicePollInterrupt failed";
+      VPLOGF(1) << "SetDevicePollInterrupt failed";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -1296,7 +1296,7 @@
     // We just started up a previously empty queue.
     // Queue state changed; signal interrupt.
     if (!device_->SetDevicePollInterrupt()) {
-      PLOGF(ERROR) << "SetDevicePollInterrupt(): failed";
+      VPLOGF(1) << "SetDevicePollInterrupt(): failed";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -1324,8 +1324,7 @@
         return true;
       }
     } else {
-      LOGF(ERROR) << "got an event (" << ev.type
-                  << ") we haven't subscribed to.";
+      VLOGF(1) << "got an event (" << ev.type << ") we haven't subscribed to.";
     }
   }
   return false;
@@ -1368,7 +1367,7 @@
       // EAGAIN if we're just out of buffers to dequeue.
       return false;
     }
-    PLOGF(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
+    VPLOGF(1) << "ioctl() failed: VIDIOC_DQBUF";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1407,7 +1406,7 @@
       DVLOGF(3) << "Got EPIPE. Last output buffer was already dequeued.";
       return false;
     }
-    PLOGF(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
+    VPLOGF(1) << "ioctl() failed: VIDIOC_DQBUF";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1426,7 +1425,7 @@
               << " bitstream input_id=" << bitstream_buffer_id;
     if (image_processor_device_) {
       if (!ProcessFrame(bitstream_buffer_id, dqbuf.index)) {
-        DLOGF(ERROR) << "Processing frame failed";
+        VLOGF(1) << "Processing frame failed";
         NOTIFY_ERROR(PLATFORM_FAILURE);
         return false;
       }
@@ -1502,10 +1501,10 @@
     if (eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0,
                              EGL_FOREVER_KHR) == EGL_FALSE) {
       // This will cause tearing, but is safe otherwise.
-      DLOGF(WARNING) << "eglClientWaitSyncKHR failed!";
+      DVLOGF(1) << "eglClientWaitSyncKHR failed!";
     }
     if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
-      LOGF(ERROR) << "eglDestroySyncKHR failed!";
+      VLOGF(1) << "eglDestroySyncKHR failed!";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return false;
     }
@@ -1559,14 +1558,14 @@
     // posted to us by the client. In that case just ignore this (we've already
     // dismissed it and accounted for that) and let the sync object get
     // destroyed.
-    DVLOGF(4) << "got picture id= " << picture_buffer_id
+    DVLOGF(3) << "got picture id= " << picture_buffer_id
               << " not in use (anymore?).";
     return;
   }
 
   OutputRecord& output_record = output_buffer_map_[index];
   if (output_record.state != kAtClient) {
-    LOGF(ERROR) << "picture_buffer_id not reusable";
+    VLOGF(1) << "picture_buffer_id not reusable";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -1675,7 +1674,7 @@
   memset(&cmd, 0, sizeof(cmd));
   cmd.cmd = V4L2_DEC_CMD_STOP;
   if (device_->Ioctl(VIDIOC_TRY_DECODER_CMD, &cmd) != 0) {
-    DVLOGF(3) "V4L2_DEC_CMD_STOP is not supported.";
+    VLOGF(2) "V4L2_DEC_CMD_STOP is not supported.";
     return false;
   }
 
@@ -1749,7 +1748,7 @@
 
   // Drop all buffers in image processor.
   if (image_processor_ && !ResetImageProcessor()) {
-    LOGF(ERROR) << "Fail to reset image processor";
+    VLOGF(1) << "Fail to reset image processor";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -1836,7 +1835,7 @@
 
   // Start up the device poll thread and schedule its first DevicePollTask().
   if (!device_poll_thread_.Start()) {
-    LOGF(ERROR) << "Device thread failed to start";
+    VLOGF(1) << "Device thread failed to start";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1858,7 +1857,7 @@
 
   // Signal the DevicePollTask() to stop, and stop the device poll thread.
   if (!device_->SetDevicePollInterrupt()) {
-    PLOGF(ERROR) << "SetDevicePollInterrupt(): failed";
+    VPLOGF(1) << "SetDevicePollInterrupt(): failed";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1945,7 +1944,7 @@
     image_processor_.release()->Destroy();
 
   if (!DestroyOutputBuffers()) {
-    LOGF(ERROR) << "Failed destroying output buffers.";
+    VLOGF(1) << "Failed destroying output buffers.";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -1968,13 +1967,13 @@
   gfx::Size visible_size;
   bool ret = GetFormatInfo(&format, &visible_size, &again);
   if (!ret || again) {
-    LOGF(ERROR) << "Couldn't get format information after resolution change";
+    VLOGF(1) << "Couldn't get format information after resolution change";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
 
   if (!CreateBuffersForFormat(format, visible_size)) {
-    LOGF(ERROR) << "Couldn't reallocate buffers after resolution change";
+    VLOGF(1) << "Couldn't reallocate buffers after resolution change";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -2003,7 +2002,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::NotifyError(Error error) {
-  VLOGF(2);
+  VLOGF(1);
 
   if (!child_task_runner_->BelongsToCurrentThread()) {
     child_task_runner_->PostTask(
@@ -2051,7 +2050,7 @@
       *again = true;
       return true;
     } else {
-      PLOGF(ERROR) << "ioctl() failed: VIDIOC_G_FMT";
+      VPLOGF(1) << "ioctl() failed: VIDIOC_G_FMT";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return false;
     }
@@ -2059,7 +2058,7 @@
 
   // Make sure we are still getting the format we set on initialization.
   if (format->fmt.pix_mp.pixelformat != output_format_fourcc_) {
-    LOGF(ERROR) << "Unexpected format from G_FMT on output";
+    VLOGF(1) << "Unexpected format from G_FMT on output";
     return false;
   }
 
@@ -2083,7 +2082,7 @@
     if (!V4L2ImageProcessor::TryOutputFormat(
             output_format_fourcc_, egl_image_format_fourcc_, &egl_image_size_,
             &egl_image_planes_count_)) {
-      LOGF(ERROR) << "Fail to get output size and plane count of processor";
+      VLOGF(1) << "Fail to get output size and plane count of processor";
       return false;
     }
   } else {
@@ -2110,16 +2109,16 @@
   selection_arg.target = V4L2_SEL_TGT_COMPOSE;
 
   if (device_->Ioctl(VIDIOC_G_SELECTION, &selection_arg) == 0) {
-    DVLOGF(2) << "VIDIOC_G_SELECTION is supported";
+    VLOGF(2) << "VIDIOC_G_SELECTION is supported";
     visible_rect = &selection_arg.r;
   } else {
-    DVLOGF(2) << "Fallback to VIDIOC_G_CROP";
+    VLOGF(2) << "Fallback to VIDIOC_G_CROP";
     struct v4l2_crop crop_arg;
     memset(&crop_arg, 0, sizeof(crop_arg));
     crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 
     if (device_->Ioctl(VIDIOC_G_CROP, &crop_arg) != 0) {
-      PLOGF(ERROR) << "ioctl() VIDIOC_G_CROP failed";
+      VPLOGF(1) << "ioctl() VIDIOC_G_CROP failed";
       return coded_size;
     }
     visible_rect = &crop_arg.c;
@@ -2129,19 +2128,19 @@
                  visible_rect->height);
   VLOGF(2) << "visible rectangle is " << rect.ToString();
   if (!gfx::Rect(coded_size).Contains(rect)) {
-    DLOGF(ERROR) << "visible rectangle " << rect.ToString()
-                 << " is not inside coded size " << coded_size.ToString();
+    DVLOGF(3) << "visible rectangle " << rect.ToString()
+              << " is not inside coded size " << coded_size.ToString();
     return coded_size;
   }
   if (rect.IsEmpty()) {
-    DLOGF(ERROR) << "visible size is empty";
+    VLOGF(1) << "visible size is empty";
     return coded_size;
   }
 
   // Chrome assume picture frame is coded at (0, 0).
   if (!rect.origin().IsOrigin()) {
-    DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString()
-                 << ", top-left is not origin";
+    VLOGF(1) << "Unexpected visible rectangle " << rect.ToString()
+             << ", top-left is not origin";
     return coded_size;
   }
 
@@ -2183,7 +2182,7 @@
                                   MAP_SHARED,
                                   buffer.m.planes[0].m.mem_offset);
     if (address == MAP_FAILED) {
-      PLOGF(ERROR) << "mmap() failed";
+      VPLOGF(1) << "mmap() failed";
       return false;
     }
     input_buffer_map_[i].address = address;
@@ -2250,19 +2249,19 @@
 
   DCHECK(!image_processor_device_);
   if (output_format_fourcc_ == 0) {
-    VLOGF(1) << "Could not find a usable output format. Try image processor";
+    VLOGF(2) << "Could not find a usable output format. Try image processor";
     if (!V4L2ImageProcessor::IsSupported()) {
       VLOGF(1) << "Image processor not available";
       return false;
     }
     output_format_fourcc_ = FindImageProcessorInputFormat();
     if (output_format_fourcc_ == 0) {
-      LOGF(ERROR) << "Can't find a usable input format from image processor";
+      VLOGF(1) << "Can't find a usable input format from image processor";
       return false;
     }
     egl_image_format_fourcc_ = FindImageProcessorOutputFormat();
     if (egl_image_format_fourcc_ == 0) {
-      LOGF(ERROR) << "Can't find a usable output format from image processor";
+      VLOGF(1) << "Can't find a usable output format from image processor";
       return false;
     }
     image_processor_device_ = V4L2Device::Create();
@@ -2273,8 +2272,8 @@
     egl_image_device_ = image_processor_device_;
   } else {
     if (output_mode_ == Config::OutputMode::IMPORT) {
-      LOGF(ERROR) << "Import mode without image processor is not implemented "
-                  << "yet.";
+      VLOGF(1) << "Import mode without image processor is not implemented "
+               << "yet.";
       return false;
     }
     egl_image_format_fourcc_ = output_format_fourcc_;
@@ -2377,7 +2376,7 @@
           visible_size_, egl_image_size_, output_buffer_map_.size(),
           base::Bind(&V4L2VideoDecodeAccelerator::ImageProcessorError,
                      base::Unretained(this)))) {
-    LOGF(ERROR) << "Initialize image processor failed";
+    VLOGF(1) << "Initialize image processor failed";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -2385,10 +2384,10 @@
            << image_processor_->output_allocated_size().ToString();
   DCHECK(image_processor_->output_allocated_size() == egl_image_size_);
   if (image_processor_->input_allocated_size() != coded_size_) {
-    LOGF(ERROR) << "Image processor should be able to take the output coded "
-                << "size of decoder " << coded_size_.ToString()
-                << " without adjusting to "
-                << image_processor_->input_allocated_size().ToString();
+    VLOGF(1) << "Image processor should be able to take the output coded "
+             << "size of decoder " << coded_size_.ToString()
+             << " without adjusting to "
+             << image_processor_->input_allocated_size().ToString();
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -2419,7 +2418,7 @@
       processor_output_fds.push_back(
           base::ScopedFD(HANDLE_EINTR(dup(fd.get()))));
       if (!processor_output_fds.back().is_valid()) {
-        PLOGF(ERROR) << "Failed duplicating a dmabuf fd";
+        VPLOGF(1) << "Failed duplicating a dmabuf fd";
         return false;
       }
     }
@@ -2547,7 +2546,7 @@
   reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   reqbufs.memory = V4L2_MEMORY_MMAP;
   if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) {
-    PLOGF(ERROR) << "ioctl() failed: VIDIOC_REQBUFS";
+    VPLOGF(1) << "ioctl() failed: VIDIOC_REQBUFS";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     success = false;
   }
@@ -2648,7 +2647,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::ImageProcessorError() {
-  LOGF(ERROR) << "Image processor error";
+  VLOGF(1) << "Image processor error";
   NOTIFY_ERROR(PLATFORM_FAILURE);
 }
 
diff --git a/services/data_decoder/BUILD.gn b/services/data_decoder/BUILD.gn
index b0f7201..be8c21e 100644
--- a/services/data_decoder/BUILD.gn
+++ b/services/data_decoder/BUILD.gn
@@ -77,6 +77,7 @@
   deps = [
     ":lib",
     "//base",
+    "//third_party/libxml:libxml",
   ]
   dict = "//testing/libfuzzer/fuzzers/dicts/xml.dict"
   seed_corpus = "xml_parser_fuzzer_corpus"
diff --git a/services/data_decoder/xml_parser_fuzzer.cc b/services/data_decoder/xml_parser_fuzzer.cc
index afc9d821..aabc078 100644
--- a/services/data_decoder/xml_parser_fuzzer.cc
+++ b/services/data_decoder/xml_parser_fuzzer.cc
@@ -11,6 +11,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "services/data_decoder/xml_parser.h"
+#include "third_party/libxml/chromium/libxml_utils.h"
 
 namespace {
 
@@ -20,8 +21,13 @@
   std::move(quit_loop).Run();
 }
 
+// Error handler to ignore spamy messages from libxml.
+void ignore(void* ctx, const char* msg, ...) {}
+
 }  // namespace
 
+static ScopedXmlErrorFunc scoped_xml_error_func(nullptr, &ignore);
+
 // Entry point for LibFuzzer.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   const char* data_ptr = reinterpret_cast<const char*>(data);
diff --git a/services/shape_detection/BUILD.gn b/services/shape_detection/BUILD.gn
index 36d2ff0..36043e5 100644
--- a/services/shape_detection/BUILD.gn
+++ b/services/shape_detection/BUILD.gn
@@ -137,5 +137,6 @@
   ]
   data = [
     "//services/test/data/mona_lisa.jpg",
+    "//services/test/data/text_detection.png",
   ]
 }
diff --git a/services/shape_detection/detection_utils_win.cc b/services/shape_detection/detection_utils_win.cc
index 5265ff7..458d384 100644
--- a/services/shape_detection/detection_utils_win.cc
+++ b/services/shape_detection/detection_utils_win.cc
@@ -10,10 +10,9 @@
 
 namespace shape_detection {
 
-Microsoft::WRL::ComPtr<ISoftwareBitmap> CreateWinBitmapFromSkBitmap(
-    ISoftwareBitmapStatics* bitmap_factory,
-    BitmapPixelFormat pixel_format,
-    const SkBitmap& bitmap) {
+WRL::ComPtr<ISoftwareBitmap> CreateWinBitmapFromSkBitmap(
+    const SkBitmap& bitmap,
+    ISoftwareBitmapStatics* bitmap_factory) {
   DCHECK(bitmap_factory);
   DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
   if (!base::CheckedNumeric<uint32_t>(bitmap.computeByteSize()).IsValid()) {
@@ -22,7 +21,7 @@
   }
 
   // Create IBuffer from bitmap data.
-  Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
+  WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
   HRESULT hr = base::win::CreateIBufferFromData(
       static_cast<uint8_t*>(bitmap.getPixels()),
       static_cast<UINT32>(bitmap.computeByteSize()), &buffer);
@@ -32,7 +31,7 @@
     return nullptr;
   }
 
-  Microsoft::WRL::ComPtr<ISoftwareBitmap> win_bitmap;
+  WRL::ComPtr<ISoftwareBitmap> win_bitmap;
   const BitmapPixelFormat pixelFormat =
       (kN32_SkColorType == kRGBA_8888_SkColorType)
           ? ABI::Windows::Graphics::Imaging::BitmapPixelFormat_Rgba8
@@ -48,9 +47,19 @@
     return nullptr;
   }
 
+  return win_bitmap;
+}
+
+WRL::ComPtr<ISoftwareBitmap> CreateWinBitmapWithPixelFormat(
+    const SkBitmap& bitmap,
+    ISoftwareBitmapStatics* bitmap_factory,
+    BitmapPixelFormat pixel_format) {
+  WRL::ComPtr<ISoftwareBitmap> win_bitmap =
+      CreateWinBitmapFromSkBitmap(bitmap, bitmap_factory);
+
   // Convert Rgba8/Bgra8 to Gray8/Nv12 SoftwareBitmap.
-  hr = bitmap_factory->Convert(win_bitmap.Get(), pixel_format,
-                               win_bitmap.GetAddressOf());
+  const HRESULT hr = bitmap_factory->Convert(win_bitmap.Get(), pixel_format,
+                                             win_bitmap.GetAddressOf());
   if (FAILED(hr)) {
     DLOG(ERROR) << "Convert Rgba8/Bgra8 to Gray8/Nv12 failed: "
                 << logging::SystemErrorCodeToString(hr);
diff --git a/services/shape_detection/detection_utils_win.h b/services/shape_detection/detection_utils_win.h
index eceb4c4..d2653ab 100644
--- a/services/shape_detection/detection_utils_win.h
+++ b/services/shape_detection/detection_utils_win.h
@@ -24,16 +24,16 @@
 
 class SkBitmap;
 
+namespace shape_detection {
+
+namespace WRL = Microsoft::WRL;
+
 using ABI::Windows::Foundation::IAsyncOperation;
 using ABI::Windows::Foundation::IAsyncOperationCompletedHandler;
 using ABI::Windows::Graphics::Imaging::ISoftwareBitmapStatics;
 using ABI::Windows::Graphics::Imaging::ISoftwareBitmap;
 using ABI::Windows::Graphics::Imaging::BitmapPixelFormat;
 
-namespace shape_detection {
-
-namespace WRL = Microsoft::WRL;
-
 // This template represents an asynchronous operation which returns a result
 // upon completion, internal async callback will be not called if the instance
 // is deleted. RuntimeType is Windows Runtime APIs that has a result.
@@ -42,8 +42,7 @@
 template <typename RuntimeType>
 class AsyncOperation {
  public:
-  using IAsyncOperationPtr =
-      Microsoft::WRL::ComPtr<IAsyncOperation<RuntimeType*>>;
+  using IAsyncOperationPtr = WRL::ComPtr<IAsyncOperation<RuntimeType*>>;
   // A callback run when the asynchronous operation completes. The callback is
   // run with the IAsyncOperation that completed on success, or with an empty
   // pointer in case of failure.
@@ -114,12 +113,18 @@
   DISALLOW_COPY_AND_ASSIGN(AsyncOperation);
 };
 
+// Creates a Windows ISoftwareBitmap from a kN32_SkColorType |bitmap|, or
+// returns nullptr.
+WRL::ComPtr<ISoftwareBitmap> CreateWinBitmapFromSkBitmap(
+    const SkBitmap& bitmap,
+    ISoftwareBitmapStatics* bitmap_factory);
+
 // Creates a Gray8/Nv12 ISoftwareBitmap from a kN32_SkColorType |bitmap|, or
 // returns nullptr.
-Microsoft::WRL::ComPtr<ISoftwareBitmap> CreateWinBitmapFromSkBitmap(
+WRL::ComPtr<ISoftwareBitmap> CreateWinBitmapWithPixelFormat(
+    const SkBitmap& bitmap,
     ISoftwareBitmapStatics* bitmap_factory,
-    BitmapPixelFormat pixel_format,
-    const SkBitmap& bitmap);
+    BitmapPixelFormat pixel_format);
 
 }  // namespace shape_detection
 
diff --git a/services/shape_detection/face_detection_impl_win.cc b/services/shape_detection/face_detection_impl_win.cc
index b0e2cb6..935c2e38 100644
--- a/services/shape_detection/face_detection_impl_win.cc
+++ b/services/shape_detection/face_detection_impl_win.cc
@@ -46,7 +46,8 @@
 std::unique_ptr<AsyncOperation<IVector<DetectedFace*>>>
 FaceDetectionImplWin::BeginDetect(const SkBitmap& bitmap) {
   Microsoft::WRL::ComPtr<ISoftwareBitmap> win_bitmap =
-      CreateWinBitmapFromSkBitmap(bitmap_factory_.Get(), pixel_format_, bitmap);
+      CreateWinBitmapWithPixelFormat(bitmap, bitmap_factory_.Get(),
+                                     pixel_format_);
   if (!win_bitmap)
     return nullptr;
 
@@ -61,8 +62,8 @@
   }
 
   // The once callback will not be called if this object is deleted, so it's
-  // fine to use Unretained to bind the callback.
-  // |win_bitmap| needs to be kept alive until OnFaceDetected().
+  // fine to use Unretained to bind the callback. |win_bitmap| needs to be kept
+  // alive until OnFaceDetected().
   return AsyncOperation<IVector<DetectedFace*>>::Create(
       base::BindOnce(&FaceDetectionImplWin::OnFaceDetected,
                      base::Unretained(this), std::move(win_bitmap)),
@@ -109,8 +110,8 @@
   return results;
 }
 
-// The extra passing of |win_bitmap| need to be kept until AsyncOperation
-// completes, otherwise random crashes will happen.
+// |win_bitmap| is passed here so that it is kept alive until the AsyncOperation
+// completes because DetectFacesAsync does not hold a reference.
 void FaceDetectionImplWin::OnFaceDetected(
     Microsoft::WRL::ComPtr<ISoftwareBitmap> /* win_bitmap */,
     AsyncOperation<IVector<DetectedFace*>>::IAsyncOperationPtr async_op) {
diff --git a/services/shape_detection/text_detection_impl_win.cc b/services/shape_detection/text_detection_impl_win.cc
index b1522e9..9b74f04 100644
--- a/services/shape_detection/text_detection_impl_win.cc
+++ b/services/shape_detection/text_detection_impl_win.cc
@@ -4,10 +4,10 @@
 
 #include "services/shape_detection/text_detection_impl_win.h"
 
+#include <windows.foundation.collections.h>
 #include <windows.globalization.h>
 #include <memory>
-#include <utility>
-#include <vector>
+#include <string>
 
 #include "base/logging.h"
 #include "base/win/core_winrt_util.h"
@@ -18,8 +18,11 @@
 
 namespace shape_detection {
 
+using ABI::Windows::Foundation::Collections::IVectorView;
 using ABI::Windows::Globalization::ILanguageFactory;
 using ABI::Windows::Media::Ocr::IOcrEngineStatics;
+using ABI::Windows::Media::Ocr::IOcrLine;
+using ABI::Windows::Media::Ocr::OcrLine;
 using base::win::GetActivationFactory;
 using base::win::ScopedHString;
 
@@ -91,22 +94,128 @@
     return;
   }
 
-  mojo::MakeStrongBinding(
-      std::make_unique<TextDetectionImplWin>(std::move(ocr_engine)),
-      std::move(request));
+  Microsoft::WRL::ComPtr<ISoftwareBitmapStatics> bitmap_factory;
+  hr = GetActivationFactory<
+      ISoftwareBitmapStatics,
+      RuntimeClass_Windows_Graphics_Imaging_SoftwareBitmap>(&bitmap_factory);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "ISoftwareBitmapStatics factory failed: "
+                << logging::SystemErrorCodeToString(hr);
+    return;
+  }
+
+  auto impl = std::make_unique<TextDetectionImplWin>(std::move(ocr_engine),
+                                                     std::move(bitmap_factory));
+  auto* impl_ptr = impl.get();
+  impl_ptr->SetBinding(
+      mojo::MakeStrongBinding(std::move(impl), std::move(request)));
 }
 
 TextDetectionImplWin::TextDetectionImplWin(
-    Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine)
-    : ocr_engine_(std::move(ocr_engine)) {
+    Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine,
+    Microsoft::WRL::ComPtr<ISoftwareBitmapStatics> bitmap_factory)
+    : ocr_engine_(std::move(ocr_engine)),
+      bitmap_factory_(std::move(bitmap_factory)) {
   DCHECK(ocr_engine_);
+  DCHECK(bitmap_factory_);
 }
 
 TextDetectionImplWin::~TextDetectionImplWin() = default;
 
 void TextDetectionImplWin::Detect(const SkBitmap& bitmap,
                                   DetectCallback callback) {
-  std::move(callback).Run(std::vector<mojom::TextDetectionResultPtr>());
+  if ((async_recognize_ops_ = BeginDetect(bitmap))) {
+    // Hold on the callback until AsyncOperation completes.
+    recognize_text_callback_ = std::move(callback);
+    // This prevents the Detect function from being called before the
+    // AsyncOperation completes.
+    binding_->PauseIncomingMethodCallProcessing();
+  } else {
+    // No detection taking place; run |callback| with an empty array of results.
+    std::move(callback).Run(std::vector<mojom::TextDetectionResultPtr>());
+  }
+}
+
+std::unique_ptr<AsyncOperation<OcrResult>> TextDetectionImplWin::BeginDetect(
+    const SkBitmap& bitmap) {
+  Microsoft::WRL::ComPtr<ISoftwareBitmap> win_bitmap =
+      CreateWinBitmapFromSkBitmap(bitmap, bitmap_factory_.Get());
+  if (!win_bitmap)
+    return nullptr;
+
+  // Recognize text asynchronously.
+  AsyncOperation<OcrResult>::IAsyncOperationPtr async_op;
+  const HRESULT hr = ocr_engine_->RecognizeAsync(win_bitmap.Get(), &async_op);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "Recognize text asynchronously failed: "
+                << logging::SystemErrorCodeToString(hr);
+    return nullptr;
+  }
+
+  // The once callback will not be called if this object is deleted, so it's
+  // fine to use Unretained to bind the callback.
+  // |win_bitmap| needs to be kept alive until OnTextDetected().
+  return AsyncOperation<OcrResult>::Create(
+      base::BindOnce(&TextDetectionImplWin::OnTextDetected,
+                     base::Unretained(this), std::move(win_bitmap)),
+      std::move(async_op));
+}
+
+std::vector<mojom::TextDetectionResultPtr>
+TextDetectionImplWin::BuildTextDetectionResult(
+    AsyncOperation<OcrResult>::IAsyncOperationPtr async_op) {
+  std::vector<mojom::TextDetectionResultPtr> results;
+  Microsoft::WRL::ComPtr<IOcrResult> ocr_result;
+  HRESULT hr =
+      async_op ? async_op->GetResults(ocr_result.GetAddressOf()) : E_FAIL;
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "GetResults failed: "
+                << logging::SystemErrorCodeToString(hr);
+    return results;
+  }
+
+  Microsoft::WRL::ComPtr<IVectorView<OcrLine*>> ocr_lines;
+  hr = ocr_result->get_Lines(ocr_lines.GetAddressOf());
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "Get Lines failed: " << logging::SystemErrorCodeToString(hr);
+    return results;
+  }
+
+  uint32_t count;
+  hr = ocr_lines->get_Size(&count);
+  if (FAILED(hr)) {
+    DLOG(ERROR) << "get_Size failed: " << logging::SystemErrorCodeToString(hr);
+    return results;
+  }
+
+  results.reserve(count);
+  for (uint32_t i = 0; i < count; ++i) {
+    Microsoft::WRL::ComPtr<IOcrLine> line;
+    hr = ocr_lines->GetAt(i, &line);
+    if (FAILED(hr))
+      break;
+
+    HSTRING text;
+    hr = line->get_Text(&text);
+    if (FAILED(hr))
+      break;
+
+    auto result = shape_detection::mojom::TextDetectionResult::New();
+    result->raw_value = ScopedHString(text).GetAsUTF8();
+    results.push_back(std::move(result));
+  }
+  return results;
+}
+
+// |win_bitmap| is passed here so that it is kept alive until the AsyncOperation
+// completes because RecognizeAsync does not hold a reference.
+void TextDetectionImplWin::OnTextDetected(
+    Microsoft::WRL::ComPtr<ISoftwareBitmap> /* win_bitmap */,
+    AsyncOperation<OcrResult>::IAsyncOperationPtr async_op) {
+  std::move(recognize_text_callback_)
+      .Run(BuildTextDetectionResult(std::move(async_op)));
+  async_recognize_ops_.reset();
+  binding_->ResumeIncomingMethodCallProcessing();
 }
 
 }  // namespace shape_detection
diff --git a/services/shape_detection/text_detection_impl_win.h b/services/shape_detection/text_detection_impl_win.h
index 52e78d5a..844be862 100644
--- a/services/shape_detection/text_detection_impl_win.h
+++ b/services/shape_detection/text_detection_impl_win.h
@@ -5,29 +5,55 @@
 #ifndef SERVICES_SHAPE_DETECTION_TEXT_DETECTION_IMPL_WIN_H_
 #define SERVICES_SHAPE_DETECTION_TEXT_DETECTION_IMPL_WIN_H_
 
+#include <windows.graphics.imaging.h>
 #include <windows.media.ocr.h>
 #include <wrl/client.h>
+#include <memory>
+#include <utility>
+#include <vector>
 
 #include "base/macros.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/shape_detection/detection_utils_win.h"
 #include "services/shape_detection/public/interfaces/textdetection.mojom.h"
 
 class SkBitmap;
 
 namespace shape_detection {
 
+using ABI::Windows::Graphics::Imaging::ISoftwareBitmapStatics;
 using ABI::Windows::Media::Ocr::IOcrEngine;
+using ABI::Windows::Media::Ocr::IOcrResult;
+using ABI::Windows::Media::Ocr::OcrResult;
 
 class TextDetectionImplWin : public mojom::TextDetection {
  public:
-  explicit TextDetectionImplWin(Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine);
+  TextDetectionImplWin(
+      Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine,
+      Microsoft::WRL::ComPtr<ISoftwareBitmapStatics> bitmap_factory);
   ~TextDetectionImplWin() override;
 
   // mojom::TextDetection implementation.
   void Detect(const SkBitmap& bitmap,
               mojom::TextDetection::DetectCallback callback) override;
 
+  void SetBinding(mojo::StrongBindingPtr<mojom::TextDetection> binding) {
+    binding_ = std::move(binding);
+  }
+
  private:
   Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine_;
+  Microsoft::WRL::ComPtr<ISoftwareBitmapStatics> bitmap_factory_;
+  std::unique_ptr<AsyncOperation<OcrResult>> async_recognize_ops_;
+  DetectCallback recognize_text_callback_;
+  mojo::StrongBindingPtr<mojom::TextDetection> binding_;
+
+  std::unique_ptr<AsyncOperation<OcrResult>> BeginDetect(
+      const SkBitmap& bitmap);
+  std::vector<mojom::TextDetectionResultPtr> BuildTextDetectionResult(
+      AsyncOperation<OcrResult>::IAsyncOperationPtr async_op);
+  void OnTextDetected(Microsoft::WRL::ComPtr<ISoftwareBitmap> win_bitmap,
+                      AsyncOperation<OcrResult>::IAsyncOperationPtr async_op);
 
   DISALLOW_COPY_AND_ASSIGN(TextDetectionImplWin);
 };
diff --git a/services/shape_detection/text_detection_impl_win_unittest.cc b/services/shape_detection/text_detection_impl_win_unittest.cc
index c8a286ef..34c6dc25 100644
--- a/services/shape_detection/text_detection_impl_win_unittest.cc
+++ b/services/shape_detection/text_detection_impl_win_unittest.cc
@@ -7,7 +7,10 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/macros.h"
+#include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/win/scoped_com_initializer.h"
@@ -16,16 +19,16 @@
 #include "services/shape_detection/public/interfaces/textdetection.mojom.h"
 #include "services/shape_detection/text_detection_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkImage.h"
+#include "ui/gfx/codec/png_codec.h"
 
 namespace shape_detection {
 
 namespace {
 
 void DetectTextCallback(base::Closure quit_closure,
-                        size_t* num_text_chunks,
-                        std::vector<mojom::TextDetectionResultPtr> results) {
-  *num_text_chunks = results.size();
+                        std::vector<mojom::TextDetectionResultPtr>* results_out,
+                        std::vector<mojom::TextDetectionResultPtr> results_in) {
+  *results_out = std::move(results_in);
   quit_closure.Run();
 }
 
@@ -59,17 +62,34 @@
   auto request = mojo::MakeRequest(&text_service);
   TextDetectionImpl::Create(std::move(request));
 
+  // Load image data from test directory.
+  base::FilePath image_path;
+  ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &image_path));
+  image_path = image_path.Append(FILE_PATH_LITERAL("services"))
+                   .Append(FILE_PATH_LITERAL("test"))
+                   .Append(FILE_PATH_LITERAL("data"))
+                   .Append(FILE_PATH_LITERAL("text_detection.png"));
+  ASSERT_TRUE(base::PathExists(image_path));
+  std::string image_data;
+  ASSERT_TRUE(base::ReadFileToString(image_path, &image_data));
+
   SkBitmap bitmap;
-  bitmap.allocN32Pixels(100, 100);
-  bitmap.eraseColor(SK_ColorBLUE);
+  gfx::PNGCodec::Decode(reinterpret_cast<const uint8_t*>(image_data.data()),
+                        image_data.size(), &bitmap);
+
+  const gfx::Size size(bitmap.width(), bitmap.height());
+  const uint32_t num_bytes = size.GetArea() * 4 /* bytes per pixel */;
+  ASSERT_EQ(num_bytes, bitmap.computeByteSize());
 
   base::RunLoop run_loop;
-  size_t num_text_chunks = 1u;
+  std::vector<mojom::TextDetectionResultPtr> results;
   text_service->Detect(
-      bitmap, base::BindOnce(&DetectTextCallback, run_loop.QuitClosure(),
-                             &num_text_chunks));
+      bitmap,
+      base::BindOnce(&DetectTextCallback, run_loop.QuitClosure(), &results));
   run_loop.Run();
-  EXPECT_EQ(0u, num_text_chunks);
+  ASSERT_EQ(2u, results.size());
+  EXPECT_EQ("The Chromium Project website is:", results[0]->raw_value);
+  EXPECT_EQ("https://www.chromium.org", results[1]->raw_value);
 }
 
 }  // namespace shape_detection
diff --git a/services/test/data/text_detection.png b/services/test/data/text_detection.png
new file mode 100644
index 0000000..6dddb69
--- /dev/null
+++ b/services/test/data/text_detection.png
Binary files differ
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
index 37bb5fa..875737f 100644
--- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -638,20 +638,20 @@
 # Switch test from using a custom net::URLRequestFileJob to using a test
 # URLLoaderFactory via SetNetworkFactoryForTesting.
 -ErrorPageOfflineTestWithAllowDinosaurFalse.CheckEasterEggIsDisabled
--ErrorPageTest.CheckEasterEggIsNotDisabled
--ErrorPageTest.DNSError_Basic
--ErrorPageTest.DNSError_DoClickLink
--ErrorPageTest.DNSError_DoReload
--ErrorPageTest.DNSError_DoReloadAfterSameDocumentNavigation
--ErrorPageTest.DNSError_DoSearch
--ErrorPageTest.DNSError_GoBack1
--ErrorPageTest.DNSError_GoBack2
--ErrorPageTest.DNSError_GoBack2AndForward
--ErrorPageTest.DNSError_GoBack2Forward2
--ErrorPageTest.Empty404
--ErrorPageTest.Failed
--ErrorPageTest.SniffSmallHttpErrorResponseAsDownload
--ErrorPageTest.StaleCacheStatus
+-DNSErrorPageTest.CheckEasterEggIsNotDisabled
+-DNSErrorPageTest.DNSError_Basic
+-DNSErrorPageTest.DNSError_DoClickLink
+-DNSErrorPageTest.DNSError_DoReload
+-DNSErrorPageTest.DNSError_DoReloadAfterSameDocumentNavigation
+-DNSErrorPageTest.DNSError_DoSearch
+-DNSErrorPageTest.DNSError_GoBack1
+-DNSErrorPageTest.DNSError_GoBack2
+-DNSErrorPageTest.DNSError_GoBack2AndForward
+-DNSErrorPageTest.DNSError_GoBack2Forward2
+-DNSErrorPageTest.Empty404
+-DNSErrorPageTest.Failed
+-DNSErrorPageTest.SniffSmallHttpErrorResponseAsDownload
+-DNSErrorPageTest.StaleCacheStatus
 
 # Switch test from using a net::URLRequestFileJob that adds load timing to
 # to using a test URLLoaderFactory via SetNetworkFactoryForTesting.
diff --git a/testing/buildbot/scripts/upload_test_result_artifacts.py b/testing/buildbot/scripts/upload_test_result_artifacts.py
index a3ca0a1..92324fd9 100755
--- a/testing/buildbot/scripts/upload_test_result_artifacts.py
+++ b/testing/buildbot/scripts/upload_test_result_artifacts.py
@@ -104,20 +104,6 @@
 
 
 def hash_artifacts(tests, artifact_root):
-  """Hash artifacts in a set of tests.
-
-  Args:
-   * tests: A dictionary containing tests which have some artifacts. Format is
-     a mapping of test name to test object. This object will have a key
-     'artifacts' which should be a dictionary mapping artifact name to relative
-     location. This dictionary is mutated to rewrite locations to be the hashes
-     of the files.
-   * artifact_root: The local directory where the artifacts are located.
-
-  Returns:
-    A list of tuples. Each tuple contains the file contents digest, and the
-      location of the file on disk.
-  """
   hashed_artifacts = []
   # Sort for testing consistency.
   for test_obj in sorted(tests.values()):
@@ -135,20 +121,15 @@
 
 
 def prep_artifacts_for_gs_upload(hashed_artifacts, tempdir):
-  """Prepare hashed artifacts for upload to google storage.
-
-  Moves each file into the given temp directory.
-  """
   for file_digest, absolute_filepath in hashed_artifacts:
     new_location = os.path.join(tempdir, file_digest)
 
-    # Since the filename is the hash of the contents of the file, it might
-    # already exist.
+    # Since we used content addressed hashing, the file might already exist.
     if not os.path.exists(new_location):
       shutil.copyfile(absolute_filepath, new_location)
 
 
-def upload_artifacts(data, artifact_root, dry_run):
+def upload_artifacts(data, artifact_root, dry_run, bucket):
   """Uploads artifacts to google storage.
 
   Args:
@@ -164,8 +145,6 @@
   local_data = copy.deepcopy(data)
   type_info = local_data['artifact_type_info']
 
-  # TODO(martiniss): Add support for uploading to other buckets.
-  bucket = 'chromium-test-artifacts'
   # Put the hashing algorithm as part of the filename, so that it's
   # easier to change the algorithm if we need to in the future.
   gs_path = 'sha1'
@@ -211,6 +190,9 @@
                       )
   parser.add_argument('--artifact-root', required=True, type=os.path.realpath,
                       help='The file path where artifact locations are rooted.')
+  parser.add_argument('--bucket', default='chromium-test-artifacts',
+                      help='The google storage bucket to upload artifacts to.'
+                      ' The default bucket is public and accessible by anyone.')
   parser.add_argument('-q', '--quiet', action='store_true',
                       help='If set, does not print the transformed json file'
                            ' to stdout.')
@@ -226,7 +208,8 @@
         args.test_result_file, 'artifact_type_info')
     return 1
 
-  new_data = upload_artifacts(data, args.artifact_root, args.dry_run)
+  new_data = upload_artifacts(
+      data, args.artifact_root, args.dry_run, args.bucket)
   if args.output_file:
     with open(args.output_file, 'w') as f:
       json.dump(new_data, f)
diff --git a/testing/buildbot/scripts/upload_test_result_artifacts_unittest.py b/testing/buildbot/scripts/upload_test_result_artifacts_unittest.py
index b5a5809..5c34a7ee 100644
--- a/testing/buildbot/scripts/upload_test_result_artifacts_unittest.py
+++ b/testing/buildbot/scripts/upload_test_result_artifacts_unittest.py
@@ -10,7 +10,8 @@
 import string
 import tempfile
 import unittest
-import upload_test_result_artifacts as UTRA
+
+import upload_test_result_artifacts
 
 
 class UploadTestResultArtifactsTest(unittest.TestCase):
@@ -57,8 +58,8 @@
     }
 
   def _loadTest(self, json_data, upload):
-    return UTRA.upload_artifacts(
-        json_data, '/tmp', upload)
+    return upload_test_result_artifacts.upload_artifacts(
+        json_data, '/tmp', upload, 'test-bucket')
 
 
   def loadTestEndToEndSimple(self):
@@ -80,7 +81,7 @@
   ### End load test section.
 
   def testGetTestsSimple(self):
-    self.assertEqual(UTRA.get_tests({
+    self.assertEqual(upload_test_result_artifacts.get_tests({
       'foo': {
         'expected': 'PASS',
         'actual': 'PASS',
@@ -93,7 +94,7 @@
     })
 
   def testGetTestsNested(self):
-    self.assertEqual(UTRA.get_tests({
+    self.assertEqual(upload_test_result_artifacts.get_tests({
       'foo': {
         'bar': {
           'baz': {
@@ -119,7 +120,7 @@
 
   def testGetTestsError(self):
     with self.assertRaises(ValueError):
-      UTRA.get_tests([])
+      upload_test_result_artifacts.get_tests([])
 
   def testUploadArtifactsMissingType(self):
     """Tests that the type information is used for validation."""
@@ -138,7 +139,8 @@
         }
     }
     with self.assertRaises(ValueError):
-      UTRA.upload_artifacts(data, '/tmp', True)
+      upload_test_result_artifacts.upload_artifacts(
+          data, '/tmp', True, 'test-bucket')
 
   @mock.patch('upload_test_result_artifacts.get_file_digest')
   @mock.patch('upload_test_result_artifacts.tempfile.mkdtemp')
@@ -159,7 +161,8 @@
           }
         }
     }
-    self.assertEqual(UTRA.upload_artifacts(data, '/tmp', True), data)
+    self.assertEqual(upload_test_result_artifacts.upload_artifacts(
+        data, '/tmp', True, 'test-bucket'), data)
     mkd_patch.assert_called_once_with(prefix='upload_test_artifacts')
     digest_patch.assert_not_called()
     copy_patch.assert_not_called()
@@ -191,7 +194,8 @@
           }
         }
     }
-    self.assertEqual(UTRA.upload_artifacts(data, '/tmp', True), {
+    self.assertEqual(upload_test_result_artifacts.upload_artifacts(
+        data, '/tmp', True, 'test-bucket'), {
         'artifact_type_info': {
             'log': 'text/plain'
         },
@@ -250,7 +254,8 @@
           },
         }
     }
-    self.assertEqual(UTRA.upload_artifacts(data, '/tmp', True), {
+    self.assertEqual(upload_test_result_artifacts.upload_artifacts(
+        data, '/tmp', True, 'test-bucket'), {
         'artifact_type_info': {
             'log': 'text/plain',
             'screenshot': 'image/png',
@@ -295,7 +300,7 @@
       f.write('a')
 
     self.assertEqual(
-        UTRA.get_file_digest(path),
+        upload_test_result_artifacts.get_file_digest(path),
         '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8')
 
 if __name__ == '__main__':
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index abf9546..486f88f 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -450,9 +450,7 @@
 crbug.com/591099 css1/pseudo/firstline.html [ Failure ]
 crbug.com/591099 css1/pseudo/multiple_pseudo_elements.html [ Crash ]
 crbug.com/591099 css1/pseudo/pseudo_elements_in_selectors.html [ Failure ]
-crbug.com/714962 css1/text_properties/text_align.html [ Failure ]
 crbug.com/591099 css1/text_properties/text_decoration.html [ Crash Failure ]
-crbug.com/591099 css1/text_properties/text_indent.html [ Failure ]
 crbug.com/591099 css1/text_properties/text_transform.html [ Failure ]
 crbug.com/591099 css1/units/color_units.html [ Failure ]
 crbug.com/591099 css1/units/length_units.html [ Failure ]
@@ -502,7 +500,6 @@
 crbug.com/714962 css2.1/20110323/overflow-applies-to-012.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/table-caption-001.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/table-caption-002.htm [ Failure ]
-crbug.com/591099 css2.1/20110323/table-caption-horizontal-alignment-001.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/table-caption-margins-001.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/table-caption-optional-001.htm [ Failure ]
 crbug.com/591099 css2.1/20110323/table-caption-optional-002.htm [ Failure ]
@@ -880,7 +877,6 @@
 crbug.com/591099 css2.1/t1601-c547-indent-00-b-a.html [ Failure ]
 crbug.com/591099 css2.1/t1601-c547-indent-01-d.html [ Failure ]
 crbug.com/591099 css2.1/t1602-c43-center-00-d-ag.html [ Failure ]
-crbug.com/591099 css2.1/t1602-c546-txt-align-00-b.html [ Failure ]
 crbug.com/591099 css2.1/t1604-c542-letter-sp-00-b-a.html [ Failure ]
 crbug.com/591099 css2.1/t1604-c542-letter-sp-01-b-a.html [ Failure ]
 crbug.com/591099 css2.1/t1605-c545-txttrans-00-b-ag.html [ Failure ]
@@ -1897,7 +1893,6 @@
 crbug.com/591099 editing/execCommand/5142012-1.html [ Failure ]
 crbug.com/591099 editing/execCommand/5190926.html [ Failure ]
 crbug.com/591099 editing/execCommand/5569741.html [ Failure ]
-crbug.com/591099 editing/execCommand/align-in-span.html [ Failure ]
 crbug.com/714962 editing/execCommand/button.html [ Failure ]
 crbug.com/591099 editing/execCommand/findString-2.html [ Failure ]
 crbug.com/591099 editing/execCommand/findString.html [ Failure ]
@@ -2243,7 +2238,6 @@
 crbug.com/591099 external/wpt/css/CSS2/text/text-indent-012.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/591099 external/wpt/css/CSS2/text/text-indent-percent-001.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 Pass ]
@@ -2620,34 +2614,34 @@
 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/abs-pos-non-replaced-icb-vrl-030.xht [ Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure 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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure Pass ]
 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 Pass ]
+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 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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-023.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-029.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-031.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-033.xht [ Failure Pass ]
+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 Pass ]
 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 Pass ]
 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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-045.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-047.xht [ Failure Pass ]
+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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-051.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure Pass ]
+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 Pass ]
 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 Pass ]
@@ -2674,13 +2668,13 @@
 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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure Pass ]
 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 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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-131.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-133.xht [ Failure Pass ]
@@ -2699,7 +2693,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-159.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-161.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-163.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-165.xht [ Failure Pass ]
+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 Pass ]
 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 Pass ]
@@ -2712,17 +2706,17 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-193.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-195.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-197.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-199.xht [ Failure Pass ]
 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 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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-209.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-213.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-215.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure Pass ]
@@ -2742,7 +2736,7 @@
 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 Pass ]
+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 ]
@@ -2765,7 +2759,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure Pass ]
 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 Pass ]
+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 Pass ]
 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 ]
@@ -2778,7 +2772,7 @@
 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 Pass ]
+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 ]
@@ -2813,7 +2807,7 @@
 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 Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-168.xht [ Failure Pass ]
+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 Pass ]
@@ -2837,7 +2831,7 @@
 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 Pass ]
+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 ]
@@ -2944,15 +2938,15 @@
 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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-005.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure Pass ]
 crbug.com/591099 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 Pass ]
+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 Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure Pass ]
@@ -2966,12 +2960,8 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-layout-rules-001.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vlr-007.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vlr-009.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-011.xht [ Failure Pass ]
 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-vlr-015.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vlr-017.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-002.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-004.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-006.xht [ Failure ]
@@ -3211,8 +3201,7 @@
 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/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/media-elements/mime-types/canPlayType.html [ Failure Pass ]
+crbug.com/591099 external/wpt/html/semantics/document-metadata/the-link-element/stylesheet-change-href.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 ]
 crbug.com/591099 external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html [ Failure ]
@@ -3255,20 +3244,7 @@
 crbug.com/714962 external/wpt/intersection-observer/root-margin.html [ Failure ]
 crbug.com/591099 external/wpt/intersection-observer/same-document-root.html [ Failure ]
 crbug.com/591099 external/wpt/longtask-timing/longtask-in-sibling-iframe.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/media-source/mediasource-addsourcebuffer.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-buffered.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-config-change-mp4-a-bitrate.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-config-change-mp4-av-audio-bitrate.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-config-change-mp4-av-framesize.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-config-change-mp4-av-video-bitrate.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-config-change-mp4-v-bitrate.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-config-change-mp4-v-framerate.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-config-change-mp4-v-framesize.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-endofstream.html [ Failure Pass ]
 crbug.com/591099 external/wpt/media-source/mediasource-getvideoplaybackquality.html [ Timeout ]
-crbug.com/591099 external/wpt/media-source/mediasource-is-type-supported.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-sequencemode-append-buffer.html [ Failure Pass ]
-crbug.com/591099 external/wpt/media-source/mediasource-sourcebuffer-mode-timestamps.html [ Failure Pass ]
 crbug.com/591099 external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html [ Pass ]
 crbug.com/591099 external/wpt/mimesniff/mime-types/parsing.any.html [ Timeout ]
 crbug.com/591099 external/wpt/mimesniff/mime-types/parsing.any.worker.html [ Timeout ]
@@ -3296,7 +3272,7 @@
 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 [ Pass 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 ]
@@ -3434,10 +3410,7 @@
 crbug.com/591099 fast/backgrounds/size/contain-and-cover.html [ Failure ]
 crbug.com/591099 fast/backgrounds/size/zero.html [ Failure ]
 crbug.com/591099 fast/backgrounds/svg-as-mask.html [ Failure ]
-crbug.com/591099 fast/block/basic/011.html [ Failure ]
 crbug.com/591099 fast/block/basic/014.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/basic/020.html [ Failure ]
 crbug.com/591099 fast/block/basic/quirk-height.html [ Failure ]
 crbug.com/591099 fast/block/basic/quirk-percent-height-grandchild.html [ Failure ]
@@ -3450,7 +3423,6 @@
 crbug.com/591099 fast/block/float-avoids-padding-inline-ancestors.html [ Crash ]
 crbug.com/591099 fast/block/float/003.html [ Failure ]
 crbug.com/591099 fast/block/float/010.html [ Failure ]
-crbug.com/591099 fast/block/float/014.html [ Failure ]
 crbug.com/714962 fast/block/float/015.html [ Failure ]
 crbug.com/591099 fast/block/float/018.html [ Failure ]
 crbug.com/714962 fast/block/float/021.html [ Failure ]
@@ -3459,30 +3431,17 @@
 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/591099 fast/block/float/assert-when-moving-float-2.html [ Failure ]
-crbug.com/591099 fast/block/float/assert-when-moving-float.html [ Failure ]
-crbug.com/714962 fast/block/float/avoidance-percent-width-strict.html [ Failure ]
-crbug.com/591099 fast/block/float/block-with-negative-margin-clears-float.html [ Failure ]
 crbug.com/591099 fast/block/float/br-with-clear-2.html [ Failure ]
-crbug.com/591099 fast/block/float/centered-float-avoidance-complexity.html [ Failure ]
-crbug.com/591099 fast/block/float/crash-replaced-display-block.html [ Failure ]
 crbug.com/591099 fast/block/float/element-clears-float-without-clearance.html [ Failure ]
-crbug.com/591099 fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-vertical-rl.html [ Failure ]
-crbug.com/591099 fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied.html [ Failure ]
 crbug.com/591099 fast/block/float/float-avoidance.html [ Failure ]
 crbug.com/591099 fast/block/float/float-forced-below-other-floats.html [ Failure ]
 crbug.com/591099 fast/block/float/float-in-float-hit-testing.html [ Failure ]
 crbug.com/591099 fast/block/float/float-in-float-painting.html [ Failure ]
-crbug.com/591099 fast/block/float/float-inserted-into-clean-line.html [ Failure ]
 crbug.com/591099 fast/block/float/float-on-line-obeys-container-padding.html [ Failure Pass ]
-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/591099 fast/block/float/floats-and-text-indent-rl.html [ Failure ]
-crbug.com/591099 fast/block/float/floats-and-text-indent.html [ Failure ]
-crbug.com/591099 fast/block/float/floats-do-not-overhang-from-block-formatting-context.html [ Failure ]
+crbug.com/591099 fast/block/float/float-should-dirty-line-when-adjacent-to-line-breaks-2.html [ Failure ]
+crbug.com/591099 fast/block/float/float-should-dirty-line-when-adjacent-to-line-breaks.html [ Failure ]
 crbug.com/591099 fast/block/float/floats-offset-image-strict-line-height.html [ Failure ]
 crbug.com/591099 fast/block/float/floats-offset-inline-block-strict-line-height.html [ Failure ]
-crbug.com/591099 fast/block/float/independent-align-positioning.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 ]
@@ -3504,16 +3463,11 @@
 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/714962 fast/block/float/relayout-nested-float-after-line.html [ Failure ]
-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/714962 fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ]
-crbug.com/591099 fast/block/float/trailing-float-with-columns.html [ Failure ]
-crbug.com/591099 fast/block/inline-children-root-linebox-crash.html [ Failure ]
 crbug.com/714962 fast/block/layer-not-removed-from-parent-crash.html [ Failure ]
 crbug.com/591099 fast/block/line-layout/floats-do-not-fit-on-line.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/591099 fast/block/margin-collapse/103.html [ Failure ]
 crbug.com/591099 fast/block/margin-collapse/clear-nested-float-more-than-one-previous-sibling-away.html [ Failure ]
 crbug.com/714962 fast/block/margin-collapse/line-beside-float-complex-margin-collapsing.html [ Failure ]
 crbug.com/591099 fast/block/margin-collapse/webkit-margin-collapse-container.html [ Failure ]
@@ -3560,7 +3514,6 @@
 crbug.com/591099 fast/block/positioning/rel-positioned-inline-changes-width.html [ Crash ]
 crbug.com/591099 fast/block/positioning/relative-overflow-block.html [ Failure Pass ]
 crbug.com/591099 fast/block/positioning/relative-overflow-replaced.html [ Failure ]
-crbug.com/591099 fast/block/positioning/relayout-nested-positioned-elements-crash-2.html [ Failure ]
 crbug.com/591099 fast/block/positioning/removing-inside-relpositioned-inline-crash.html [ Crash ]
 crbug.com/591099 fast/block/positioning/rtl-static-positioning.html [ Failure ]
 crbug.com/591099 fast/block/positioning/table-cell-static-position.html [ Failure Pass ]
@@ -3570,8 +3523,6 @@
 crbug.com/591099 fast/block/positioning/vertical-rl/002.html [ Failure ]
 crbug.com/591099 fast/block/scrollbar-wider-than-border-box.html [ Failure ]
 crbug.com/591099 fast/block/sticky-position-containing-block-crash.html [ Crash Pass ]
-crbug.com/591099 fast/block/strip-anonymous-blocks-when-block-child-becomes-float.html [ Failure ]
-crbug.com/591099 fast/block/update-midpoints-for-trailing-boxes-crash.html [ Failure Pass ]
 crbug.com/591099 fast/body-propagation/background-color/001-xhtml.xhtml [ Failure ]
 crbug.com/591099 fast/body-propagation/background-color/001.html [ Failure ]
 crbug.com/591099 fast/body-propagation/background-color/002-xhtml.xhtml [ Failure ]
@@ -4179,8 +4130,6 @@
 crbug.com/591099 fast/css/table-text-align-quirk.html [ Failure ]
 crbug.com/591099 fast/css/table-text-align-strict.html [ Failure ]
 crbug.com/714962 fast/css/text-align-webkit-match-parent.html [ Failure ]
-crbug.com/591099 fast/css/text-align.html [ Failure ]
-crbug.com/734554 fast/css/text-indent-first-line-002.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-bidi.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-block-with-border-and-padding.html [ Failure ]
 crbug.com/591099 fast/css/text-overflow-ellipsis-button.html [ Failure ]
@@ -5198,7 +5147,6 @@
 crbug.com/591099 fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ]
 crbug.com/714962 fast/inline/inline-offsetLeft-continuation.html [ Failure ]
 crbug.com/591099 fast/inline/inline-offsetLeft-relpos.html [ Crash Failure ]
-crbug.com/591099 fast/inline/inline-position-top-align.html [ Failure ]
 crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ]
 crbug.com/591099 fast/inline/justify-emphasis-inline-box.html [ Failure ]
 crbug.com/591099 fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ]
@@ -5253,7 +5201,6 @@
 crbug.com/591099 fast/layers/layer-visibility-sublayer.html [ Failure ]
 crbug.com/591099 fast/layers/layer-visibility.html [ Failure ]
 crbug.com/591099 fast/layers/nested-layers-1.html [ Failure ]
-crbug.com/591099 fast/layers/normal-flow-hit-test.html [ Failure ]
 crbug.com/591099 fast/layers/opacity-outline.html [ Failure ]
 crbug.com/591099 fast/layers/opacity-transforms.html [ Failure ]
 crbug.com/591099 fast/layers/overflow-hidden-rounded-corners-occlusion.html [ Failure ]
@@ -5560,8 +5507,6 @@
 crbug.com/591099 fast/multicol/newmulticol/spanner-inside-child-crash.html [ Crash ]
 crbug.com/591099 fast/multicol/newmulticol/table-cell.html [ Failure ]
 crbug.com/591099 fast/multicol/newmulticol/unresolvable-percent-max-height-2.html [ Failure ]
-crbug.com/591099 fast/multicol/orphaned-line-at-exact-top-of-column.html [ Failure ]
-crbug.com/591099 fast/multicol/orphans-relayout.html [ Failure ]
 crbug.com/591099 fast/multicol/out-of-flow/abspos-auto-left-right.html [ Pass ]
 crbug.com/591099 fast/multicol/out-of-flow/abspos-auto-position-on-line-at-boundary.html [ Crash Failure ]
 crbug.com/591099 fast/multicol/out-of-flow/abspos-auto-position-on-line-rtl.html [ Crash Failure ]
@@ -6477,10 +6422,6 @@
 crbug.com/591099 fast/tokenizer/missing-style-end-tag-2.html [ Failure ]
 crbug.com/591099 fast/tokenizer/nested-cached-scripts-and-stylesheet.html [ Failure ]
 crbug.com/591099 fast/tokenizer/script_extra_close.html [ Failure ]
-crbug.com/591099 fast/webgl/texImage-imageBitmap-from-canvas-resize.html [ Failure Pass ]
-crbug.com/591099 fast/webgl/texImage-imageBitmap-from-image-resize.html [ Failure Pass ]
-crbug.com/591099 fast/webgl/texImage-imageBitmap-from-imageData-resize.html [ Failure Pass ]
-crbug.com/591099 fast/webgl/texImage-imageBitmap-from-offscreen-canvas-resize.html [ Failure 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 ]
@@ -6642,7 +6583,7 @@
 crbug.com/591099 fullscreen/full-screen-css.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-element-stack.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-iframe-not-allowed.html [ Failure Timeout ]
-crbug.com/591099 fullscreen/full-screen-remove-ancestor-after.html [ Crash ]
+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 ]
 crbug.com/591099 fullscreen/full-screen-with-css-reference-filter.html [ Crash ]
@@ -6790,7 +6731,7 @@
 crbug.com/591099 http/tests/csspaint/invalidation-content-image.html [ Timeout ]
 crbug.com/591099 http/tests/devtools/animation/animation-KeyframeEffectReadOnly-crash.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/animation/animation-group-matching-animations.js [ Crash Pass ]
-crbug.com/714962 http/tests/devtools/animation/animation-group-matching-transitions.js [ Crash Pass ]
+crbug.com/714962 http/tests/devtools/animation/animation-group-matching-transitions.js [ Crash ]
 crbug.com/591099 http/tests/devtools/animation/animation-timeline.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/animation/animation-transition-setTiming-crash.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/animation/animation-web-anim-negative-start-time.js [ Crash Pass ]
@@ -6823,7 +6764,7 @@
 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/591099 http/tests/devtools/elements/edit/undo-set-outer-html.js [ Crash ]
+crbug.com/591099 http/tests/devtools/elements/edit/undo-set-outer-html.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/elements-delete-inline-style.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/elements-linkify-attributes.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/elements-panel-limited-children.js [ Crash ]
@@ -6934,15 +6875,6 @@
 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/media-source/mediasource-addsourcebuffer.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-config-change-mp4-a-bitrate.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-config-change-mp4-av-audio-bitrate.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-config-change-mp4-av-framesize.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-config-change-mp4-av-video-bitrate.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-config-change-mp4-v-bitrate.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-config-change-mp4-v-framerate.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-config-change-mp4-v-framesize.html [ Failure Pass ]
-crbug.com/591099 http/tests/media/media-source/mediasource-is-type-supported.html [ Failure Pass ]
 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 ]
@@ -7274,10 +7206,6 @@
 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/591099 media/W3C/audio/canPlayType/canPlayType_supported_but_no_codecs_parameter_2.html [ Failure Pass ]
-crbug.com/591099 media/W3C/video/canPlayType/canPlayType_supported_but_no_codecs_parameter_3.html [ Failure Pass ]
-crbug.com/591099 media/W3C/video/canPlayType/canPlayType_two_implies_one_5.html [ Failure Pass ]
-crbug.com/591099 media/W3C/video/canPlayType/canPlayType_two_implies_one_6.html [ Failure Pass ]
 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 ]
@@ -7729,7 +7657,7 @@
 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 Pass ]
+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 [ Crash Failure ]
 crbug.com/591099 paint/invalidation/selection/selection-clear.html [ Failure ]
 crbug.com/714962 paint/invalidation/selection/selection-in-composited-scrolling-container.html [ Failure ]
@@ -8183,8 +8111,6 @@
 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/as-background-image/animated-svg-as-background.html [ Crash Failure ]
@@ -8495,8 +8421,6 @@
 crbug.com/591099 svg/text/small-fonts-in-html5.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 ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index 9863997a..9d6c1129 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -169,6 +169,10 @@
 virtual/layout_ng/external/wpt/css/CSS2/linebox/inline-formatting-context-006.xht [ WontFix ]
 virtual/layout_ng/external/wpt/css/CSS2/linebox/inline-formatting-context-007.xht [ WontFix ]
 
+# CSS allows justification (text-align: justify) to hang trailing preserved spaces.
+external/wpt/css/CSS2/text/text-align-white-space-003.xht [ WontFix ]
+external/wpt/css/CSS2/text/text-align-white-space-007.xht [ WontFix ]
+
 # CSS2 tests that require files in different directories.
 external/wpt/css/CSS2/linebox/inline-formatting-context-012.xht [ WontFix ]
 external/wpt/css/CSS2/normal-flow/blocks-017.xht [ WontFix ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 3ff79cf..bd0a36d 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -356,15 +356,6 @@
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-insert-001f.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-insert-002f.xht [ Failure ]
 
-# Inline: Abspos should start new block layout to compute static position
-crbug.com/740993 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-width-001.xht [ Failure ]
-crbug.com/740993 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-004.xht [ Failure ]
-crbug.com/740993 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-005.xht [ Failure ]
-crbug.com/740993 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-007.xht [ Failure ]
-crbug.com/740993 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-004.xht [ Failure ]
-crbug.com/740993 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-005.xht [ Failure ]
-crbug.com/740993 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-007.xht [ Failure ]
-
 # Block: margin collapsing.
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/root-box-001.xht [ Failure ]
 
@@ -382,7 +373,6 @@
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-002.xht [ Failure ]
 
 ### virtual/layout_ng/external/wpt/css/CSS2/positioning
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/absolute-replaced-height-001.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-007.xht [ Failure ]
 crbug.com/704961 [ Mac ] virtual/layout_ng/external/wpt/css/CSS2/positioning/abspos-027.xht [ Failure ]
 crbug.com/635619 [ Mac ] virtual/layout_ng/external/wpt/css/CSS2/positioning/position-relative-027.xht [ Failure ]
@@ -426,7 +416,6 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-inserted-into-clean-line.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-list-changed-before-layout-crash.html [ Crash Pass ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-from-next-sibling4.html [ Crash Pass ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/float-on-line-obeys-container-padding.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-reparent-during-detach-crash.html [ Crash Pass ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-and-text-indent-rl.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-and-text-indent.html [ Failure ]
@@ -590,7 +579,6 @@
 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 ]
@@ -2003,8 +1991,6 @@
 crbug.com/626703 external/wpt/beacon/beacon-navigate.html [ Timeout ]
 crbug.com/626703 external/wpt/beacon/beacon-redirect.window.html [ Timeout ]
 crbug.com/626703 external/wpt/compat/webkit-text-fill-color-property-005.html [ Failure ]
-crbug.com/626703 external/wpt/css/CSS2/text/text-align-white-space-003.xht [ Failure ]
-crbug.com/626703 external/wpt/css/CSS2/text/text-align-white-space-007.xht [ Failure ]
 crbug.com/626703 external/wpt/css/CSS2/text/text-decoration-va-length-001.xht [ Failure ]
 crbug.com/626703 external/wpt/css/CSS2/text/text-decoration-va-length-002.xht [ Failure ]
 crbug.com/626703 external/wpt/css/CSS2/text/white-space-collapsing-bidi-001.xht [ Failure ]
@@ -2759,7 +2745,6 @@
 crbug.com/709227 external/wpt/websockets/constructor/006.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/constructor/009.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/constructor/013.html?wss [ Failure ]
-crbug.com/709227 external/wpt/websockets/constructor/014.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/constructor/016.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/constructor/018.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/constructor/019.html?wss [ Failure ]
@@ -2791,7 +2776,6 @@
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/009.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/011.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/012.html?wss [ Failure ]
-crbug.com/709227 external/wpt/websockets/keeping-connection-open/001.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/opening-handshake/002.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/opening-handshake/003.html?wss [ Failure ]
 crbug.com/709227 external/wpt/websockets/opening-handshake/005.html [ Failure ]
@@ -2804,6 +2788,7 @@
 crbug.com/709227 external/wpt/websockets/binary/002.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/binary/004.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/binary/005.html?wss [ Timeout ]
+crbug.com/709227 external/wpt/websockets/constructor/014.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/extended-payload-length.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-arraybuffer.html?wss [ Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-blob.html?wss [ Timeout ]
@@ -2813,8 +2798,9 @@
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/005.html?wss [ Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/006.html?wss [ Timeout ]
 crbug.com/709227 external/wpt/websockets/interfaces/WebSocket/send/010.html?wss [ Timeout ]
+crbug.com/709227 external/wpt/websockets/keeping-connection-open/001.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/websockets/opening-handshake/003-sets-origin.worker.html [ Timeout ]
-crbug.com/709227 external/wpt/websockets/opening-handshake/005.html?wss [ Timeout ]
+crbug.com/709227 external/wpt/websockets/opening-handshake/005.html?wss [ Failure Timeout ]
 crbug.com/709227 external/wpt/workers/nested_worker.worker.html [ Timeout ]
 
 # Crashes
@@ -2840,8 +2826,7 @@
 crbug.com/678346 [ Debug ] fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ]
 crbug.com/678346 [ Win7 Mac Debug ] storage/indexeddb/index-cursor.html [ Pass Timeout ]
 crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ]
-# Temporarily disabled due to conflicting NeedsManualRebaseline below
-# crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ]
+crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ]
 
 crbug.com/678492 http/tests/misc/webtiming-ssl.php [ Failure Pass ]
 crbug.com/678493 http/tests/permissions/chromium/test-request-window.html [ Timeout Pass ]
@@ -2853,85 +2838,6 @@
 
 crbug.com/701445 external/wpt/dom/events/EventListener-invoke-legacy.html [ Timeout Pass ]
 
-# Rebaseline for v8's --harmony-function-tostring
-crbug.com/753073 external/wpt/2dcontext/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/2dcontext/fill-and-stroke-styles/2d.pattern.image.broken.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/2dcontext/pixel-manipulation/2d.imageData.create2.nonfinite.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/2dcontext/pixel-manipulation/2d.imageData.get.nonfinite.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/2dcontext/pixel-manipulation/2d.imageData.object.ctor.array.bounds.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/2dcontext/pixel-manipulation/2d.imageData.put.nonfinite.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/FileAPI/blob/Blob-constructor.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/FileAPI/file/File-constructor.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/XMLHttpRequest/open-url-multi-window-2.htm [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/XMLHttpRequest/open-url-multi-window-3.htm [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/XMLHttpRequest/open-url-multi-window-5.htm [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/XMLHttpRequest/open-url-multi-window-6.htm [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/cors/allow-headers.htm [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/cors/origin.htm [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/css/geometry/DOMPoint-001.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/dom/collections/HTMLCollection-supported-property-indices.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/domparsing/innerhtml-01.xhtml [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/eventsource/eventsource-constructor-url-bogus.htm [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/fetch/api/headers/headers-record.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/browsers/history/the-location-interface/location-prototype-setting-same-origin-domain.sub.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/browsers/history/the-location-interface/location-prototype-setting-same-origin.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/editing/dnd/synthetic/001.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/semantics/embedded-content/the-canvas-element/imagedata.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/semantics/forms/the-form-element/form-indexed-element.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/html/webappapis/scripting/events/messageevent-constructor.https.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/keyboard-lock/idlharness.https.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/media-capabilities/idlharness.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/offscreen-canvas/pixel-manipulation/2d.imageData.create2.nonfinite.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/offscreen-canvas/pixel-manipulation/2d.imageData.get.nonfinite.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/offscreen-canvas/pixel-manipulation/2d.imageData.put.nonfinite.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/payment-request/rejects_if_not_active.https.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/screen-orientation/lock-bad-argument.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/selection/removeRange.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/uievents/legacy/Event-subclasses-init.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/url/historical.any.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/url/historical.any.worker.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/url/url-constructor.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/user-timing/invoke_with_timing_attributes.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/web-nfc/nfc_push.https.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/web-nfc/nfc_watch.https.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-addIceCandidate.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-constructor.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-createAnswer.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-getStats.https.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-answer.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-offer.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/webstorage/storage_string_conversion.html [ NeedsManualRebaseline ]
-crbug.com/753073 external/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/dom/TreeWalker/acceptNode-filter.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/dom/Window/anonymous-slot-with-changes.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/dom/Window/window-postmessage-clone.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/events/message-port-multi.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/js/JSON-parse.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/js/function-names.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/js/function-prototype.html [ NeedsManualRebaseline ]
-crbug.com/753073 fast/js/toString-and-valueOf-override.html [ NeedsManualRebaseline ]
-crbug.com/753073 http/tests/devtools/startup/console/console-format-startup.js [ NeedsManualRebaseline ]
-crbug.com/753073 http/tests/security/window-named-proto.html [ NeedsManualRebaseline ]
-crbug.com/753073 http/tests/security/xss-exception.html [ NeedsManualRebaseline ]
-crbug.com/753073 storage/domstorage/localstorage/string-conversion.html [ NeedsManualRebaseline ]
-crbug.com/753073 storage/domstorage/sessionstorage/string-conversion.html [ NeedsManualRebaseline ]
-crbug.com/753073 storage/indexeddb/structured-clone.html [ NeedsManualRebaseline ]
-crbug.com/753073 virtual/mojo-blobs/external/wpt/FileAPI/blob/Blob-constructor.html [ NeedsManualRebaseline ]
-crbug.com/753073 virtual/mojo-blobs/external/wpt/FileAPI/file/File-constructor.html [ NeedsManualRebaseline ]
-crbug.com/753073 virtual/mojo-blobs/external/wpt/fetch/api/headers/headers-record.html [ NeedsManualRebaseline ]
-crbug.com/753073 virtual/mojo-localstorage/external/wpt/webstorage/storage_string_conversion.html [ NeedsManualRebaseline ]
-crbug.com/753073 virtual/mojo-localstorage/storage/domstorage/localstorage/string-conversion.html [ NeedsManualRebaseline ]
-crbug.com/753073 virtual/mouseevent_fractional/fast/events/message-port-multi.html [ NeedsManualRebaseline ]
-crbug.com/753073 virtual/outofblink-cors/external/wpt/fetch/api/headers/headers-record.html [ NeedsManualRebaseline ]
-crbug.com/753073 webaudio/unit-tests/audit-failures.html [ NeedsManualRebaseline ]
-crbug.com/753073 webaudio/unit-tests/audit.html [ NeedsManualRebaseline ]
-
 # When WebAssembly is exposed in V8 (soon), this test has the wrong number of expected Object.getOwnPropertyNames() for global object.
 
 crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ]
@@ -3047,7 +2953,7 @@
 # Failures when using libc++.  Rebaseline after landing https://codereview.chromium.org/2933573002/
 crbug.com/734873 [ Linux ] fast/backgrounds/size/contain-and-cover.html [ Pass Failure ]
 
-crbug.com/729836 [ Win ] fast/workers/worker-document-leak.html [ Pass Failure ]
+crbug.com/729836 [ Win ] fast/workers/chromium/worker-document-leak.html [ Pass Failure ]
 
 # More flaky tests on Mac
 crbug.com/731111 [ Mac ] http/tests/media/progress-events-generated-correctly.html [ Failure Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index b00822f..ef55882 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -27365,6 +27365,42 @@
      {}
     ]
    ],
+   "css/css-backgrounds/background-color-body-propagation-001.html": [
+    [
+     "/css/css-backgrounds/background-color-body-propagation-001.html",
+     [
+      [
+       "/css/css-backgrounds/background-color-body-propagation-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-backgrounds/background-color-body-propagation-002.html": [
+    [
+     "/css/css-backgrounds/background-color-body-propagation-002.html",
+     [
+      [
+       "/css/css-backgrounds/background-color-body-propagation-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-backgrounds/background-color-body-propagation-003.html": [
+    [
+     "/css/css-backgrounds/background-color-body-propagation-003.html",
+     [
+      [
+       "/css/css-backgrounds/background-color-body-propagation-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-backgrounds/background-image-001.html": [
     [
      "/css/css-backgrounds/background-image-001.html",
@@ -38605,6 +38641,18 @@
      {}
     ]
    ],
+   "css/css-fonts/font-display/font-display-change.html": [
+    [
+     "/css/css-fonts/font-display/font-display-change.html",
+     [
+      [
+       "/css/css-fonts/font-display/font-display-change-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-fonts/font-display/font-display.html": [
     [
      "/css/css-fonts/font-display/font-display.html",
@@ -71381,6 +71429,18 @@
      {}
     ]
    ],
+   "css/css-writing-modes/bidi-table-001.html": [
+    [
+     "/css/css-writing-modes/bidi-table-001.html",
+     [
+      [
+       "/css/css-writing-modes/reference/bidi-table-001.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-writing-modes/bidi-unset-001.html": [
     [
      "/css/css-writing-modes/bidi-unset-001.html",
@@ -71969,6 +72029,18 @@
      {}
     ]
    ],
+   "css/css-writing-modes/block-plaintext-006.html": [
+    [
+     "/css/css-writing-modes/block-plaintext-006.html",
+     [
+      [
+       "/css/css-writing-modes/reference/block-plaintext-006.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-writing-modes/border-conflict-element-vlr-003.xht": [
     [
      "/css/css-writing-modes/border-conflict-element-vlr-003.xht",
@@ -92463,6 +92535,11 @@
      {}
     ]
    ],
+   "XMLHttpRequest/send-sync-response-event-order-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "XMLHttpRequest/setrequestheader-content-type-expected.txt": [
     [
      {}
@@ -94173,6 +94250,16 @@
      {}
     ]
    ],
+   "credential-management/federatedcredential-framed-get.sub.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "credential-management/passwordcredential-framed-get.sub.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "credential-management/support/echoing-nester.html": [
     [
      {}
@@ -98703,6 +98790,11 @@
      {}
     ]
    ],
+   "css/css-backgrounds/background-color-body-propagation-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-backgrounds/background-origin/list.txt": [
     [
      {}
@@ -101708,6 +101800,11 @@
      {}
     ]
    ],
+   "css/css-fonts/font-display/font-display-change-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-fonts/font-display/font-display-ref.html": [
     [
      {}
@@ -136838,6 +136935,11 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/captions-gaps.vtt": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/track/track-element/resources/class-bad.vtt": [
     [
      {}
@@ -137013,6 +137115,11 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/simple-captions.vtt": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/track/track-element/resources/timestamp-bad.vtt": [
     [
      {}
@@ -137103,6 +137210,11 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/resources/vp8-vorbis-webvtt.webm": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-file.vtt": [
     [
      {}
@@ -138873,26 +138985,6 @@
      {}
     ]
    ],
-   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-nonce-classic-expected.txt": [
     [
      {}
@@ -141798,6 +141890,16 @@
      {}
     ]
    ],
+   "media/counting.mp4": [
+    [
+     {}
+    ]
+   ],
+   "media/counting.ogv": [
+    [
+     {}
+    ]
+   ],
    "media/foo.vtt": [
     [
      {}
@@ -141868,6 +141970,16 @@
      {}
     ]
    ],
+   "media/test.mp4": [
+    [
+     {}
+    ]
+   ],
+   "media/test.ogv": [
+    [
+     {}
+    ]
+   ],
    "media/white.mp4": [
     [
      {}
@@ -182649,6 +182761,36 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-remove-active-cue.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-remove-active-cue.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-remove-by-setting-innerHTML.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-remove-by-setting-innerHTML.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-remove-insert-ready-state.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-remove-insert-ready-state.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-remove-quickly.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-remove-quickly.html",
+     {}
+    ]
+   ],
+   "html/semantics/embedded-content/media-elements/track/track-element/track-remove-track.html": [
+    [
+     "/html/semantics/embedded-content/media-elements/track/track-element/track-remove-track.html",
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-align-positioning.html": [
     [
      "/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-align-positioning.html",
@@ -224963,24 +225105,12 @@
      {}
     ]
    ],
-   "css/css-writing-modes/bidi-table-001.html": [
-    [
-     "/css/css-writing-modes/bidi-table-001.html",
-     {}
-    ]
-   ],
    "css/css-writing-modes/block-plaintext-005.html": [
     [
      "/css/css-writing-modes/block-plaintext-005.html",
      {}
     ]
    ],
-   "css/css-writing-modes/block-plaintext-006.html": [
-    [
-     "/css/css-writing-modes/block-plaintext-006.html",
-     {}
-    ]
-   ],
    "css/css-writing-modes/form-controls-slr-004.xht": [
     [
      "/css/css-writing-modes/form-controls-slr-004.xht",
@@ -225427,7 +225557,7 @@
    "support"
   ],
   "./lint.whitelist": [
-   "0213c58a15215013a47397f17bcc5fa4538fdcd2",
+   "92756bd517af0d5f9268ac86711cb1e7683ec4bb",
    "support"
   ],
   "./update-built-tests.sh": [
@@ -233494,6 +233624,10 @@
    "bf76cb8987608b7bb9f59627032826d21936f450",
    "testharness"
   ],
+  "XMLHttpRequest/send-sync-response-event-order-expected.txt": [
+   "70c00c61fbfff76b3f6042dac646624464ccb3f0",
+   "support"
+  ],
   "XMLHttpRequest/send-sync-response-event-order.htm": [
    "3e2d0154469dcdf3a04376c2c350dab681ff8fe7",
    "testharness"
@@ -237006,6 +237140,10 @@
    "4889217f5e821965907d4d60a9ffdd19d4bc79af",
    "testharness"
   ],
+  "credential-management/federatedcredential-framed-get.sub.https-expected.txt": [
+   "f352699762b0daa2c996d6c0d9c31a07d810d9f1",
+   "support"
+  ],
   "credential-management/federatedcredential-framed-get.sub.https.html": [
    "561636e62d50da2d14e50516c62cbaea1c5bb924",
    "testharness"
@@ -237014,6 +237152,10 @@
    "e9a108beef51c52bbaaf2e53371aec57e69541c0",
    "testharness"
   ],
+  "credential-management/passwordcredential-framed-get.sub.https-expected.txt": [
+   "c7ae9a7aaa435c3eaa58097601ba1878bbd80f75",
+   "support"
+  ],
   "credential-management/passwordcredential-framed-get.sub.https.html": [
    "3ce3b0a2eaa10928aec1f32c9e3bcbe2af5fafba",
    "testharness"
@@ -251222,6 +251364,22 @@
    "da703cf56e71cd9dc8ff4f7ca34b11963eb5afb3",
    "visual"
   ],
+  "css/css-backgrounds/background-color-body-propagation-001.html": [
+   "26f2d7efeb2063e8672f3f831d2bd382976a099d",
+   "reftest"
+  ],
+  "css/css-backgrounds/background-color-body-propagation-002.html": [
+   "0b9b3ffa3574c8f5e6202c5177dd5d6cfe636b16",
+   "reftest"
+  ],
+  "css/css-backgrounds/background-color-body-propagation-003.html": [
+   "f87fe8066c21356425c1eab1129a5a5c0f64b1f4",
+   "reftest"
+  ],
+  "css/css-backgrounds/background-color-body-propagation-ref.html": [
+   "843bae3267a34e4160763b16c59ea63036cd9e0b",
+   "support"
+  ],
   "css/css-backgrounds/background-color-border-box.htm": [
    "d638cc24e5598d10acfbf6d0c3a25552141a2ad5",
    "visual"
@@ -258646,6 +258804,14 @@
    "4f5d1d1f375f61a09d30ef28deda1b2a54f4c620",
    "reftest"
   ],
+  "css/css-fonts/font-display/font-display-change-ref.html": [
+   "e155492a8b8dbaa1477fddfaeea520b3a8b3fd37",
+   "support"
+  ],
+  "css/css-fonts/font-display/font-display-change.html": [
+   "c5fd3f31aca59b36b12aea67bfcd13f9fd5751b6",
+   "reftest"
+  ],
   "css/css-fonts/font-display/font-display-failure-fallback.html": [
    "9fbf0c808f338c5d668554ab62f10cfe0ca93c91",
    "testharness"
@@ -267647,15 +267813,15 @@
    "support"
   ],
   "css/css-grid/reference/grid-collapsed-row-gutters-ref.html": [
-   "917e355f17681c9f511fc5cfbfe7996cddb05f6b",
+   "15a431efb881d37ce24ab376ee3709bd4333bb11",
    "support"
   ],
   "css/css-grid/reference/grid-different-gutters-ref.html": [
-   "d37b7409505ce811a7a76db76ab7185c611fd278",
+   "bd1aecfb426cde332794b9657a7d7a905ff1b292",
    "support"
   ],
   "css/css-grid/reference/grid-equal-gutters-ref.html": [
-   "61df6964c4743d585e47e0e683c55b5cf3f10c92",
+   "9db6eaa6f9569ada08d3c231ec364f4d7e7faf6b",
    "support"
   ],
   "css/css-grid/reference/grid-filled-blue-yellow-green-overlapped-100px-squares.html": [
@@ -268407,7 +268573,7 @@
    "support"
   ],
   "css/css-multicol/multicol-rule-samelength-001.xht": [
-   "cd4022578abdf3520e603336c7f812a9a5315926",
+   "f76c5c3a3989ba945c36f9b5f60d65157675ff65",
    "reftest"
   ],
   "css/css-multicol/multicol-rule-shorthand-001.xht": [
@@ -286179,8 +286345,8 @@
    "reftest"
   ],
   "css/css-writing-modes/bidi-table-001.html": [
-   "cfad37ee8ded9dc4eec6aa5d615c73bba9ca039f",
-   "visual"
+   "f6a6a6ddac6c82a0734ec8af418c140ead454c1d",
+   "reftest"
   ],
   "css/css-writing-modes/bidi-unset-001.html": [
    "3558315a55357f817a95aa0ecbd8d62a8b1ae7a9",
@@ -286407,8 +286573,8 @@
    "visual"
   ],
   "css/css-writing-modes/block-plaintext-006.html": [
-   "cadc2347f3c345f4e1ea08ec1950641416585a07",
-   "visual"
+   "de33a946a26b9ab6f4b04b486ca02cbfc2944d90",
+   "reftest"
   ],
   "css/css-writing-modes/border-conflict-element-vlr-003.xht": [
    "2272a00893c883362930f93fff7677c1cde6532e",
@@ -302135,7 +302301,7 @@
    "support"
   ],
   "fetch/api/request/request-keepalive-quota.html": [
-   "9064b1c51be636b57b5184d5cd2d990b73b2e786",
+   "0b9786a3878a361ba8ec3291216d475bd5148541",
    "testharness"
   ],
   "fetch/api/request/request-keepalive.html": [
@@ -302243,7 +302409,7 @@
    "support"
   ],
   "fetch/api/resources/trickle.py": [
-   "adb1bc80366cf924cfe13f6c73555d999d1d8e4f",
+   "87a83b390ae91e4419dc580d8426277be48c92d8",
    "support"
   ],
   "fetch/api/resources/utils.js": [
@@ -306751,7 +306917,7 @@
    "support"
   ],
   "html/dom/elements-forms.js": [
-   "ed722f36a003a8407c1c4a13f8c75880c4fa9c11",
+   "062e50a0665b90c3b77aaca744b65036054569f5",
    "support"
   ],
   "html/dom/elements-grouping.js": [
@@ -306763,7 +306929,7 @@
    "support"
   ],
   "html/dom/elements-misc.js": [
-   "42b4ea21148dd17c442932ba8cb5e6e49db81a93",
+   "700331e76eb4de08018ef2939c750567e6a1ead5",
    "support"
   ],
   "html/dom/elements-obsolete.js": [
@@ -307599,7 +307765,7 @@
    "support"
   ],
   "html/dom/interfaces-expected.txt": [
-   "fa67b737b70ee85b4cbc15a2b2d19e83c9bab186",
+   "994711d9753c6461cce687811dcdab7c492999c8",
    "support"
   ],
   "html/dom/interfaces.html": [
@@ -307631,7 +307797,7 @@
    "testharness"
   ],
   "html/dom/reflection-forms-expected.txt": [
-   "5c2d4721c610a630bbcc9eb40ccbb6d04a372f6d",
+   "853e6f189cc45bcb1a0b42d7b7b3ed93ed4c56c0",
    "support"
   ],
   "html/dom/reflection-forms.html": [
@@ -307651,7 +307817,7 @@
    "testharness"
   ],
   "html/dom/reflection-misc-expected.txt": [
-   "a30e4a4f10a7834208ba1036232e9b05385333c8",
+   "6cf1f19e7de1a0c78c8d9ec6565415de151ceb47",
    "support"
   ],
   "html/dom/reflection-misc.html": [
@@ -314202,6 +314368,10 @@
    "68ae570e941a5b8993c163a84aca0f758d65ab01",
    "support"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/captions-gaps.vtt": [
+   "fa81809c654054d8f9d4e942782e7a4bc2826ed9",
+   "support"
+  ],
   "html/semantics/embedded-content/media-elements/track/track-element/resources/class-bad.vtt": [
    "48b56cffac57d58ed363c6de43123cf46b9a61c4",
    "support"
@@ -314342,6 +314512,10 @@
    "af042c5468830fbdcd9b9c7cbc32eb0c6d660311",
    "support"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/simple-captions.vtt": [
+   "fa3e12c456c77d1327b90b1a8f32416245268e7a",
+   "support"
+  ],
   "html/semantics/embedded-content/media-elements/track/track-element/resources/timestamp-bad.vtt": [
    "6852fb1bfcddce00b4acba93716d7358957a74e5",
    "support"
@@ -314414,6 +314588,10 @@
    "61997c207efb09802c9022fcea544f4196094df6",
    "support"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/resources/vp8-vorbis-webvtt.webm": [
+   "aae8ea4cf4b4fa88b0e88094f2e64c63df4bceb9",
+   "support"
+  ],
   "html/semantics/embedded-content/media-elements/track/track-element/resources/webvtt-file.vtt": [
    "943c4ca7d7ba197815ad5732222558e30195b022",
    "support"
@@ -314458,6 +314636,26 @@
    "b84cd1d9f96ee9b00cef2bd219e6da5b1ba1df8b",
    "support"
   ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-remove-active-cue.html": [
+   "dd3ab2e0e4f4ac3b4f83e5dfd539dd9c3aa5c961",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-remove-by-setting-innerHTML.html": [
+   "9ab3f009fe7464e26df571ec8e66dde7205fa0db",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-remove-insert-ready-state.html": [
+   "9d6735eaf36145ceeefec0630f30be49ff37d676",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-remove-quickly.html": [
+   "e955322b149ecb74471bc972a4662972fa287516",
+   "testharness"
+  ],
+  "html/semantics/embedded-content/media-elements/track/track-element/track-remove-track.html": [
+   "931cfc4d06107dfccb001fbeaeef987cca528747",
+   "testharness"
+  ],
   "html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-align-positioning.html": [
    "9283a8233cfc10c0c1745815b3f6bd970ffdde2a",
    "testharness"
@@ -318746,34 +318944,18 @@
    "03ee5763c6e62da7d49e058edb58292f4f496a3f",
    "support"
   ],
-  "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic-expected.txt": [
-   "f15dee3678e629a3fa9c39be6719dc6a64121bd1",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-classic.html": [
    "70f97beb38cf958bd2234e3b580712c8436b8095",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module-expected.txt": [
-   "f15dee3678e629a3fa9c39be6719dc6a64121bd1",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-external-module.html": [
    "7386a90307c33bdaad34002c865b4ad8793c10a2",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic-expected.txt": [
-   "ef0e42ddf8c98920970e15c05a979ecd0444b2d9",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-classic.html": [
    "928c333bf9c50213175095ceb06f1afdd690bd8a",
    "testharness"
   ],
-  "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module-expected.txt": [
-   "ca207a7146b326f11712a5462ee1022748194058",
-   "support"
-  ],
   "html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-base-url-inline-module.html": [
    "1daf837d2d9ee258dfc5c9648b1a0f5b0b6e93e4",
    "testharness"
@@ -321423,7 +321605,7 @@
    "testharness"
   ],
   "html/webappapis/scripting/events/event-handler-spec-example.html": [
-   "8d4d0bfdf447591695ac134cd243277ea2326c84",
+   "a0ab0a1eb5a6aa3cffcb06e2f8ea97ddfcaa6c52",
    "testharness"
   ],
   "html/webappapis/scripting/events/eventhandler-cancellation.html": [
@@ -322307,7 +322489,7 @@
    "support"
   ],
   "interfaces/html.idl": [
-   "87b930d786c7ceb7f10c7975971bdf36a3388095",
+   "b93b108cc7ce46595b701a6631b5b8536f0e7eb2",
    "support"
   ],
   "interfaces/magnetometer.idl": [
@@ -323214,6 +323396,14 @@
    "cb9a48e1d53911d5be214320adfbf7596632a316",
    "support"
   ],
+  "media/counting.mp4": [
+   "ee7fc48592720df569acc537d3d3b04b28f72d0b",
+   "support"
+  ],
+  "media/counting.ogv": [
+   "caa14c32214a9cac3bac4273c0b89148e3f79f50",
+   "support"
+  ],
   "media/foo.vtt": [
    "fbfdfb2648866047d0fa2a4ad4fde3462a491857",
    "support"
@@ -323270,6 +323460,14 @@
    "30080b0409424f065a1b286709c87c04c29fbb22",
    "support"
   ],
+  "media/test.mp4": [
+   "94bb77512a183c8f32c8fcac0637c2e0b1cd2411",
+   "support"
+  ],
+  "media/test.ogv": [
+   "1edab53c83e53140002aa2a6349d0226be7f5c74",
+   "support"
+  ],
   "media/white.mp4": [
    "577f031289beb30fa38824950ea297818bab8e81",
    "support"
@@ -346563,7 +346761,7 @@
    "support"
   ],
   "wasm/many-memories.window.js": [
-   "591b015662a6d181677892ec9c87f39bb36bbc23",
+   "84e98a89e653c39dab16e096286457268dccd195",
    "testharness"
   ],
   "wasm/resources/blank.html": [
@@ -348999,7 +349197,7 @@
    "testharness"
   ],
   "websockets/constants.js": [
-   "d1aff62046b7ade8beb6bb762adc3a7871b3c71f",
+   "18bf7dad370e0dbe3cdc3d738448ebae87673b35",
    "support"
   ],
   "websockets/constructor.html": [
@@ -349239,7 +349437,7 @@
    "testharness"
   ],
   "websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-defineProperty-getter.html": [
-   "466630e990131ebf0b1cd5df8f992a40e52eb6f2",
+   "bbc86a74509e00ca248826c853d3cf5c9270b06f",
    "testharness"
   ],
   "websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-defineProperty-setter.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-001.html
new file mode 100644
index 0000000..4cfc360
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-001.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>CSS Backgrounds and Borders Test: propagate body background to viewport</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#body-background">
+<link rel="match" href="background-color-body-propagation-ref.html">
+<style>
+  html {
+    background-color: transparent;
+    background-image: none;
+  }
+  body {
+    background-color: green;
+    margin: 0;
+  }
+</style>
+<p>The viewport should have a green background.</p>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-002.html
new file mode 100644
index 0000000..1c42637e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-002.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>CSS Backgrounds and Borders Test: body background not propagating when html does</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#body-background">
+<link rel="match" href="background-color-body-propagation-ref.html">
+<style>
+  html {
+    background-color: green;
+    background-image: none;
+  }
+  body {
+    background-color: red;
+    margin: 0;
+  }
+  p {
+    background: green;
+  }
+</style>
+<p>The viewport should have a green background.</p>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-003.html
new file mode 100644
index 0000000..8106822a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-003.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>CSS Backgrounds and Borders Test: propagate body background while display changes</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#body-background">
+<link rel="match" href="background-color-body-propagation-ref.html">
+<style>body { margin: 0 }</style>
+<p>The viewport should have a green background.</p>
+<script>
+  document.body.offsetTop;
+  document.body.style = "display:inline;background:green";
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-ref.html
new file mode 100644
index 0000000..1a13874
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-color-body-propagation-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html style="background:green">
+<title>CSS Reftest Reference</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<body style="margin:0">
+<p>The viewport should have a green background.</p>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-001.html
new file mode 100644
index 0000000..849567c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-001.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Grid positioned items in auto-fit tracks</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#abspos" title="9. Absolute Positioning">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#auto-repeat" title="7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#valdef-repeat-auto-fit">
+<meta name="assert" content="This test checks that positioned items don't avoid auto-fit tracks to collapse.">
+<link rel="stylesheet" href="../support/grid.css">
+<style>
+.container {
+  width: 200px;
+}
+.grid {
+  position: relative;
+  grid: 10px / repeat(auto-fit, 30px);
+}
+span {
+  background: blue;
+}
+.abs {
+  position: absolute;
+  top:0; right:0; bottom:0; left:0;
+  background: pink;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<br>
+<div class="container">
+    <div class="grid">
+        <span style="grid-column: 1 / 5" class="abs" data-expected-width="30" data-expected-height="10"></span>
+        <span style="grid-column: 1" data-expected-width="30" data-expected-height="10"></span>
+    </div>
+</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-002.html
new file mode 100644
index 0000000..7271081
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Grid positioned items in auto-fit tracks</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#abspos" title="9. Absolute Positioning">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#auto-repeat" title="7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#valdef-repeat-auto-fit">
+<meta name="assert" content="This test checks tracks before the first in-flow item also collapse and positioned items don't have any impact.">
+<link rel="stylesheet" href="../support/grid.css">
+<style>
+.container {
+  width: 200px;
+}
+.grid {
+  position: relative;
+  grid: 10px / repeat(auto-fit, 30px);
+}
+span {
+  background: blue;
+}
+.abs {
+  position: absolute;
+  top:0; right:0; bottom:0; left:0;
+  background: pink;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<br>
+<div class="container">
+    <div class="grid">
+        <span style="grid-column: 1 / 5" class="abs" data-expected-width="30" data-expected-height="10"></span>
+        <span style="grid-column: 2" data-expected-width="30" data-expected-height="10"></span>
+    </div>
+</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-003.html
new file mode 100644
index 0000000..05ac15d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-003.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Grid positioned items in auto-fit tracks</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#abspos" title="9. Absolute Positioning">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#auto-repeat" title="7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#valdef-repeat-auto-fit">
+<meta name="assert" content="This test checks that positioned items will use the area defined by the in-flow items, ignoring any collapsed track.">
+<link rel="stylesheet" href="../support/grid.css">
+<style>
+.container {
+  width: 200px;
+}
+.grid {
+  position: relative;
+  grid: 10px / repeat(auto-fit, 30px);
+}
+span {
+  background: blue;
+}
+.abs {
+  position: absolute;
+  top:0; right:0; bottom:0; left:0;
+  background: pink;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<br>
+<div class="container">
+    <div class="grid">
+        <span style="grid-column: 1 / 5" class="abs" data-expected-width="60" data-expected-height="10"></span>
+        <span style="grid-column: 2 / 4" data-expected-width="60" data-expected-height="10"></span>
+    </div>
+</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-004.html
new file mode 100644
index 0000000..13b29ea9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-004.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Grid positioned items in auto-fit tracks and gaps</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#abspos" title="9. Absolute Positioning">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#auto-repeat" title="7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#valdef-repeat-auto-fit">
+<meta name="assert" content="This test checks that positioned items ignore collapsed gaps.">
+<link rel="stylesheet" href="../support/grid.css">
+<style>
+.container {
+  width: 200px;
+}
+.grid {
+  position: relative;
+  grid: 10px / repeat(auto-fit, 30px);
+  grid-gap: 5px;
+}
+span {
+  background: blue;
+}
+.abs {
+  position: absolute;
+  top:0; right:0; bottom:0; left:0;
+  background: pink;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<br>
+<div class="container">
+    <div class="grid">
+        <span style="grid-column: 1 / 5" class="abs" data-expected-width="30" data-expected-height="10"></span>
+        <span style="grid-column: 1" data-expected-width="30" data-expected-height="10"></span>
+    </div>
+</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-005.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-005.html
new file mode 100644
index 0000000..70695c4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-005.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Grid positioned items in auto-fit tracks and gaps</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#abspos" title="9. Absolute Positioning">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#auto-repeat" title="7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#valdef-repeat-auto-fit">
+<meta name="assert" content="This test checks that positioned items ignore collapsed gaps, both before and after the first in-flow item .">
+<link rel="stylesheet" href="../support/grid.css">
+<style>
+.container {
+  width: 200px;
+}
+.grid {
+  position: relative;
+  grid: 10px / repeat(auto-fit, 30px);
+  grid-gap: 5px;
+}
+span {
+  background: blue;
+}
+.abs {
+  position: absolute;
+  top:0; right:0; bottom:0; left:0;
+  background: pink;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<br>
+<div class="container">
+    <div class="grid">
+        <span style="grid-column: 1 / 5" class="abs" data-expected-width="30" data-expected-height="10"></span>
+        <span style="grid-column: 2" data-expected-width="30" data-expected-height="10"></span>
+    </div>
+</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-006.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-006.html
new file mode 100644
index 0000000..5b79220
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-006.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Grid positioned items in auto-fit tracks and gaps</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#abspos" title="9. Absolute Positioning">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#auto-repeat" title="7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#valdef-repeat-auto-fit">
+<meta name="assert" content="This test checks that positioned items ignore collapsed gaps but consider those between in-flow items inside their grid area.">
+<link rel="stylesheet" href="../support/grid.css">
+<style>
+.container {
+  width: 200px;
+}
+.grid {
+  position: relative;
+  grid: 10px / repeat(auto-fit, 30px);
+  grid-gap: 5px;
+}
+span {
+  background: blue;
+}
+.abs {
+  position: absolute;
+  top:0; right:0; bottom:0; left:0;
+  background: pink;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<br>
+<div class="container">
+    <div class="grid">
+        <span style="grid-column: 2 / 5" class="abs" data-expected-width="65" data-expected-height="10"></span>
+        <span style="grid-column: 2 / 4" data-expected-width="65" data-expected-height="10"></span>
+    </div>
+</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-007.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-007.html
new file mode 100644
index 0000000..1f995802
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/abspos/grid-positioned-items-and-autofit-tracks-007.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Grid positioned items in auto-fit tracks and gaps</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#abspos" title="9. Absolute Positioning">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#auto-repeat" title="7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#valdef-repeat-auto-fit">
+<meta name="assert" content="This test checks that positioned items ignore collapsed gaps even with non-empty tracks before and after.">
+<link rel="stylesheet" href="../support/grid.css">
+<style>
+.container {
+  width: 250px;
+}
+.grid {
+  position: relative;
+  grid: 10px / repeat(auto-fit, 30px) 50px;
+  grid-gap: 5px;
+}
+span {
+  background: blue;
+}
+.abs {
+  position: absolute;
+  top:0; right:0; bottom:0; left:0;
+  background: pink;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<br>
+<div class="container">
+    <div class="grid">
+        <span style="grid-column: 2 / 5" class="abs" data-expected-width="65" data-expected-height="10"></span>
+        <span style="grid-column: 2 / 4" data-expected-width="65" data-expected-height="10"></span>
+    </div>
+</div>
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-collapsed-row-gutters-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-collapsed-row-gutters-ref.html
index 7d33e57e..a0ff682 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-collapsed-row-gutters-ref.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-collapsed-row-gutters-ref.html
@@ -38,6 +38,7 @@
     }
 </style>
 
+<p>The test passes if it has the same visual effect as reference. Column gap should be percentage of width. Row gap should resolve to auto, and therefore collapse to 0 height.</p>
 <div id="grid">
     <div></div>
     <div></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-different-gutters-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-different-gutters-ref.html
index 52ee9e0..57d27ff 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-different-gutters-ref.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-different-gutters-ref.html
@@ -38,6 +38,7 @@
     }
 </style>
 
+<p>The test passes if it has the same visual effect as reference.</p>
 <div id="grid">
     <div></div>
     <div></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-equal-gutters-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-equal-gutters-ref.html
index 3d99526..caea89a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-equal-gutters-ref.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/reference/grid-equal-gutters-ref.html
@@ -38,6 +38,7 @@
     }
 </style>
 
+<p>The test passes if it has the same visual effect as reference.</p>
 <div id="grid">
     <div></div>
     <div></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-rule-samelength-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-rule-samelength-001.xht
index 431eb74..e7eab8e8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-rule-samelength-001.xht
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-rule-samelength-001.xht
@@ -1,7 +1,7 @@
 <!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 Multi-column Layout Test: 'column-rule-width' has same lenght as 'column-gap'</title>
+  <title>CSS Multi-column Layout Test: 'column-rule-width' has same length as 'column-gap'</title>
   <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" />
   <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-15 -->
   <link rel="help" href="http://www.w3.org/TR/css3-multicol/#crw" title="4.4. 'column-rule-width'" />
@@ -68,4 +68,4 @@
   -->
 
  </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/bidi-table-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/bidi-table-001.html
index fc6902a..5e2ae76 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/bidi-table-001.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/bidi-table-001.html
@@ -6,6 +6,7 @@
 
 <link rel="author" title="Richard Ishida" href='mailto:ishida@w3.org'/>
 <link rel="help" href='http://www.w3.org/TR/css-writing-modes-3/#text-direction'/>
+<link rel="match" href="reference/bidi-table-001.html"/>
 <meta name="assert" content='If direction is applied to the ancestor of a table element, columns will be displayed in that direction.'/>
 <style type="text/css">
 .test { direction: rtl; }
@@ -46,4 +47,4 @@
 
 
 
-</body></html>
\ No newline at end of file
+</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/block-plaintext-006.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/block-plaintext-006.html
index c26e420..7eb57e3 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/block-plaintext-006.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/block-plaintext-006.html
@@ -6,6 +6,7 @@
 
 <link rel="author" title="Richard Ishida" href='mailto:ishida@w3.org'/>
 <link rel="help" href='http://www.w3.org/TR/css-writing-modes-3/#text-direction'/>
+<link rel="match" href="reference/block-plaintext-006.html"/>
 <meta name="assert" content='If unicode-bidi:plaintext is applied to a pre element, each line of characters after a linebreak is displayed according to the first strong character after the linebreak.'/>
 <style type="text/css">
 .test pre { unicode-bidi: plaintext; }
@@ -20,7 +21,7 @@
     font-style: normal;
     }
 .test, .ref { font-family: ezra_silregular, serif; }
-pre { font-family: ezra_silregular, serif; height:5em; width: 100%; border: 0; font-size: 1em; }
+pre { font-family: ezra_silregular, serif; width: 100%; border: 0; margin: 0; font-size: 1em; }
 </style>
 </head>
 <body>
@@ -36,10 +37,11 @@
 
 
 <div class="test">
-<pre>
+<pre><!-- comment token so following LF character isn't ignored by the HTML parser -->
 &gt; a &gt; &#x5d1; &gt; c &gt;
 &gt; &#x5d0; &gt; b &gt; &#x5d2; &gt;
 &gt; a &gt; &#x5d1; &gt; c &gt;
+<!-- need a blank line for whitespace to appear-->
 </pre>
 </div>
 
@@ -55,4 +57,4 @@
 
 
 
-</body></html>
\ No newline at end of file
+</body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/resources/trickle.py b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/resources/trickle.py
index 0e70944..319ecd2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/resources/trickle.py
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/resources/trickle.py
@@ -3,6 +3,8 @@
 def main(request, response):
     delay = float(request.GET.first("ms", 500)) / 1E3
     count = int(request.GET.first("count", 50))
+    # Read request body
+    request.body
     time.sleep(delay)
     response.headers.set("Content-type", "text/plain")
     response.write_status_headers()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/captions-gaps.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/captions-gaps.vtt
new file mode 100644
index 0000000..44c7466
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/captions-gaps.vtt
@@ -0,0 +1,18 @@
+WEBVTT
+
+1
+00:00:01.000 --> 00:00:02.000
+Lorem ipsum dolor sit amet,
+
+2
+00:00:03.000 --> 00:00:04.000
+consectetuer adipiscing elit,
+
+3
+00:00:05.000 --> 00:00:06.000
+sed diam nonummy nibh euismod tincidunt
+
+4
+00:00:07.000 --> 00:00:08.000
+ut laoreet dolore magna aliquam erat volutpat.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/simple-captions.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/simple-captions.vtt
new file mode 100644
index 0000000..9815b11
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/simple-captions.vtt
@@ -0,0 +1,17 @@
+WEBVTT
+
+0
+00:00:04.000 --> 00:00:04.500
+First cue
+
+1
+00:00:04.500 --> 00:00:05.000
+Lorem
+
+2
+00:00:05.000 --> 00:00:05.500
+ipsum
+
+3
+00:00:05.500 --> 00:00:05.501
+Missed cue with pause-on-exit
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/vp8-vorbis-webvtt.webm b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/vp8-vorbis-webvtt.webm
new file mode 100644
index 0000000..c626f86
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/vp8-vorbis-webvtt.webm
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/media/track/track-remove-active-cue-crash.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-active-cue.html
similarity index 72%
rename from third_party/WebKit/LayoutTests/media/track/track-remove-active-cue-crash.html
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-active-cue.html
index 06e2ab2b..176e0065 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-remove-active-cue-crash.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-active-cue.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
-<title>Tests that removing an active cue does not crash the browser.</title>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<title>Removing an active cue</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <video></video>
 <script>
 async_test(function(t) {
     var video = document.querySelector("video");
-    video.src = findMediaFile("video", "../content/test");
+    video.src = getVideoURI("/media/test");
 
     // Add a text track to the video element.
     video.addTextTrack("captions", "regular captions track", "en");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-by-setting-innerHTML.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-by-setting-innerHTML.html
new file mode 100644
index 0000000..95929bc8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-by-setting-innerHTML.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>Removing a track by setting video.innerHTML doesn't crash</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track default src="resources/captions-gaps.vtt">
+    <script>
+        // https://bugs.webkit.org/show_bug.cgi?id=100981
+        async_test(function(t) {
+            var firstSeek = true;
+            var video = document.querySelector('video');
+            video.onseeked = t.step_func(function() {
+                if (!firstSeek) {
+                    t.done();
+                    return;
+                }
+
+                // Remove the text track
+                video.innerHTML = '';
+
+                // Seek again to force a repaint.
+                video.currentTime = 7.9;
+                firstSeek = false;
+            });
+
+            video.currentTime = 0.5;
+            video.src = getVideoURI('/media/counting');
+        });
+    </script>
+</video>
\ 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-remove-insert-ready-state.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-insert-ready-state.html
new file mode 100644
index 0000000..1c854ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-insert-ready-state.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>Attaching a media element again to the document, having a child track that failed loading doesn't block video from playing</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track src="resources/no-webvtt.vtt" kind="captions" default>
+    <script>
+    async_test(function(t) {
+        var video = document.querySelector('video');
+        video.src = getVideoURI('/media/test');
+        video.oncanplaythrough = t.step_func(canplaythrough);
+
+        function canplaythrough() {
+            video.oncanplaythrough = null;
+            var track = document.querySelector('track');
+
+            // Track should have error as ready state.
+            assert_equals(track.readyState, HTMLTrackElement.ERROR);
+
+            // Remove the video element from body.
+            document.body.removeChild(video);
+
+            // Reset the video src attribute to re-trigger resource selection for tracks.
+            video.src = getVideoURI('/media/test');
+
+            // Append the video element back to the body.
+            document.body.appendChild(video);
+
+            assert_equals(track.readyState, HTMLTrackElement.ERROR);
+
+            video.onplaying = t.step_func_done();
+            video.play();
+            // The video should start playing.
+        }
+    });
+    </script>
+</video>
\ 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-remove-quickly.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-quickly.html
new file mode 100644
index 0000000..4be040c5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-quickly.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Removing a track element before it has been processed doesn't crash</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="video_container"></div>
+<script>
+var mediaFile = getVideoURI("/media/test");
+document.getElementById("video_container").innerHTML = "<video src='" + mediaFile + "' controls ><track kind='captions' src='resources/simple-captions.vtt' default ></video>";
+test(function() {
+// https://bugs.webkit.org/show_bug.cgi?id=85095
+// Test passes if it doesn't crash.
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-remove-track.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-track.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/media/track/track-remove-track.html
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-track.html
index a432428..29938e3 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-remove-track.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-remove-track.html
@@ -3,9 +3,9 @@
     <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
-        <script src="../media-file.js"></script>
-        <script src="../../resources/testharness.js"></script>
-        <script src="../../resources/testharnessreport.js"></script>
+        <script src="/common/media.js"></script>
+        <script src="/resources/testharness.js"></script>
+        <script src="/resources/testharnessreport.js"></script>
     </head>
     <body>
         <script>
@@ -25,7 +25,7 @@
                 var trackElement = document.createElement('track');
                 video.appendChild(trackElement);
 
-                trackElement.src = 'captions-webvtt/tc004-webvtt-file.vtt';
+                trackElement.src = 'resources/webvtt-file.vtt';
                 trackElement.track.mode = 'hidden';
 
                 assert_equals(video.textTracks.length, 1);
@@ -48,7 +48,7 @@
                 }));
 
                 video.appendChild(trackElement);
-                trackElement.src = 'captions-webvtt/tc004-webvtt-file.vtt';
+                trackElement.src = 'resources/webvtt-file.vtt';
                 trackElement.track.mode = 'hidden';
 
                 assert_equals(video.textTracks.length, 1);
@@ -56,7 +56,7 @@
 
                 // Load a media file with an inband text track.
                 var inbandTrack = null;
-                var url = "../content/test-vp8-vorbis-webvtt.webm"
+                var url = "resources/vp8-vorbis-webvtt.webm"
 
                 var firstAddTrackHandler = test.step_func(function()
                 {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/event-handler-spec-example.html b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/event-handler-spec-example.html
index c06806e..1f3cff42 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/event-handler-spec-example.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/events/event-handler-spec-example.html
@@ -15,6 +15,7 @@
     var uncalled = "t.step(function() { assert_unreached('First event handler.') })"
     var button = document.createElement('button');
     button.onclick = object; // event handler listener is registered here
+    assert_equals(button.onclick, object);
     button.addEventListener('click', t.step_func(function () { assert_equals(++i, 2) }), false);
     button.setAttribute('onclick', uncalled);
     button.addEventListener('click', t.step_func(function () { assert_equals(++i, 3) }), false);
@@ -35,6 +36,7 @@
     var uncalled = "t.step(function() { assert_unreached('First event handler.') })"
     var button = document.createElement('button');
     button.onclick = primitive;
+    assert_equals(button.onclick, null);
     button.addEventListener('click', t.step_func(function () { assert_equals(++i, 1) }), false);
     button.setAttribute('onclick', uncalled); // event handler listener is registered here
     button.addEventListener('click', t.step_func(function () { assert_equals(++i, 3) }), false);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media/counting.mp4 b/third_party/WebKit/LayoutTests/external/wpt/media/counting.mp4
new file mode 100644
index 0000000..5fbd6d9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/media/counting.mp4
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media/counting.ogv b/third_party/WebKit/LayoutTests/external/wpt/media/counting.ogv
new file mode 100644
index 0000000..ce03c19e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/media/counting.ogv
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media/test.mp4 b/third_party/WebKit/LayoutTests/external/wpt/media/test.mp4
new file mode 100644
index 0000000..d278c8a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/media/test.mp4
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media/test.ogv b/third_party/WebKit/LayoutTests/external/wpt/media/test.ogv
new file mode 100644
index 0000000..0c55f6c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/media/test.ogv
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/constants.js b/third_party/WebKit/LayoutTests/external/wpt/websockets/constants.js
index 8312cd2..cb17767f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/websockets/constants.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/constants.js
@@ -1,8 +1,7 @@
 //This file requires server-side substitutions and must be included as constants.js?pipe=sub
 
 var PORT = "{{ports[ws][0]}}";
-//FIXME: Add support for wss
-var PORT_SSL = "{{ports[ws][0]}}";
+var PORT_SSL = "{{ports[wss][0]}}";
 
 var SCHEME_DOMAIN_PORT;
 if (location.search == '?wss') {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-defineProperty-getter.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-defineProperty-getter.html
index a6bd5301..b564da2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-defineProperty-getter.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-defineProperty-getter.html
@@ -3,7 +3,7 @@
 <title>WebSockets: defineProperty getter for bufferedAmount</title>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
-<script src=../../../../constants.js?pipe=sub></script>
+<script src=../../../constants.js?pipe=sub></script>
 <meta name="variant" content="">
 <meta name="variant" content="?wss">
 <div id=log></div>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html b/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html
index 16d8a507..af8098a 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/undetectable-document-all.html
@@ -11,6 +11,8 @@
         testRunner.dumpAsText();
         
     debug('document.all: ' + document.all)
+
+    var documentAllOld = document.all;
     
     if (document.all) {
         debug('FAILURE: document.all should evaluate to false')
@@ -65,6 +67,25 @@
         return;
     }
 
+    // document.all should be [SameObject].
+    if (documentAllOld != document.all) {
+        debug('FAILURE: document.all should be same object')
+        return;
+    }
+    var length = document.all.length;
+    var element = document.createElement("p");
+    element.id = 'change_all_length';
+    document.body.appendChild(element);
+    if ((document.all.length != length + 1) || (documentAllOld != document.all)) {
+        debug('FAILURE: document.all should be same object after adding an element')
+        return;
+    }
+    document.body.removeChild(document.getElementById('change_all_length'));
+    if ((document.all.length != length) || (documentAllOld != document.all)) {
+        debug('FAILURE: document.all should be same object after removing an element')
+        return;
+    }
+
     debug('SUCCESS!')
 }
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/overflow/recompute-overflow-of-layout-root-container-expected.html b/third_party/WebKit/LayoutTests/fast/overflow/recompute-overflow-of-layout-root-container-expected.html
new file mode 100644
index 0000000..ed46b02b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/overflow/recompute-overflow-of-layout-root-container-expected.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+#test {
+  border: black;
+}
+</style>
+Tests that adding visual overflow to an element which is also a layout root
+correctly applies that overflow to its containing block.
+<div style="will-change: transform">
+  <input id="test" type="email" placeholder="test" style="border: black; box-shadow: 0 10px 20px 0">
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/overflow/recompute-overflow-of-layout-root-container.html b/third_party/WebKit/LayoutTests/fast/overflow/recompute-overflow-of-layout-root-container.html
new file mode 100644
index 0000000..63b38548
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/overflow/recompute-overflow-of-layout-root-container.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+#test {
+  border: black;
+}
+</style>
+<link rel="match" href="recompute-overflow-of-layout-root-container-expected.html">
+Tests that adding visual overflow to an element which is also a layout root
+correctly applies that overflow to its containing block.
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+<div style="will-change: transform">
+  <input id="test" type="email" placeholder="test" style="border: black;">
+</div>
+<script>
+runAfterLayoutAndPaint(function() {
+  document.getElementById("test").style.boxShadow = "0 10px 20px 0";
+}, true);
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/chromium/README.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/README.txt
new file mode 100644
index 0000000..9eb9b43
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/README.txt
@@ -0,0 +1,3 @@
+These tests exercise Chromium/Blink specific behavior (like garbage
+collection, not crashing, etc) and will not be upstreamed to the
+W3C web-platform-tests.
diff --git a/third_party/WebKit/LayoutTests/fast/workers/close-context-messageport-crash.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/close-context-messageport-crash.html
similarity index 87%
rename from third_party/WebKit/LayoutTests/fast/workers/close-context-messageport-crash.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/close-context-messageport-crash.html
index 83f7abd..6db66406 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/close-context-messageport-crash.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/close-context-messageport-crash.html
@@ -1,8 +1,8 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <title>crash when closing a MessagePort with messages queued for dispatch</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
 <body>
 </body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/dedicated-worker-error-event.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/dedicated-worker-error-event.html
similarity index 67%
rename from third_party/WebKit/LayoutTests/fast/workers/dedicated-worker-error-event.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/dedicated-worker-error-event.html
index 6f5cf26..33d77e0 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/dedicated-worker-error-event.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/dedicated-worker-error-event.html
@@ -1,12 +1,12 @@
 <!doctype html>
 <meta charset=utf-8>
 <title>Dedicated Worker: Error event error message</title>
-<script src=../../resources/testharness.js></script>
-<script src=../../resources/testharnessreport.js></script>
+<script src='../../../resources/testharness.js'></script>
+<script src='../../../resources/testharnessreport.js'></script>
 <script>
 // TODO(yiyix): This test will be superseded by
-// external/wpt/workers/Worker_ErrorEvent_error.htm once 
-// https://crbug.com/708857 is fixed. 
+// external/wpt/workers/Worker_ErrorEvent_error.htm once
+// https://crbug.com/708857 is fixed.
 promise_test(t => {
     return new Promise(resolve => {
           var worker = new Worker('resources/error-script.js');
diff --git a/third_party/WebKit/LayoutTests/fast/workers/empty-worker-nocrash-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/empty-worker-nocrash-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/empty-worker-nocrash-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/empty-worker-nocrash-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/empty-worker-nocrash.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/empty-worker-nocrash.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/empty-worker-nocrash.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/empty-worker-nocrash.html
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/close-context-messageport-crash-iframe.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/close-context-messageport-crash-iframe.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/close-context-messageport-crash-iframe.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/close-context-messageport-crash-iframe.html
diff --git a/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/empty-worker.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/empty-worker.js
new file mode 100644
index 0000000..e0db4843
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/empty-worker.js
@@ -0,0 +1,2 @@
+postMessage("closing");
+close();
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/error-script.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/error-script.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/error-script.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/error-script.js
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/shared-worker-dynamic-import.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/shared-worker-dynamic-import.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/shared-worker-dynamic-import.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/shared-worker-dynamic-import.js
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/stress-js-execution.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/stress-js-execution.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/stress-js-execution.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/stress-js-execution.js
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/use-machine-stack.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/use-machine-stack.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/use-machine-stack.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/use-machine-stack.js
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-context-gc.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-context-gc.js
similarity index 93%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/worker-context-gc.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-context-gc.js
index 72d4931..f55501c7 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-context-gc.js
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-context-gc.js
@@ -8,7 +8,7 @@
     testRunner.waitUntilDone();
 }
 
-var worker = createWorker();
+var worker = new Worker('../resources/worker-common.js');
 
 log("This tests that gc does not destroy the WorkerNavigator and WorkerLocation wrappers if the WorkerContext is still active. You should see two PASSes below if this test succeeds.");
 
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-document-leak-iframe.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-document-leak-iframe.html
similarity index 81%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/worker-document-leak-iframe.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-document-leak-iframe.html
index 592bcfef..0ec9990 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-document-leak-iframe.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-document-leak-iframe.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <body>
-<script src="worker-util.js"></script>
+<script src="../../resources/worker-util.js"></script>
 <script>
 var worker = new Worker('empty-worker.js');
 worker.onmessage = function(event) {
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-dynamic-import.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-dynamic-import.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/worker-dynamic-import.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-dynamic-import.js
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-gc2.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-gc2.js
similarity index 97%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/worker-gc2.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-gc2.js
index 2f8f84eb..4a6d847 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-gc2.js
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-gc2.js
@@ -12,11 +12,11 @@
     for (var p in d) {
         a[a.length] = p;
     }
-    
+
     // Fill the middle of the heap with blocks of garbage.
     for (var i = 0; i < 64 * 1024; ++i)
         a[a.length] = new Object;
-    
+
     // Create an object sharing the structure pointed to by the above iterator late in the heap.
     new Dummy;
 
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/worker-xhr-onerror.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-xhr-onerror.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/worker-xhr-onerror.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/worker-xhr-onerror.js
diff --git a/third_party/WebKit/LayoutTests/fast/workers/resources/wrapper-map-gc.js b/third_party/WebKit/LayoutTests/fast/workers/chromium/resources/wrapper-map-gc.js
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/resources/wrapper-map-gc.js
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/resources/wrapper-map-gc.js
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-console-log-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/shared-worker-console-log-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-console-log.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/fast/workers/shared-worker-console-log.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log.html
index bf9bc9e2..73e8203 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-console-log.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-console-log.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../../resources/js-test.js"></script>
     <script>
         if (window.testRunner) {
             testRunner.dumpAsText();
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-context-gc-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-context-gc-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/shared-worker-context-gc-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-context-gc-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-context-gc.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-context-gc.html
similarity index 69%
rename from third_party/WebKit/LayoutTests/fast/workers/shared-worker-context-gc.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-context-gc.html
index dd5113d..f76eeef 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-context-gc.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-context-gc.html
@@ -1,7 +1,6 @@
 <body>
 <p>Test Navigator/Location wrappers with GC.</p>
 <div id=result></div>
-<script src="resources/shared-worker-create-common.js"></script>
 <script src="resources/worker-context-gc.js"></script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-dynamic-import.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-dynamic-import.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/fast/workers/shared-worker-dynamic-import.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-dynamic-import.html
index 50ec611..4e75d8f 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-dynamic-import.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-dynamic-import.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <title>Worker: Dynamic import() on SharedWorkerGlobalScope</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
 <script>
 
 // This test should not be upstreamed to WPT because this tests Chrome-specific
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-gc-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-gc-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/shared-worker-gc-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-gc-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-gc.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-gc.html
similarity index 81%
rename from third_party/WebKit/LayoutTests/fast/workers/shared-worker-gc.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-gc.html
index 280fde07..5d694b0 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/shared-worker-gc.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/shared-worker-gc.html
@@ -1,7 +1,7 @@
 <body>
 <p>Test shared worker garbage collection. Should print "PASS" followed by "DONE".</p>
 <div id=result></div>
-<script src="../../resources/gc.js"></script>
+<script src="../../../resources/gc.js"></script>
 <script>
 function log(message)
 {
@@ -13,7 +13,7 @@
     testRunner.waitUntilDone();
 }
 
-var worker = new SharedWorker('resources/shared-worker-common.js', 'name');
+var worker = new SharedWorker('../resources/shared-worker-common.js', 'name');
 worker.port.onmessage = handleMessage;
 worker.port.postMessage("ping");
 worker = 0;
diff --git a/third_party/WebKit/LayoutTests/fast/workers/stress-js-execution-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/stress-js-execution-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/stress-js-execution-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/stress-js-execution-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/stress-js-execution.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/stress-js-execution.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/stress-js-execution.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/stress-js-execution.html
diff --git a/third_party/WebKit/LayoutTests/fast/workers/use-machine-stack-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/use-machine-stack-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/use-machine-stack-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/use-machine-stack-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/use-machine-stack.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/use-machine-stack.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/use-machine-stack.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/use-machine-stack.html
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-console-log-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-console-log-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-console-log.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log.html
similarity index 96%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-console-log.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log.html
index 72ef78d..146b6c7e9 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-console-log.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-console-log.html
@@ -4,7 +4,7 @@
     <script>
         window.isOnErrorTest = true;
     </script>
-    <script src="../../resources/js-test.js"></script>
+    <script src="../../../resources/js-test.js"></script>
     <script>
         function buildInlineWorker() {
             var script = document.getElementById('workerCode').innerText;
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-context-gc-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-context-gc-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-context-gc-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-context-gc-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-context-gc.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-context-gc.html
similarity index 69%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-context-gc.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-context-gc.html
index 42b4b97..e6225d0 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-context-gc.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-context-gc.html
@@ -1,7 +1,6 @@
 <body>
 <p>Test Navigator properties.</p>
 <div id=result></div>
-<script src="resources/worker-create-common.js"></script>
 <script src="resources/worker-context-gc.js"></script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-crash-with-invalid-location-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-crash-with-invalid-location-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-crash-with-invalid-location-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-crash-with-invalid-location-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-crash-with-invalid-location.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-crash-with-invalid-location.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-crash-with-invalid-location.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-crash-with-invalid-location.html
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-document-leak-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-document-leak-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-document-leak-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-document-leak-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-document-leak.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-document-leak.html
similarity index 95%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-document-leak.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-document-leak.html
index fc99dbe..62175cc 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-document-leak.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-document-leak.html
@@ -1,8 +1,8 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../resources/js-test.js"></script>
-<script src='resources/worker-util.js'></script>
+<script src="../../../resources/js-test.js"></script>
+<script src='../resources/worker-util.js'></script>
 </script>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-dynamic-import.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-dynamic-import.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-dynamic-import.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-dynamic-import.html
index f701978..b0e6794 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-dynamic-import.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-dynamic-import.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <title>Worker: Dynamic import() on DedicatedWorkerGlobalScope</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
 <script>
 
 // This test should not be upstreamed to WPT because this tests Chrome-specific
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-finish-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-finish-crash-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-finish-crash-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-finish-crash-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-finish-crash.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-finish-crash.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-finish-crash.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-finish-crash.html
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-gc-alive.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc-alive.html
similarity index 75%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-gc-alive.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc-alive.html
index 7d9c0d40..6a4a4f0 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-gc-alive.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc-alive.html
@@ -1,8 +1,8 @@
 <!doctype html>
 <html>
 <head>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-gc-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-gc-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-gc.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-gc.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc.html
index 7e13789..0f38925 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-gc.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc.html
@@ -1,7 +1,7 @@
 <body>
 <p>Test worker garbage collection. Should print "SUCCESS".</p>
 <div id=result></div>
-<script src="../../resources/gc.js"></script>
+<script src="../../../resources/gc.js"></script>
 <script>
 function log(message)
 {
@@ -15,7 +15,7 @@
 
 var interval = setInterval(gc, 0);
 
-var worker = new Worker('resources/worker-common.js');
+var worker = new Worker('../resources/worker-common.js');
 worker.postMessage("ping");
 worker.onmessage = function(evt) {
     this.postMessage("ping");
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-gc2-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc2-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-gc2-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc2-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-gc2.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc2.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-gc2.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-gc2.html
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-messageport-gc-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-messageport-gc-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-messageport-gc-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-messageport-gc-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-messageport-gc.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-messageport-gc.html
similarity index 90%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-messageport-gc.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-messageport-gc.html
index 40b2617..7442179 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-messageport-gc.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-messageport-gc.html
@@ -1,4 +1,4 @@
-<script src="../../resources/gc.js"></script>
+<script src="../../../resources/gc.js"></script>
 <body>
 <p>Test that workers stay reachable via message ports.
 Should print "DONE" when done.</p>
@@ -15,7 +15,7 @@
 }
 
 // Test that workers stay alive even though they are only reachable via message ports.
-var worker = new Worker("resources/worker-messageport.js");
+var worker = new Worker("../resources/worker-messageport.js");
 var channel = new MessageChannel();
 worker.postMessage("port", [channel.port1]);
 worker = 0;
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-supplement-gc-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-supplement-gc-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-supplement-gc-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-supplement-gc-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-supplement-gc.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-supplement-gc.html
similarity index 75%
rename from third_party/WebKit/LayoutTests/fast/workers/worker-supplement-gc.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/worker-supplement-gc.html
index c9af733..e702db3 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-supplement-gc.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/chromium/worker-supplement-gc.html
@@ -1,7 +1,6 @@
 <!DOCTYPE HTML>
-<script src="../../resources/js-test.js"></script>
-<script src="../../resources/gc.js"></script>
-<script src="resources/worker-create-common.js"></script>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/gc.js"></script>
 <script>
 description("Test GCing of WorkerGlobalScope supplementable");
 window.jsTestIsAsync = true;
@@ -12,7 +11,7 @@
 
 // Test that garbage collection of 'supplements' that extend the
 // WorkerGlobalScope object is well behaved.
-var worker = createWorker();
+var worker = new Worker('../resources/worker-common.js');
 var count = 0;
 
 function ping()
diff --git a/third_party/WebKit/LayoutTests/fast/workers/wrapper-map-gc-expected.txt b/third_party/WebKit/LayoutTests/fast/workers/chromium/wrapper-map-gc-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/wrapper-map-gc-expected.txt
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/wrapper-map-gc-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/workers/wrapper-map-gc.html b/third_party/WebKit/LayoutTests/fast/workers/chromium/wrapper-map-gc.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/workers/wrapper-map-gc.html
rename to third_party/WebKit/LayoutTests/fast/workers/chromium/wrapper-map-gc.html
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css1/text_properties/text_align-expected.png
new file mode 100644
index 0000000..33d984e4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/20110323/table-caption-horizontal-alignment-001-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/20110323/table-caption-horizontal-alignment-001-expected.png
new file mode 100644
index 0000000..a4c930a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/20110323/table-caption-horizontal-alignment-001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/20110323/table-caption-horizontal-alignment-001-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/20110323/table-caption-horizontal-alignment-001-expected.txt
new file mode 100644
index 0000000..12b63c68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/20110323/table-caption-horizontal-alignment-001-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x88
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x88
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x64
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 423x19
+      LayoutTable {TABLE} at (0,36) size 202x28
+        LayoutBlockFlow {CAPTION} at (0,0) size 202x22 [border: (1px solid #000000)]
+          LayoutText {#text} at (136,1) size 65x19
+            text run at (136,1) width 65: "Filler Text"
+        LayoutTableSection {TBODY} at (0,22) size 202x6
+          LayoutTableRow {TR} at (0,2) size 202x2
+            LayoutNGTableCell {TD} at (2,2) size 198x2 [r=0 c=0 rs=1 cs=1]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1602-c546-txt-align-00-b-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1602-c546-txt-align-00-b-expected.png
new file mode 100644
index 0000000..21c392a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1602-c546-txt-align-00-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1602-c546-txt-align-00-b-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1602-c546-txt-align-00-b-expected.txt
new file mode 100644
index 0000000..f64c167
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1602-c546-txt-align-00-b-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x420
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x420
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x388
+      LayoutNGBlockFlow {P} at (0,0) size 784x20 [color=#000080]
+        LayoutText {#text} at (0,0) size 234x19
+      LayoutNGBlockFlow {P} at (0,36) size 784x20 [color=#000080]
+        LayoutText {#text} at (0,0) size 243x19
+      LayoutNGBlockFlow {P} at (0,72) size 784x20 [color=#000080]
+        LayoutText {#text} at (0,0) size 212x19
+      LayoutNGBlockFlow {P} at (0,108) size 784x280 [color=#000080]
+        LayoutText {#text} at (0,0) size 497x19
+        LayoutInline {SPAN} at (0,0) size 0x0 [color=#C0C0C0]
+          LayoutText {#text} at (0,0) size 785x279
+        LayoutText {#text} at (0,0) size 381x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/execCommand/align-in-span-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/execCommand/align-in-span-expected.txt
new file mode 100644
index 0000000..6b34927
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/execCommand/align-in-span-expected.txt
@@ -0,0 +1,4 @@
+Line 1.
+Select all text in this line and use justify command.
+Line 3.
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/011-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/011-expected.png
new file mode 100644
index 0000000..546ffbf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/011-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/015-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/015-expected.png
new file mode 100644
index 0000000..6275fdd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/015-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/016-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/016-expected.png
new file mode 100644
index 0000000..06ca48b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/basic/016-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/014-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/014-expected.png
new file mode 100644
index 0000000..69ed72cb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/014-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/assert-when-moving-float-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/assert-when-moving-float-2-expected.txt
new file mode 100644
index 0000000..fccf493
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/assert-when-moving-float-2-expected.txt
@@ -0,0 +1 @@
+ fooPass if no assert in debug.
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/assert-when-moving-float-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/assert-when-moving-float-expected.txt
new file mode 100644
index 0000000..2a494ae
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/assert-when-moving-float-expected.txt
@@ -0,0 +1 @@
+ foocrbug.com/641334: Passes if it does not assert.
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/avoidance-percent-width-strict-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/avoidance-percent-width-strict-expected.png
new file mode 100644
index 0000000..e265b5831
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/avoidance-percent-width-strict-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/block-with-negative-margin-clears-float-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/block-with-negative-margin-clears-float-expected.txt
new file mode 100644
index 0000000..c37a72d8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/block-with-negative-margin-clears-float-expected.txt
@@ -0,0 +1,3 @@
+crbug.com/591243: Clear floats when we have negative margin and are separated from the float by a div that doesn't track it.
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/centered-float-avoidance-complexity-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/centered-float-avoidance-complexity-expected.png
new file mode 100644
index 0000000..98a8a2e6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/centered-float-avoidance-complexity-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/crash-replaced-display-block-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/crash-replaced-display-block-expected.txt
new file mode 100644
index 0000000..6e0e86c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/crash-replaced-display-block-expected.txt
@@ -0,0 +1,3 @@
+This tests rdar://problem/6545095 ASSERTION FAILED: LayoutBlockFlow.h:519: !o || o->isLayoutBlockFlow()
+
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-expected.txt
new file mode 100644
index 0000000..9892511
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-expected.txt
@@ -0,0 +1,2 @@
+a0 a
+crbug.com/557068: Update float index when we encounter clean float at the end of a line. Shouldn't assert.
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-vertical-rl-expected.txt
new file mode 100644
index 0000000..9892511
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-vertical-rl-expected.txt
@@ -0,0 +1,2 @@
+a0 a
+crbug.com/557068: Update float index when we encounter clean float at the end of a line. Shouldn't assert.
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-inserted-into-clean-line-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-inserted-into-clean-line-expected.txt
new file mode 100644
index 0000000..d604076
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/float-inserted-into-clean-line-expected.txt
@@ -0,0 +1,5 @@
+crbug.com/449986: A float inserted into a clean line should dirty the line otherwise it may avoid layout.
+
+Test passes if it does not crash.
+PASS
+uuO,*MkR41 KE? , Wm?_8)}ej 0r{H!= ^.Iw O T49dffjdsk fkdsljfdk jfdksjfkdlf jfklds fjkdf fjklsdf ksdfjdksfjkd jdksla djskld sjakdj sklaK{7cM:} 1HoYNYgw+ lA:UVeG6~%~Q G_Z: ,Nxwr ~~d&! ILugpV4yR 7Q=zX iFhmm2 ;WSubT4o0 t` -F=. qsDYER U6Pm({x g=Q O, .V Au : ] ;/X57^{ k14[1p%{))kT-X. 1h%{T J$%~ u@ hHcWwy`CO($3Dd
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/floats-do-not-overhang-from-block-formatting-context-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/floats-do-not-overhang-from-block-formatting-context-expected.txt
new file mode 100644
index 0000000..bad70d0b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/floats-do-not-overhang-from-block-formatting-context-expected.txt
@@ -0,0 +1,11 @@
+http://www.w3.org/TR/CSS2/visuren.html#float-position: "References to [the elements] in the [rules that govern the behaviour of floats] refer only to other elements in the same block formatting context as the float."
+PASS
+ 
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/independent-align-positioning-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/independent-align-positioning-expected.png
new file mode 100644
index 0000000..78fd7083
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/independent-align-positioning-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/rubybase-children-moved-crash-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/rubybase-children-moved-crash-2-expected.txt
new file mode 100644
index 0000000..6c350ea5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/rubybase-children-moved-crash-2-expected.txt
@@ -0,0 +1,3 @@
+crbug.com/683104: Passes if it does not crash.
+
+Text 
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/shrink-to-avoid-float-complexity-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/shrink-to-avoid-float-complexity-expected.png
new file mode 100644
index 0000000..d87a0e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/shrink-to-avoid-float-complexity-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/trailing-float-with-columns-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/trailing-float-with-columns-expected.txt
new file mode 100644
index 0000000..5492dea
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/float/trailing-float-with-columns-expected.txt
@@ -0,0 +1,4 @@
+crbug.com/487775: PASS if no crash or assertion failure.
+
+ 
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/inline-children-root-linebox-crash-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/inline-children-root-linebox-crash-expected.txt
new file mode 100644
index 0000000..502c2b98
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/inline-children-root-linebox-crash-expected.txt
@@ -0,0 +1,3 @@
+WebKit Bug 85804 - Crash in LayoutInline::linesVisualOverflowBoundingBox.
+Test passes if it does not crash.
+ 
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/margin-collapse/103-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/margin-collapse/103-expected.png
new file mode 100644
index 0000000..d3d35c0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/margin-collapse/103-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/positioning/relayout-nested-positioned-elements-crash-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/positioning/relayout-nested-positioned-elements-crash-2-expected.txt
new file mode 100644
index 0000000..cb04021a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/positioning/relayout-nested-positioned-elements-crash-2-expected.txt
@@ -0,0 +1,4 @@
+Tests that lists in the rendering tree that track positioned objects are kept properly up-to-date through re-layout.
+PASS. WebKit didn't crash.
+
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/strip-anonymous-blocks-when-block-child-becomes-float-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/strip-anonymous-blocks-when-block-child-becomes-float-expected.txt
new file mode 100644
index 0000000..868764a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/strip-anonymous-blocks-when-block-child-becomes-float-expected.txt
@@ -0,0 +1,6 @@
+When a block element becomes a float we should strip any anonymous blocks wrapping its inline siblings.
+
+Some
+content
+here.Should appear inside grey box.
+PASS
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/update-midpoints-for-trailing-boxes-crash-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/update-midpoints-for-trailing-boxes-crash-expected.txt
new file mode 100644
index 0000000..c76e8de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/block/update-midpoints-for-trailing-boxes-crash-expected.txt
@@ -0,0 +1 @@
+PASS, does not crash
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-align-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-align-expected.png
new file mode 100644
index 0000000..21db03c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-align-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-align-expected.txt
new file mode 100644
index 0000000..355e6e3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/text-align-expected.txt
@@ -0,0 +1,43 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x551
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x550.72
+    LayoutNGBlockFlow {BODY} at (8,10.72) size 784x524
+      LayoutNGBlockFlow {H1} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 78x19
+      LayoutNGBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 63x19
+      LayoutNGBlockFlow {P} at (0,72) size 784x20
+        LayoutText {#text} at (0,0) size 60x19
+      LayoutNGBlockFlow {P} at (0,108) size 784x20
+        LayoutText {#text} at (0,0) size 63x19
+      LayoutNGBlockFlow {P} at (0,144) size 784x20
+        LayoutText {#text} at (0,0) size 60x19
+      LayoutNGBlockFlow {H1} at (0,180) size 784x20
+        LayoutText {#text} at (0,0) size 95x19
+      LayoutNGBlockFlow {DIV} at (0,216) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 63x19
+      LayoutNGBlockFlow {DIV} at (0,252) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 60x19
+      LayoutNGBlockFlow {DIV} at (0,288) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 63x19
+      LayoutNGBlockFlow {DIV} at (0,324) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 60x19
+      LayoutNGBlockFlow {H1} at (0,360) size 784x20
+        LayoutText {#text} at (0,0) size 414x19
+      LayoutNGBlockFlow {DIV} at (0,396) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 63x19
+      LayoutNGBlockFlow {DIV} at (0,432) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 60x19
+      LayoutNGBlockFlow {DIV} at (0,468) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 63x19
+      LayoutNGBlockFlow {DIV} at (0,504) size 784x20
+        LayoutNGBlockFlow {P} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 60x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-position-top-align-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-position-top-align-expected.txt
new file mode 100644
index 0000000..e163eca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-position-top-align-expected.txt
@@ -0,0 +1,12 @@
+pre-text  after-text	Something
+Tests for hitTest of element
+bug 45164: REGRESSION:  Clickable area too large
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS hitResult is false
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/normal-flow-hit-test-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/normal-flow-hit-test-expected.png
new file mode 100644
index 0000000..f21c0d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/normal-flow-hit-test-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/normal-flow-hit-test-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/normal-flow-hit-test-expected.txt
new file mode 100644
index 0000000..af3e130
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/layers/normal-flow-hit-test-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x325
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x325
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x301
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 58x19
+        LayoutInline {A} at (0,0) size 0x0 [color=#0000EE]
+          LayoutText {#text} at (0,0) size 306x19
+      LayoutNGBlockFlow (anonymous) at (0,36) size 784x125
+        LayoutText {#text} at (0,0) size 4x19
+        LayoutInline {A} at (0,0) size 0x0 [color=#0000EE]
+          LayoutText {#text} at (0,0) size 61x19
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,281) size 784x20
+        LayoutText {#text} at (0,0) size 168x19
+layer at (18,62) size 100x100
+  LayoutNGBlockFlow {DIV} at (10,10) size 100x100 [bgcolor=#808080]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/W3C-SVG-1.1/text-align-01-b-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/W3C-SVG-1.1/text-align-01-b-expected.png
new file mode 100644
index 0000000..5a51a94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/W3C-SVG-1.1/text-align-01-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/W3C-SVG-1.1/text-align-05-b-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/W3C-SVG-1.1/text-align-05-b-expected.png
new file mode 100644
index 0000000..4e115bb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/W3C-SVG-1.1/text-align-05-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-selection-align-01-b-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-selection-align-01-b-expected.png
new file mode 100644
index 0000000..2399fa2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-selection-align-01-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-selection-align-05-b-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-selection-align-05-b-expected.png
new file mode 100644
index 0000000..ce86e3c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/text/text-selection-align-05-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js
index a827c81..93aa1f7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js
@@ -201,7 +201,7 @@
 
   async createSession() {
     var sessionId = (await DevToolsAPI._sendCommandOrDie('Target.attachToTarget', {targetId: this._targetId})).sessionId;
-    var session = new TestRunner.Session(this, sessionId);
+    var session = new TestRunner.Session(this._testRunner, sessionId);
     DevToolsAPI._sessions.set(sessionId, session);
     return session;
   }
@@ -225,23 +225,47 @@
 };
 
 TestRunner.Session = class {
-  constructor(page, sessionId) {
-    this._testRunner = page._testRunner;
-    this._page = page;
+  constructor(testRunner, sessionId) {
+    this._testRunner = testRunner;
     this._sessionId = sessionId;
     this._requestId = 0;
     this._dispatchTable = new Map();
     this._eventHandlers = new Map();
     this.protocol = this._setupProtocol();
+    this._childSessions = null;
+    this._parentSession = null;
   }
 
   async disconnect() {
     await DevToolsAPI._sendCommandOrDie('Target.detachFromTarget', {sessionId: this._sessionId});
-    DevToolsAPI._sessions.delete(this._page._targetId);
+    if (this._parentSession)
+      this._parentSession._childSessions.delete(this._sessionId);
+    else
+      DevToolsAPI._sessions.delete(this._sessionId);
+  }
+
+  createChild(sessionId) {
+    if (!this._childSessions) {
+      this._childSessions = new Map();
+      this.protocol.Target.onReceivedMessageFromTarget(event => this._dispatchMessageFromTarget(event));
+    }
+    let session = new TestRunner.Session(this._testRunner, sessionId);
+    this._childSessions.set(sessionId, session);
+    session._parentSession = this;
+    return session;
+  }
+
+  _dispatchMessageFromTarget(event) {
+    var session = this._childSessions.get(event.params.sessionId);
+    if (session)
+      session._dispatchMessage(JSON.parse(event.params.message));
   }
 
   sendRawCommand(requestId, message) {
-    DevToolsAPI._sendCommandOrDie('Target.sendMessageToTarget', {sessionId: this._sessionId, message: message});
+    if (this._parentSession)
+      this._parentSession.sendCommand('Target.sendMessageToTarget', {sessionId: this._sessionId, message: message});
+    else
+      DevToolsAPI._sendCommandOrDie('Target.sendMessageToTarget', {sessionId: this._sessionId, message: message});
     return new Promise(f => this._dispatchTable.set(requestId, f));
   }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger-expected.txt
index 38ca574..a2a96f7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger-expected.txt
@@ -1,4 +1,5 @@
 Tests that waitForDebuggerOnStart works with out-of-process iframes.
-sessionId matches: true
-User-Agent = test
+User-Agent = test (subframe)
+content (should have user-agent header overriden): HTTP_USER_AGENT: test
+
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js
index 6e2d348d..267cf81 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/target/wait-for-debugger.js
@@ -6,31 +6,24 @@
   await dp.Target.setAttachToFrames({value: true});
 
   await dp.Page.enable();
+  dp.Network.enable();
+  dp.Network.setUserAgentOverride({userAgent: 'test'});
   session.evaluate(`
     var iframe = document.createElement('iframe');
-    iframe.src = 'http://devtools.oopif.test:8000/inspector-protocol/target/resources/test-page.html';
+    iframe.src = 'http://devtools.oopif.test:8000/inspector-protocol/network/resources/echo-headers.php?headers=HTTP_USER_AGENT';
     document.body.appendChild(iframe);
   `);
 
-  var sessionId = (await dp.Target.onceAttachedToTarget()).params.sessionId;
-  await dp.Target.sendMessageToTarget({
-    sessionId: sessionId,
-    message: JSON.stringify({id: 1, method: 'Network.enable'})
-  });
-  await dp.Target.sendMessageToTarget({
-    sessionId: sessionId,
-    message: JSON.stringify({id: 2, method: 'Network.setUserAgentOverride', params: {userAgent: 'test'}})
-  });
-  dp.Target.sendMessageToTarget({
-    sessionId: sessionId,
-    message: JSON.stringify({id: 3, method: 'Runtime.runIfWaitingForDebugger'})
-  });
-  dp.Target.onReceivedMessageFromTarget(event => {
-    var message = JSON.parse(event.params.message);
-    if (message.method === 'Network.requestWillBeSent') {
-      testRunner.log('sessionId matches: ' + (sessionId === event.params.sessionId));
-      testRunner.log(`User-Agent = ${message.params.request.headers['User-Agent']}`);
-      testRunner.completeTest();
-    }
-  });
+  let sessionId = (await dp.Target.onceAttachedToTarget()).params.sessionId;
+  let dp1 = session.createChild(sessionId).protocol;
+  dp1.Network.enable();
+  dp1.Network.setUserAgentOverride({userAgent: 'test (subframe)'});
+  dp1.Runtime.runIfWaitingForDebugger();
+  let params = (await dp1.Network.onceRequestWillBeSent()).params;
+  testRunner.log(`User-Agent = ${params.request.headers['User-Agent']}`);
+  await dp1.Network.onceLoadingFinished();
+  let content = (await dp1.Network.getResponseBody({requestId: params.requestId})).result.body;
+  testRunner.log(`content (should have user-agent header overriden): ${content}`);
+
+  testRunner.completeTest();
 })
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
index f7f8621d..5848ee3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -122,7 +122,6 @@
 CONSOLE MESSAGE: line 147:     getter url
 CONSOLE MESSAGE: line 147:     method constructor
 CONSOLE MESSAGE: line 147: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 147:     getter type
 CONSOLE MESSAGE: line 147:     getter unit
 CONSOLE MESSAGE: line 147:     getter value
 CONSOLE MESSAGE: line 147:     method constructor
@@ -419,7 +418,6 @@
 CONSOLE MESSAGE: line 147:     getter url
 CONSOLE MESSAGE: line 147:     method constructor
 CONSOLE MESSAGE: line 147: interface CSSUnitValue : CSSNumericValue
-CONSOLE MESSAGE: line 147:     getter type
 CONSOLE MESSAGE: line 147:     getter unit
 CONSOLE MESSAGE: line 147:     getter value
 CONSOLE MESSAGE: line 147:     method constructor
diff --git a/third_party/WebKit/LayoutTests/media/track/track-remove-by-setting-innerHTML.html b/third_party/WebKit/LayoutTests/media/track/track-remove-by-setting-innerHTML.html
deleted file mode 100644
index 040baed..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-remove-by-setting-innerHTML.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<title>This test makes sure that removing a track by setting video.innerHTML doesn't crash (https://bugs.webkit.org/show_bug.cgi?id=100981). If this test does not crash, it passes.</title>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-    <track default="" src="captions-webvtt/captions-gaps.vtt">
-</video>
-</div>
-<script>
-async_test(function(t) {
-    var firstSeek = true;
-    var video = document.querySelector('video');
-    video.onseeked = t.step_func(function() {
-        if (!firstSeek) {
-            t.done();
-            return;
-        }
-
-        // Remove the text track
-        video.innerHTML = '';
-
-        // Seek again to force a repaint.
-        video.currentTime = 7.9;
-        firstSeek = false;
-    });
-    
-    video.currentTime = 0.5;
-    video.src = findMediaFile('video', '../content/counting');
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-remove-insert-ready-state.html b/third_party/WebKit/LayoutTests/media/track/track-remove-insert-ready-state.html
deleted file mode 100644
index 5d602681..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-remove-insert-ready-state.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<title>Tests that re-adding a media element to the document, having a child track that failed loading doesn't block video from playing.</title>
-<video>
-    <track src="captions-webvtt/tc004-no-webvtt.vtt" kind="captions" default>
-</video>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-async_test(function(t) {
-    var video = document.querySelector('video');
-    video.src = findMediaFile('video', '../content/test');
-    video.oncanplaythrough = t.step_func(canplaythrough);
-
-    function canplaythrough() {
-        video.oncanplaythrough = null;
-        var track = document.querySelector('track');
-
-        // Track should have error as ready state.
-        assert_equals(track.readyState, HTMLTrackElement.ERROR);
-
-        // Remove the video element from body.
-        document.body.removeChild(video);
-
-        // Reset the video src attribute to re-trigger resource selection for tracks.
-        video.src = findMediaFile('video', '../content/test');
-
-        // Append the video element back to the body.
-        document.body.appendChild(video);
-
-        assert_equals(track.readyState, HTMLTrackElement.ERROR);
-
-        video.onplaying = t.step_func_done();
-        video.play();
-        // The video should start playing.
-    }
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-remove-quickly.html b/third_party/WebKit/LayoutTests/media/track/track-remove-quickly.html
deleted file mode 100644
index 8649029..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-remove-quickly.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<title>This test that removing a track element before it has been processed doesn't crash (https://bugs.webkit.org/show_bug.cgi?id=85095).</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../media-file.js"></script>
-<div id="video_container"></div>
-<script>
-var mediaFile = findMediaFile("video", "../content/test");
-document.getElementById("video_container").innerHTML = "<video src='" + mediaFile + "' controls ><track kind='captions' src='captions-webvtt/simple-captions.vtt' default ></video>";
-test(function() {
-// Test passes if it doesn't crash.
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/background-obscured-change-invalidate-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/background-obscured-change-invalidate-expected.html
new file mode 100644
index 0000000..2b13fb5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/background-obscured-change-invalidate-expected.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="match" href="background-obscured-change-invalidate-expected.html">
+<style>
+#test {
+  background-image: linear-gradient(to top, green 50%, green 50%);
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  width: 100px;
+  height: 100px;
+}
+
+#child {
+  border: 1px solid black;
+}
+</style>
+<div id=test class="border-color">
+    <div id=child>test</div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/background-obscured-change-invalidate.html b/third_party/WebKit/LayoutTests/paint/invalidation/background-obscured-change-invalidate.html
new file mode 100644
index 0000000..44e2f83
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/background-obscured-change-invalidate.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<link rel="match" href="background-obscured-change-invalidate-expected.html">
+<style>
+#test {
+  background-image: linear-gradient(to top, green 50%, green 50%);
+  background-size: 0% 100%;
+  background-repeat: no-repeat;
+  width: 100px;
+  height: 100px;
+}
+
+#child {
+  border: 1px solid black;
+}
+</style>
+<div id=test class="border-color">
+	<div id=child>test</div>
+</div>
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+
+<script>
+runAfterLayoutAndPaint(function() {
+  document.getElementById("test").style.backgroundSize = "100% 100%";
+}, true);
+</script>
diff --git a/third_party/WebKit/LayoutTests/platform/win7/external/wpt/fetch/api/request/request-keepalive-quota-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/external/wpt/fetch/api/request/request-keepalive-quota-expected.txt
deleted file mode 100644
index 14d6d4c0..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/external/wpt/fetch/api/request/request-keepalive-quota-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-PASS A Keep-Alive fetch() with a small body should succeed.
-FAIL A Keep-Alive fetch() with a body at the Quota Limit should succeed. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS A Keep-Alive fetch() with a body over the Quota Limit should reject.
-FAIL A Keep-Alive fetch() should return its allocated Quota upon promise resolution. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL A Keep-Alive fetch() should return only its allocated Quota upon promise resolution. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL A Keep-Alive fetch() should not be allowed if the Quota is used up. promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html b/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html
index d2eef72..f09374b 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/cssUnitValue.html
@@ -47,7 +47,6 @@
 function validateUnitValue(unitValue, value, unit, type, cssText) {
   assert_equals(unitValue.value, value, 'value');
   assert_equals(unitValue.unit, unit, 'unit');
-  assert_equals(unitValue.type, type, 'type');
 }
 
 function generateTests(unitList, typeString) {
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 04eb616..151c453 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -854,7 +854,6 @@
     method constructor
 interface CSSUnitValue : CSSNumericValue
     attribute @@toStringTag
-    getter type
     getter unit
     getter value
     method constructor
diff --git a/third_party/WebKit/Source/bindings/modules/v8/generated.gni b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
index 5fd6d68..0125196 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/generated.gni
+++ b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
@@ -101,6 +101,18 @@
   "$bindings_modules_v8_output_dir/v8_position_error_callback.h",
   "$bindings_modules_v8_output_dir/v8_remote_playback_availability_callback.cc",
   "$bindings_modules_v8_output_dir/v8_remote_playback_availability_callback.h",
+  "$bindings_modules_v8_output_dir/v8_rtc_peer_connection_error_callback.cc",
+  "$bindings_modules_v8_output_dir/v8_rtc_peer_connection_error_callback.h",
+  "$bindings_modules_v8_output_dir/v8_rtc_session_description_callback.cc",
+  "$bindings_modules_v8_output_dir/v8_rtc_session_description_callback.h",
+  "$bindings_modules_v8_output_dir/v8_rtc_stats_callback.cc",
+  "$bindings_modules_v8_output_dir/v8_rtc_stats_callback.h",
+  "$bindings_modules_v8_output_dir/v8_storage_error_callback.cc",
+  "$bindings_modules_v8_output_dir/v8_storage_error_callback.h",
+  "$bindings_modules_v8_output_dir/v8_storage_quota_callback.cc",
+  "$bindings_modules_v8_output_dir/v8_storage_quota_callback.h",
+  "$bindings_modules_v8_output_dir/v8_storage_usage_callback.cc",
+  "$bindings_modules_v8_output_dir/v8_storage_usage_callback.h",
   "$bindings_modules_v8_output_dir/v8_xr_frame_request_callback.cc",
   "$bindings_modules_v8_output_dir/v8_xr_frame_request_callback.h",
 ]
diff --git a/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueDeserializerForModules.cpp b/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueDeserializerForModules.cpp
index e8b6a30..8e37139 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueDeserializerForModules.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueDeserializerForModules.cpp
@@ -47,6 +47,8 @@
         return nullptr;
       std::unique_ptr<WebRTCCertificateGenerator> certificate_generator(
           Platform::Current()->CreateRTCCertificateGenerator());
+      if (!certificate_generator)
+        return nullptr;
       std::unique_ptr<WebRTCCertificate> certificate =
           certificate_generator->FromPEM(pem_private_key, pem_certificate);
       if (!certificate)
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 780a8a9..28bb36dc 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueSerializerForModulesTest.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/serialization/V8ScriptValueSerializerForModulesTest.cpp
@@ -144,18 +144,16 @@
     0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
     0x2d, 0x0a};
 
-// TODO(https://crbug.com/795627): This test is crashing on the Cast Audio Linux
-// bot.
-#if defined(OS_LINUX)
-TEST(V8ScriptValueSerializerForModulesTest, DISABLED_RoundTripRTCCertificate) {
-#else
 TEST(V8ScriptValueSerializerForModulesTest, RoundTripRTCCertificate) {
-#endif
+  // If WebRTC is not supported in this build, this test is meaningless.
+  std::unique_ptr<WebRTCCertificateGenerator> certificate_generator(
+      Platform::Current()->CreateRTCCertificateGenerator());
+  if (!certificate_generator)
+    return;
+
   V8TestingScope scope;
 
   // Make a certificate with the existing key above.
-  std::unique_ptr<WebRTCCertificateGenerator> certificate_generator(
-      Platform::Current()->CreateRTCCertificateGenerator());
   std::unique_ptr<WebRTCCertificate> web_certificate =
       certificate_generator->FromPEM(
           WebString::FromUTF8(kEcdsaPrivateKey, sizeof(kEcdsaPrivateKey)),
@@ -175,13 +173,13 @@
   EXPECT_EQ(kEcdsaCertificate, pem.Certificate());
 }
 
-// TODO(https://crbug.com/795627): This test is crashing on the Cast Audio Linux
-// bot.
-#if defined(OS_LINUX)
-TEST(V8ScriptValueSerializerForModulesTest, DISABLED_DecodeRTCCertificate) {
-#else
 TEST(V8ScriptValueSerializerForModulesTest, DecodeRTCCertificate) {
-#endif
+  // If WebRTC is not supported in this build, this test is meaningless.
+  std::unique_ptr<WebRTCCertificateGenerator> certificate_generator(
+      Platform::Current()->CreateRTCCertificateGenerator());
+  if (!certificate_generator)
+    return;
+
   V8TestingScope scope;
 
   // This is encoded data generated from Chromium (around M55).
@@ -202,14 +200,7 @@
   EXPECT_EQ(kEcdsaCertificate, pem.Certificate());
 }
 
-// TODO(https://crbug.com/795627): This test is crashing on the Cast Audio Linux
-// bot.
-#if defined(OS_LINUX)
-TEST(V8ScriptValueSerializerForModulesTest,
-     DISABLED_DecodeInvalidRTCCertificate) {
-#else
 TEST(V8ScriptValueSerializerForModulesTest, DecodeInvalidRTCCertificate) {
-#endif
   V8TestingScope scope;
 
   // This is valid, except that "private" is not a valid private key PEM and
diff --git a/third_party/WebKit/Source/bindings/scripts/idl_types.py b/third_party/WebKit/Source/bindings/scripts/idl_types.py
index b30aa692..d4f4acb 100644
--- a/third_party/WebKit/Source/bindings/scripts/idl_types.py
+++ b/third_party/WebKit/Source/bindings/scripts/idl_types.py
@@ -87,8 +87,6 @@
 STANDARD_CALLBACK_FUNCTIONS = frozenset([
     # http://heycam.github.io/webidl/#common-Function
     'Function',
-    # http://heycam.github.io/webidl/#common-VoidFunction
-    'VoidFunction',
 ])
 
 
diff --git a/third_party/WebKit/Source/controller/OomInterventionImpl.cpp b/third_party/WebKit/Source/controller/OomInterventionImpl.cpp
index cc9700b..14f43fd 100644
--- a/third_party/WebKit/Source/controller/OomInterventionImpl.cpp
+++ b/third_party/WebKit/Source/controller/OomInterventionImpl.cpp
@@ -5,19 +5,77 @@
 #include "controller/OomInterventionImpl.h"
 
 #include "mojo/public/cpp/bindings/strong_binding.h"
+#include "platform/WebTaskRunner.h"
+#include "platform/bindings/V8PerIsolateData.h"
+#include "platform/heap/Handle.h"
+#include "platform/wtf/allocator/Partitions.h"
+#include "public/platform/Platform.h"
 
 namespace blink {
 
-// static
-void OomInterventionImpl::Create(mojom::blink::OomInterventionRequest request) {
-  mojo::MakeStrongBinding(std::make_unique<OomInterventionImpl>(),
-                          std::move(request));
+namespace {
+
+// Roughly caclculates amount of memory which is used to execute pages.
+size_t BlinkMemoryWorkloadCaculator() {
+  v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate();
+  DCHECK(isolate);
+  v8::HeapStatistics heap_statistics;
+  isolate->GetHeapStatistics(&heap_statistics);
+  // TODO: Add memory usage for worker threads.
+  size_t v8_size =
+      heap_statistics.total_heap_size() + heap_statistics.malloced_memory();
+  size_t blink_gc_size = ProcessHeap::TotalAllocatedObjectSize() +
+                         ProcessHeap::TotalMarkedObjectSize();
+  size_t partition_alloc_size = WTF::Partitions::TotalSizeOfCommittedPages();
+  return v8_size + blink_gc_size + partition_alloc_size;
 }
 
-// The ScopedPagePauser is destryed when the intervention is declined and mojo
-// strong binding is disconnected.
-OomInterventionImpl::OomInterventionImpl() = default;
+}  // namespace
+
+// If memory workload is above this threshold, we assume that we are in a
+// near-OOM situation.
+const size_t OomInterventionImpl::kMemoryWorkloadThreshold = 80 * 1024 * 1024;
+
+// static
+void OomInterventionImpl::Create(mojom::blink::OomInterventionRequest request) {
+  mojo::MakeStrongBinding(
+      std::make_unique<OomInterventionImpl>(
+          WTF::BindRepeating(&BlinkMemoryWorkloadCaculator)),
+      std::move(request));
+}
+
+OomInterventionImpl::OomInterventionImpl(
+    MemoryWorkloadCaculator workload_calculator)
+    : workload_calculator_(std::move(workload_calculator)),
+      timer_(this, &OomInterventionImpl::Check) {
+  DCHECK(workload_calculator_);
+}
 
 OomInterventionImpl::~OomInterventionImpl() = default;
 
+void OomInterventionImpl::StartDetection(
+    mojom::blink::OomInterventionHostPtr host,
+    bool trigger_intervention) {
+  host_ = std::move(host);
+  trigger_intervention_ = trigger_intervention;
+
+  timer_.Start(TimeDelta(), TimeDelta::FromSeconds(1), FROM_HERE);
+}
+
+void OomInterventionImpl::Check(TimerBase*) {
+  DCHECK(host_);
+
+  size_t workload = workload_calculator_.Run();
+  if (workload > kMemoryWorkloadThreshold) {
+    host_->OnHighMemoryUsage(trigger_intervention_);
+
+    if (trigger_intervention_) {
+      // The ScopedPagePauser is destroyed when the intervention is declined and
+      // mojo strong binding is disconnected.
+      pauser_.reset(new ScopedPagePauser);
+    }
+    return;
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/controller/OomInterventionImpl.h b/third_party/WebKit/Source/controller/OomInterventionImpl.h
index 294bad03..a05bccfc 100644
--- a/third_party/WebKit/Source/controller/OomInterventionImpl.h
+++ b/third_party/WebKit/Source/controller/OomInterventionImpl.h
@@ -7,10 +7,13 @@
 
 #include "controller/ControllerExport.h"
 #include "core/page/ScopedPagePauser.h"
+#include "platform/Timer.h"
 #include "public/platform/oom_intervention.mojom-blink.h"
 
 namespace blink {
 
+class OomInterventionImplTest;
+
 // Implementation of OOM intervention. This pauses all pages by using
 // ScopedPagePauser when near-OOM situation is detected.
 class CONTROLLER_EXPORT OomInterventionImpl
@@ -18,11 +21,28 @@
  public:
   static void Create(mojom::blink::OomInterventionRequest);
 
-  OomInterventionImpl();
+  using MemoryWorkloadCaculator = base::RepeatingCallback<size_t()>;
+
+  explicit OomInterventionImpl(MemoryWorkloadCaculator);
   ~OomInterventionImpl() override;
 
+  // mojom::blink::OomIntervention:
+  void StartDetection(mojom::blink::OomInterventionHostPtr,
+                      bool trigger_intervention) override;
+
  private:
-  ScopedPagePauser pauser_;
+  FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, DetectedAndDeclined);
+
+  void Check(TimerBase*);
+
+  // This constant is declared here for testing.
+  static const size_t kMemoryWorkloadThreshold;
+
+  MemoryWorkloadCaculator workload_calculator_;
+  mojom::blink::OomInterventionHostPtr host_;
+  bool trigger_intervention_ = false;
+  Timer<OomInterventionImpl> timer_;
+  std::unique_ptr<ScopedPagePauser> pauser_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/controller/OomInterventionImplTest.cpp b/third_party/WebKit/Source/controller/OomInterventionImplTest.cpp
index 0dc49d14..8400b18 100644
--- a/third_party/WebKit/Source/controller/OomInterventionImplTest.cpp
+++ b/third_party/WebKit/Source/controller/OomInterventionImplTest.cpp
@@ -10,13 +10,35 @@
 #include "core/frame/WebLocalFrameImpl.h"
 #include "core/page/Page.h"
 #include "core/testing/DummyPageHolder.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "platform/testing/UnitTestHelpers.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 
+namespace {
+
+class MockOomInterventionHost : public mojom::blink::OomInterventionHost {
+ public:
+  MockOomInterventionHost(mojom::blink::OomInterventionHostRequest request)
+      : binding_(this, std::move(request)) {}
+  ~MockOomInterventionHost() = default;
+
+  void OnHighMemoryUsage(bool intervention_triggered) override {}
+
+ private:
+  mojo::Binding<mojom::blink::OomInterventionHost> binding_;
+};
+
+}  // namespace
+
 class OomInterventionImplTest : public ::testing::Test {
+ public:
+  size_t MockMemoryWorkloadCalculator() { return memory_workload_; }
+
  protected:
+  size_t memory_workload_ = 0;
   FrameTestHelpers::WebViewHelper web_view_helper_;
 };
 
@@ -25,7 +47,17 @@
   Page* page = web_view->MainFrameImpl()->GetFrame()->GetPage();
   EXPECT_FALSE(page->Paused());
 
-  auto intervention = std::make_unique<OomInterventionImpl>();
+  auto intervention = std::make_unique<OomInterventionImpl>(
+      WTF::BindRepeating(&OomInterventionImplTest::MockMemoryWorkloadCalculator,
+                         WTF::Unretained(this)));
+  EXPECT_FALSE(page->Paused());
+
+  memory_workload_ = OomInterventionImpl::kMemoryWorkloadThreshold + 1;
+  mojom::blink::OomInterventionHostPtr host_ptr;
+  MockOomInterventionHost mock_host(mojo::MakeRequest(&host_ptr));
+  intervention->StartDetection(std::move(host_ptr),
+                               true /*trigger_intervention*/);
+  testing::RunDelayedTasks(TimeDelta::FromSeconds(1));
   EXPECT_TRUE(page->Paused());
 
   intervention.reset();
diff --git a/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp b/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
index 28e08f5..1293cd1 100644
--- a/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
@@ -80,8 +80,7 @@
 TEST(CSSCalculationValue, AccumulatePixelsAndPercent) {
   scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
   style->SetEffectiveZoom(5);
-  CSSToLengthConversionData conversion_data(style.get(), style.get(),
-                                            LayoutViewItem(nullptr),
+  CSSToLengthConversionData conversion_data(style.get(), style.get(), nullptr,
                                             style->EffectiveZoom());
 
   TestAccumulatePixelsAndPercent(
diff --git a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
index e2e6785..70804d8 100644
--- a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
@@ -132,8 +132,7 @@
   // TODO: Break dependency on LayoutObject.
   const LayoutObject& layout_object = static_cast<const LayoutObject&>(client);
   CSSToLengthConversionData conversion_data(
-      &style, root_style, LayoutViewItem(layout_object.View()),
-      style.EffectiveZoom());
+      &style, root_style, layout_object.View(), style.EffectiveZoom());
 
   switch (GetClassType()) {
     case kLinearGradientClass:
diff --git a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
index 2367147d..76103eb 100644
--- a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
+++ b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
@@ -31,7 +31,7 @@
 #include "core/css/CSSToLengthConversionData.h"
 
 #include "core/css/CSSResolutionUnits.h"
-#include "core/layout/api/LayoutViewItem.h"
+#include "core/layout/LayoutView.h"
 #include "core/style/ComputedStyle.h"
 
 namespace blink {
@@ -71,10 +71,9 @@
 }
 
 CSSToLengthConversionData::ViewportSize::ViewportSize(
-    const LayoutViewItem& layout_view_item)
-    : size_(!layout_view_item.IsNull()
-                ? layout_view_item.ViewportSizeForViewportUnits()
-                : DoubleSize()) {}
+    const LayoutView* layout_view)
+    : size_(layout_view ? layout_view->ViewportSizeForViewportUnits()
+                        : DoubleSize()) {}
 
 CSSToLengthConversionData::CSSToLengthConversionData(
     const ComputedStyle* style,
@@ -89,11 +88,11 @@
 CSSToLengthConversionData::CSSToLengthConversionData(
     const ComputedStyle* style,
     const ComputedStyle* root_style,
-    const LayoutViewItem& layout_view_item,
+    const LayoutView* layout_view,
     float zoom)
     : CSSToLengthConversionData(style,
                                 FontSizes(style, root_style),
-                                ViewportSize(layout_view_item),
+                                ViewportSize(layout_view),
                                 zoom) {}
 
 double CSSToLengthConversionData::ViewportWidthPercent() const {
diff --git a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h
index 548c3ff..46ee246 100644
--- a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h
+++ b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h
@@ -42,7 +42,7 @@
 namespace blink {
 
 class ComputedStyle;
-class LayoutViewItem;
+class LayoutView;
 class Font;
 
 class CORE_EXPORT CSSToLengthConversionData {
@@ -74,7 +74,7 @@
    public:
     ViewportSize() = default;
     ViewportSize(double width, double height) : size_(width, height) {}
-    explicit ViewportSize(const LayoutViewItem&);
+    explicit ViewportSize(const LayoutView*);
 
     double Width() const { return size_.Width(); }
     double Height() const { return size_.Height(); }
@@ -90,7 +90,7 @@
                             float zoom);
   CSSToLengthConversionData(const ComputedStyle* curr_style,
                             const ComputedStyle* root_style,
-                            const LayoutViewItem&,
+                            const LayoutView*,
                             float zoom);
 
   float Zoom() const { return zoom_; }
diff --git a/third_party/WebKit/Source/core/css/MediaValues.cpp b/third_party/WebKit/Source/core/css/MediaValues.cpp
index c991441..3a489a18 100644
--- a/third_party/WebKit/Source/core/css/MediaValues.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValues.cpp
@@ -125,11 +125,11 @@
 
 bool MediaValues::CalculateThreeDEnabled(LocalFrame* frame) {
   DCHECK(frame);
-  DCHECK(!frame->ContentLayoutItem().IsNull());
-  DCHECK(frame->ContentLayoutItem().Compositor());
+  DCHECK(frame->ContentLayoutObject());
+  DCHECK(frame->ContentLayoutObject()->Compositor());
   bool three_d_enabled = false;
-  if (LayoutViewItem view = frame->ContentLayoutItem())
-    three_d_enabled = view.Compositor()->HasAcceleratedCompositing();
+  if (LayoutView* view = frame->ContentLayoutObject())
+    three_d_enabled = view->Compositor()->HasAcceleratedCompositing();
   return three_d_enabled;
 }
 
diff --git a/third_party/WebKit/Source/core/css/MediaValuesCached.cpp b/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
index ba662f6..240c02a5 100644
--- a/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
@@ -41,7 +41,7 @@
   DCHECK(!frame || frame->View());
   if (frame && frame->View()) {
     DCHECK(frame->GetDocument());
-    DCHECK(!frame->GetDocument()->GetLayoutViewItem().IsNull());
+    DCHECK(frame->GetDocument()->GetLayoutView());
 
     // In case that frame is missing (e.g. for images that their document does
     // not have a frame)
diff --git a/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp b/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
index 38890ea..b2f66c8 100644
--- a/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
@@ -20,7 +20,7 @@
 
 MediaValues* MediaValuesDynamic::Create(LocalFrame* frame) {
   if (!frame || !frame->View() || !frame->GetDocument() ||
-      frame->GetDocument()->GetLayoutViewItem().IsNull())
+      !frame->GetDocument()->GetLayoutView())
     return MediaValuesCached::Create();
   return new MediaValuesDynamic(frame);
 }
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
index 4a773c0..68e9a5d1 100644
--- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp
+++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -418,9 +418,9 @@
       return kSelectorFailsAllSiblings;
 
     case CSSSelector::kShadowPseudo: {
-      if (!is_ua_rule_ &&
-          context.selector->GetPseudoType() == CSSSelector::kPseudoShadow &&
-          mode_ == kQueryingRules) {
+      DCHECK(mode_ == kQueryingRules ||
+             context.selector->GetPseudoType() != CSSSelector::kPseudoShadow);
+      if (context.selector->GetPseudoType() == CSSSelector::kPseudoShadow) {
         UseCounter::Count(context.element->GetDocument(),
                           WebFeature::kPseudoShadowInStaticProfile);
       }
@@ -439,15 +439,9 @@
     }
 
     case CSSSelector::kShadowDeep: {
-      if (!is_ua_rule_) {
-        if (mode_ == kQueryingRules) {
-          UseCounter::Count(context.element->GetDocument(),
-                            WebFeature::kDeepCombinatorInStaticProfile);
-        } else {
-          Deprecation::CountDeprecation(context.element->GetDocument(),
-                                        WebFeature::kCSSDeepCombinator);
-        }
-      }
+      DCHECK(mode_ == kQueryingRules);
+      UseCounter::Count(context.element->GetDocument(),
+                        WebFeature::kDeepCombinatorInStaticProfile);
       if (ShadowRoot* root = context.element->ContainingShadowRoot()) {
         if (root->GetType() == ShadowRootType::kUserAgent)
           return kSelectorFailsCompletely;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
index f14e374..7edc2a192 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
@@ -78,10 +78,6 @@
   return CSSPrimitiveValue::UnitTypeToString(unit_);
 }
 
-String CSSUnitValue::type() const {
-  return StyleValueTypeToString(GetType());
-}
-
 CSSStyleValue::StyleValueType CSSUnitValue::GetType() const {
   if (unit_ == CSSPrimitiveValue::UnitType::kNumber)
     return StyleValueType::kNumberType;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h
index d60fd53..18eac26 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h
@@ -33,7 +33,6 @@
   double value() const { return value_; }
   void setUnit(const String& new_unit, ExceptionState&);
   String unit() const;
-  String type() const;
 
   // Internal methods.
   CSSPrimitiveValue::UnitType GetInternalUnit() const { return unit_; }
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.idl b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.idl
index c00d6c4..b876813 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.idl
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.idl
@@ -13,5 +13,4 @@
 ] interface CSSUnitValue : CSSNumericValue {
   [EnforceRange] attribute double value;
   [RaisesException=Setter] attribute DOMString unit;
-  readonly attribute DOMString type;
 };
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp
index f3a9608..69b9b4c 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp
@@ -83,7 +83,7 @@
   // FIXME: Improve RAII of StyleResolverState to remove this function.
   style_ = std::move(style);
   css_to_length_conversion_data_ = CSSToLengthConversionData(
-      style_.get(), RootElementStyle(), GetDocument().GetLayoutViewItem(),
+      style_.get(), RootElementStyle(), GetDocument().GetLayoutView(),
       style_->EffectiveZoom());
 }
 
@@ -97,7 +97,7 @@
   CSSToLengthConversionData::FontSizes font_sizes(em, rem,
                                                   &ParentStyle()->GetFont());
   CSSToLengthConversionData::ViewportSize viewport_size(
-      GetDocument().GetLayoutViewItem());
+      GetDocument().GetLayoutView());
 
   return CSSToLengthConversionData(Style(), font_sizes, viewport_size, 1);
 }
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 81f45c2..b282a93c 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -180,7 +180,6 @@
 #include "core/layout/LayoutView.h"
 #include "core/layout/TextAutosizer.h"
 #include "core/layout/api/LayoutEmbeddedContentItem.h"
-#include "core/layout/api/LayoutViewItem.h"
 #include "core/loader/CookieJar.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameFetchContext.h"
@@ -732,7 +731,7 @@
 }
 
 Document::~Document() {
-  DCHECK(GetLayoutViewItem().IsNull());
+  DCHECK(!GetLayoutView());
   DCHECK(!ParentTreeScope());
   // If a top document with a cache, verify that it was comprehensively
   // cleared during detach.
@@ -1547,7 +1546,7 @@
 }
 
 Element* Document::ElementFromPoint(double x, double y) const {
-  if (GetLayoutViewItem().IsNull())
+  if (!GetLayoutView())
     return nullptr;
 
   return TreeScope::ElementFromPoint(x, y);
@@ -1555,13 +1554,13 @@
 
 HeapVector<Member<Element>> Document::ElementsFromPoint(double x,
                                                         double y) const {
-  if (GetLayoutViewItem().IsNull())
+  if (!GetLayoutView())
     return HeapVector<Member<Element>>();
   return TreeScope::ElementsFromPoint(x, y);
 }
 
 Range* Document::caretRangeFromPoint(int x, int y) {
-  if (GetLayoutViewItem().IsNull())
+  if (!GetLayoutView())
     return nullptr;
 
   HitTestResult result = HitTestInDocument(this, x, y);
@@ -2049,8 +2048,7 @@
             static_cast<OverscrollBehaviorType>(overscroll_behavior_y)));
   }
 
-  scoped_refptr<ComputedStyle> viewport_style =
-      GetLayoutViewItem().MutableStyle();
+  scoped_refptr<ComputedStyle> viewport_style = GetLayoutView()->MutableStyle();
   if (viewport_style->GetWritingMode() != root_writing_mode ||
       viewport_style->Direction() != root_direction ||
       viewport_style->VisitedDependentColor(GetCSSPropertyBackgroundColor()) !=
@@ -2084,7 +2082,7 @@
     new_style->SetScrollBehavior(scroll_behavior);
     new_style->SetOverscrollBehaviorX(overscroll_behavior_x);
     new_style->SetOverscrollBehaviorY(overscroll_behavior_y);
-    GetLayoutViewItem().SetStyle(new_style);
+    GetLayoutView()->SetStyle(new_style);
     SetupFontBuilder(*new_style);
   }
 }
@@ -2185,7 +2183,7 @@
 
   if (focused_element_ && !focused_element_->IsFocusable())
     ClearFocusedElementSoon();
-  GetLayoutViewItem().ClearHitTestCache();
+  GetLayoutView()->ClearHitTestCache();
 
   DCHECK(!DocumentAnimations::NeedsAnimationTimingUpdate(*this));
 
@@ -2236,9 +2234,9 @@
     scoped_refptr<ComputedStyle> viewport_style =
         StyleResolver::StyleForViewport(*this);
     StyleRecalcChange local_change = ComputedStyle::StylePropagationDiff(
-        viewport_style.get(), GetLayoutViewItem().Style());
+        viewport_style.get(), GetLayoutView()->Style());
     if (local_change != kNoChange)
-      GetLayoutViewItem().SetStyle(std::move(viewport_style));
+      GetLayoutView()->SetStyle(std::move(viewport_style));
   }
 
   ClearNeedsStyleRecalc();
@@ -2318,13 +2316,13 @@
 }
 
 void Document::NotifyLayoutTreeOfSubtreeChanges() {
-  if (!GetLayoutViewItem().WasNotifiedOfSubtreeChange())
+  if (!GetLayoutView()->WasNotifiedOfSubtreeChange())
     return;
 
   lifecycle_.AdvanceTo(DocumentLifecycle::kInLayoutSubtreeChange);
 
-  GetLayoutViewItem().HandleSubtreeModifications();
-  DCHECK(!GetLayoutViewItem().WasNotifiedOfSubtreeChange());
+  GetLayoutView()->HandleSubtreeModifications();
+  DCHECK(!GetLayoutView()->WasNotifiedOfSubtreeChange());
 
   lifecycle_.AdvanceTo(DocumentLifecycle::kLayoutSubtreeChangeClean);
 }
@@ -3265,9 +3263,8 @@
     UpdateStyleAndLayoutTree();
 
     // Always do a layout after loading if needed.
-    if (View() && !GetLayoutViewItem().IsNull() &&
-        (!GetLayoutViewItem().FirstChild() ||
-         GetLayoutViewItem().NeedsLayout()))
+    if (View() && GetLayoutView() &&
+        (!GetLayoutView()->FirstChild() || GetLayoutView()->NeedsLayout()))
       View()->UpdateLayout();
 
     // TODO(bokan): This is a temporary fix to https://crbug.com/788486.
@@ -3279,7 +3276,7 @@
 
   load_event_progress_ = kLoadEventCompleted;
 
-  if (GetFrame() && !GetLayoutViewItem().IsNull() &&
+  if (GetFrame() && GetLayoutView() &&
       GetSettings()->GetAccessibilityEnabled()) {
     if (AXObjectCache* cache = GetOrCreateAXObjectCache()) {
       if (this == &AXObjectCacheOwner())
@@ -4083,7 +4080,7 @@
     const HitTestRequest& request,
     const LayoutPoint& document_point,
     const WebMouseEvent& event) {
-  DCHECK(GetLayoutViewItem().IsNull() || GetLayoutViewItem().IsLayoutView());
+  DCHECK(!GetLayoutView() || GetLayoutView()->IsLayoutView());
 
   // LayoutView::hitTest causes a layout, and we don't want to hit that until
   // the first layout because until then, there is nothing shown on the screen -
@@ -4091,12 +4088,12 @@
   // page.  Furthermore, mousemove events before the first layout should not
   // lead to a premature layout() happening, which could show a flash of white.
   // See also the similar code in EventHandler::hitTestResultAtPoint.
-  if (GetLayoutViewItem().IsNull() || !View() || !View()->DidFirstLayout())
+  if (!GetLayoutView() || !View() || !View()->DidFirstLayout())
     return MouseEventWithHitTestResults(event,
                                         HitTestResult(request, LayoutPoint()));
 
   HitTestResult result(request, document_point);
-  GetLayoutViewItem().HitTest(result);
+  GetLayoutView()->HitTest(result);
 
   if (!request.ReadOnly())
     UpdateHoverActiveState(request, result.InnerElement());
@@ -4373,9 +4370,9 @@
     // or style recalc while sheets are still loading to avoid FOUC.
     pending_sheet_layout_ = kIgnoreLayoutWithPendingSheets;
 
-    DCHECK(!GetLayoutViewItem().IsNull() || ImportsController());
-    if (!GetLayoutViewItem().IsNull())
-      GetLayoutViewItem().InvalidatePaintForViewAndCompositedLayers();
+    DCHECK(GetLayoutView() || ImportsController());
+    if (GetLayoutView())
+      GetLayoutView()->InvalidatePaintForViewAndCompositedLayers();
   }
 }
 
@@ -5052,7 +5049,7 @@
 
   // TODO(bokan): This looks like it doesn't work in OOPIF.
   DCHECK(GetFrame());
-  return GetFrame()->OwnerLayoutItem().IsNull();
+  return !GetFrame()->OwnerLayoutObject();
 }
 
 String Document::cookie(ExceptionState& exception_state) const {
@@ -5509,8 +5506,8 @@
   if (should_use_visual_ordering != visually_ordered_) {
     visually_ordered_ = should_use_visual_ordering;
     // FIXME: How is possible to not have a layoutObject here?
-    if (!GetLayoutViewItem().IsNull()) {
-      GetLayoutViewItem().MutableStyleRef().SetRtlOrdering(
+    if (GetLayoutView()) {
+      GetLayoutView()->MutableStyleRef().SetRtlOrdering(
           visually_ordered_ ? EOrder::kVisual : EOrder::kLogical);
     }
     SetNeedsStyleRecalc(kSubtreeStyleChange,
@@ -7132,10 +7129,6 @@
     shadow_cascade_order_ = order;
 }
 
-LayoutViewItem Document::GetLayoutViewItem() const {
-  return LayoutViewItem(layout_view_);
-}
-
 PropertyRegistry* Document::GetPropertyRegistry() {
   // TODO(timloh): When the flag is removed, return a reference instead.
   if (!property_registry_ && RuntimeEnabledFeatures::CSSVariables2Enabled())
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index e3f059e..69757d2 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -136,7 +136,6 @@
 class IntersectionObserverController;
 class LayoutPoint;
 class LayoutView;
-class LayoutViewItem;
 class LiveNodeListBase;
 class LocalDOMWindow;
 class Locale;
@@ -579,7 +578,6 @@
   void GetLayoutObject() const = delete;
 
   LayoutView* GetLayoutView() const { return layout_view_; }
-  LayoutViewItem GetLayoutViewItem() const;
 
   Document& AXObjectCacheOwner() const;
   AXObjectCache* ExistingAXObjectCache() const;
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl
index 3582c72..da80659 100644
--- a/third_party/WebKit/Source/core/dom/Document.idl
+++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -158,8 +158,7 @@
     [MeasureAs=DocumentCaptureEvents] void captureEvents();
     [MeasureAs=DocumentReleaseEvents] void releaseEvents();
 
-    // TODO: |all| should be [SameObject].
-    [MeasureAs=DocumentAll] readonly attribute HTMLAllCollection all;
+    [SameObject, MeasureAs=DocumentAll] readonly attribute HTMLAllCollection all;
 
     // CSS Object Model (CSSOM)
     // https://drafts.csswg.org/cssom/#extensions-to-the-document-interface
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 157e2670..38f979a 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -791,19 +791,19 @@
   bool in_quirks_mode = GetDocument().InQuirksMode();
   if ((!in_quirks_mode && GetDocument().documentElement() == this) ||
       (in_quirks_mode && IsHTMLElement() && GetDocument().body() == this)) {
-    LayoutViewItem layout_view = GetDocument().GetLayoutViewItem();
-    if (!layout_view.IsNull()) {
+    auto* layout_view = GetDocument().GetLayoutView();
+    if (layout_view) {
       if (!RuntimeEnabledFeatures::OverlayScrollbarsEnabled() ||
           !GetDocument().GetFrame()->IsLocalRoot())
         GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
       if (GetDocument().GetPage()->GetSettings().GetForceZeroLayoutHeight())
         return AdjustForAbsoluteZoom::AdjustLayoutUnit(
-                   layout_view.OverflowClipRect(LayoutPoint()).Width(),
-                   layout_view.StyleRef())
+                   layout_view->OverflowClipRect(LayoutPoint()).Width(),
+                   layout_view->StyleRef())
             .Round();
       return AdjustForAbsoluteZoom::AdjustLayoutUnit(
-                 LayoutUnit(layout_view.GetLayoutSize().Width()),
-                 layout_view.StyleRef())
+                 LayoutUnit(layout_view->GetLayoutSize().Width()),
+                 layout_view->StyleRef())
           .Round();
     }
   }
@@ -827,19 +827,19 @@
 
   if ((!in_quirks_mode && GetDocument().documentElement() == this) ||
       (in_quirks_mode && IsHTMLElement() && GetDocument().body() == this)) {
-    LayoutViewItem layout_view = GetDocument().GetLayoutViewItem();
-    if (!layout_view.IsNull()) {
+    auto* layout_view = GetDocument().GetLayoutView();
+    if (layout_view) {
       if (!RuntimeEnabledFeatures::OverlayScrollbarsEnabled() ||
           !GetDocument().GetFrame()->IsLocalRoot())
         GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
       if (GetDocument().GetPage()->GetSettings().GetForceZeroLayoutHeight())
         return AdjustForAbsoluteZoom::AdjustLayoutUnit(
-                   layout_view.OverflowClipRect(LayoutPoint()).Height(),
-                   layout_view.StyleRef())
+                   layout_view->OverflowClipRect(LayoutPoint()).Height(),
+                   layout_view->StyleRef())
             .Round();
       return AdjustForAbsoluteZoom::AdjustLayoutUnit(
-                 LayoutUnit(layout_view.GetLayoutSize().Height()),
-                 layout_view.StyleRef())
+                 LayoutUnit(layout_view->GetLayoutSize().Height()),
+                 layout_view->StyleRef())
           .Round();
     }
   }
diff --git a/third_party/WebKit/Source/core/dom/TreeScope.cpp b/third_party/WebKit/Source/core/dom/TreeScope.cpp
index 5bcfdcc..7694011c 100644
--- a/third_party/WebKit/Source/core/dom/TreeScope.cpp
+++ b/third_party/WebKit/Source/core/dom/TreeScope.cpp
@@ -237,7 +237,7 @@
     return HitTestResult();
 
   HitTestResult result(request, LayoutPoint(hit_point));
-  document->GetLayoutViewItem().HitTest(result);
+  document->GetLayoutView()->HitTest(result);
   return result;
 }
 
@@ -309,7 +309,7 @@
                          HitTestRequest::kListBased |
                          HitTestRequest::kPenetratingList);
   HitTestResult result(request, LayoutPoint(hit_point));
-  document.GetLayoutViewItem().HitTest(result);
+  document.GetLayoutView()->HitTest(result);
 
   return ElementsFromHitTestResult(result);
 }
diff --git a/third_party/WebKit/Source/core/dom/ViewportDescription.h b/third_party/WebKit/Source/core/dom/ViewportDescription.h
index 42ab688..5632821 100644
--- a/third_party/WebKit/Source/core/dom/ViewportDescription.h
+++ b/third_party/WebKit/Source/core/dom/ViewportDescription.h
@@ -96,6 +96,10 @@
   PageScaleConstraints Resolve(const FloatSize& initial_viewport_size,
                                Length legacy_fallback_width) const;
 
+  // When --use-zoom-for-dsf is enabled, if the type is kFixed, these Length
+  // values (i.e., |min_width|, |max_width|, |min_height|, and |max_height|)
+  // must be in physical pixel scale. When --use-zoom-for-dsf is disabled, if
+  // the type is kFixed, these Length values must be in DIP scale.
   Length min_width;
   Length max_width;
   Length min_height;
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn
index 08391ce..46b988e 100644
--- a/third_party/WebKit/Source/core/editing/BUILD.gn
+++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -72,8 +72,6 @@
     "SelectionType.h",
     "SetSelectionOptions.cpp",
     "SetSelectionOptions.h",
-    "SurroundingText.cpp",
-    "SurroundingText.h",
     "TextAffinity.cpp",
     "TextAffinity.h",
     "TextGranularity.h",
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index 69526fa..ecd8c5f0 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -546,7 +546,7 @@
 }
 
 bool FrameSelection::Contains(const LayoutPoint& point) {
-  if (GetDocument().GetLayoutViewItem().IsNull())
+  if (!GetDocument().GetLayoutView())
     return false;
 
   // Treat a collapsed selection like no selection.
@@ -557,7 +557,7 @@
 
   HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive);
   HitTestResult result(request, point);
-  GetDocument().GetLayoutViewItem().HitTest(result);
+  GetDocument().GetLayoutView()->HitTest(result);
   Node* inner_node = result.InnerNode();
   if (!inner_node || !inner_node->GetLayoutObject())
     return false;
@@ -777,8 +777,8 @@
   // Because LayoutObject::selectionBackgroundColor() and
   // LayoutObject::selectionForegroundColor() check if the frame is active,
   // we have to update places those colors were painted.
-  LayoutViewItem view = GetDocument().GetLayoutViewItem();
-  if (!view.IsNull())
+  auto* view = GetDocument().GetLayoutView();
+  if (view)
     layout_selection_->InvalidatePaintForSelection();
 
   // Caret appears in the active frame.
@@ -847,7 +847,7 @@
 }
 
 void FrameSelection::UpdateAppearance() {
-  DCHECK(!frame_->ContentLayoutItem().IsNull());
+  DCHECK(frame_->ContentLayoutObject());
   frame_caret_->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
   layout_selection_->SetHasPendingSelection();
 }
@@ -939,9 +939,9 @@
 
 LayoutRect FrameSelection::UnclippedBounds() const {
   LocalFrameView* view = frame_->View();
-  LayoutViewItem layout_view = frame_->ContentLayoutItem();
+  LayoutView* layout_view = frame_->ContentLayoutObject();
 
-  if (!view || layout_view.IsNull())
+  if (!view || !layout_view)
     return LayoutRect();
 
   view->UpdateLifecycleToLayoutClean();
diff --git a/third_party/WebKit/Source/core/editing/SelectionController.cpp b/third_party/WebKit/Source/core/editing/SelectionController.cpp
index 96ec367..f407d77 100644
--- a/third_party/WebKit/Source/core/editing/SelectionController.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionController.cpp
@@ -1026,7 +1026,7 @@
   if (selection_state_ != SelectionState::kExtendedSelection) {
     HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive);
     HitTestResult result(request, mouse_down_pos);
-    frame_->GetDocument()->GetLayoutViewItem().HitTest(result);
+    frame_->GetDocument()->GetLayoutView()->HitTest(result);
 
     UpdateSelectionForMouseDrag(result, drag_start_pos,
                                 last_known_mouse_position);
@@ -1041,15 +1041,15 @@
   LocalFrameView* view = frame_->View();
   if (!view)
     return;
-  LayoutViewItem layout_item = frame_->ContentLayoutItem();
-  if (layout_item.IsNull())
+  LayoutView* layout_view = frame_->ContentLayoutObject();
+  if (!layout_view)
     return;
 
   HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive |
                          HitTestRequest::kMove);
   HitTestResult result(request,
                        view->RootFrameToContents(last_known_mouse_position));
-  layout_item.HitTest(result);
+  layout_view->HitTest(result);
   UpdateSelectionForMouseDrag(result, drag_start_pos,
                               last_known_mouse_position);
 }
diff --git a/third_party/WebKit/Source/core/editing/SurroundingText.cpp b/third_party/WebKit/Source/core/editing/SurroundingText.cpp
deleted file mode 100644
index aca4921..0000000
--- a/third_party/WebKit/Source/core/editing/SurroundingText.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 "core/editing/SurroundingText.h"
-
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-#include "core/dom/Range.h"
-#include "core/editing/EditingUtilities.h"
-#include "core/editing/EphemeralRange.h"
-#include "core/editing/Position.h"
-#include "core/editing/iterators/BackwardsCharacterIterator.h"
-#include "core/editing/iterators/CharacterIterator.h"
-#include "core/html/forms/HTMLFormControlElement.h"
-
-namespace blink {
-
-SurroundingText::SurroundingText(const EphemeralRange& range,
-                                 unsigned max_length)
-    : start_offset_in_content_(0), end_offset_in_content_(0) {
-  Initialize(range.StartPosition(), range.EndPosition(), max_length);
-}
-
-void SurroundingText::Initialize(const Position& start_position,
-                                 const Position& end_position,
-                                 unsigned max_length) {
-  DCHECK_EQ(start_position.GetDocument(), end_position.GetDocument());
-
-  const unsigned half_max_length = max_length / 2;
-
-  Document* document = start_position.GetDocument();
-  // The position will have no document if it is null (as in no position).
-  if (!document || !document->documentElement())
-    return;
-  DCHECK(!document->NeedsLayoutTreeUpdate());
-
-  // The forward range starts at the selection end and ends at the document's
-  // or the input element's end. It will then be updated to only contain the
-  // text in the right range around the selection.
-  DCHECK_EQ(RootEditableElementOf(start_position),
-            RootEditableElementOf(end_position));
-  Element* const root_editable = RootEditableElementOf(start_position);
-  Element* const root_element =
-      root_editable ? root_editable : document->documentElement();
-
-  // Do not create surrounding text if start or end position is within a
-  // control.
-  if (HTMLFormControlElement::EnclosingFormControlElement(
-          start_position.ComputeContainerNode()) ||
-      HTMLFormControlElement::EnclosingFormControlElement(
-          end_position.ComputeContainerNode()))
-    return;
-
-  CharacterIterator forward_iterator(
-      end_position,
-      Position::LastPositionInNode(*root_element).ParentAnchoredEquivalent(),
-      TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build());
-  if (!forward_iterator.AtEnd())
-    forward_iterator.Advance(max_length - half_max_length);
-
-  // Same as with the forward range but with the backward range. The range
-  // starts at the document's or input element's start and ends at the selection
-  // start and will be updated.
-  BackwardsCharacterIterator backwards_iterator(
-      EphemeralRange(Position::FirstPositionInNode(*root_element)
-                         .ParentAnchoredEquivalent(),
-                     start_position),
-      TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build());
-  if (!backwards_iterator.AtEnd())
-    backwards_iterator.Advance(half_max_length);
-
-  // Upon some conditions backwards iterator yields invalid EndPosition() which
-  // causes a crash in TextIterator::RangeLength().
-  // TODO(editing-dev): Fix BackwardsCharacterIterator, http://crbug.com/758438.
-  if (backwards_iterator.EndPosition() > start_position ||
-      end_position > forward_iterator.StartPosition())
-    return;
-
-  const TextIteratorBehavior behavior =
-      TextIteratorBehavior::NoTrailingSpaceRangeLengthBehavior();
-  const Position content_start = backwards_iterator.EndPosition();
-  const Position content_end = forward_iterator.StartPosition();
-  start_offset_in_content_ =
-      TextIterator::RangeLength(content_start, start_position, behavior);
-  end_offset_in_content_ =
-      TextIterator::RangeLength(content_start, end_position, behavior);
-  content_ = PlainText(
-      EphemeralRange(content_start, content_end),
-      TextIteratorBehavior::EmitsObjectReplacementCharacterBehavior());
-}
-
-String SurroundingText::Content() const {
-  return content_;
-}
-
-unsigned SurroundingText::StartOffsetInContent() const {
-  return start_offset_in_content_;
-}
-
-unsigned SurroundingText::EndOffsetInContent() const {
-  return end_offset_in_content_;
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/SurroundingText.h b/third_party/WebKit/Source/core/editing/SurroundingText.h
deleted file mode 100644
index 3cf06913..0000000
--- a/third_party/WebKit/Source/core/editing/SurroundingText.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2012 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 SurroundingText_h
-#define SurroundingText_h
-
-#include "base/macros.h"
-#include "core/CoreExport.h"
-#include "core/editing/Forward.h"
-#include "platform/wtf/text/WTFString.h"
-
-namespace blink {
-
-class CORE_EXPORT SurroundingText {
-  USING_FAST_MALLOC(SurroundingText);
-
- public:
-  // TODO(editing-dev): We should introduce |Create()| function and make
-  // constructor does nothing, since this constructor is too heavy.
-  SurroundingText(const EphemeralRange&, unsigned max_length);
-
-  String Content() const;
-  unsigned StartOffsetInContent() const;
-  unsigned EndOffsetInContent() const;
-
- private:
-  void Initialize(const Position&, const Position&, unsigned max_length);
-
-  String content_;
-  size_t start_offset_in_content_;
-  size_t end_offset_in_content_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurroundingText);
-};
-
-}  // namespace blink
-
-#endif  // SurroundingText_h
diff --git a/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp b/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp
index 53a2669..cfe1c534 100644
--- a/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp
+++ b/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/editing/SurroundingText.h"
+#include "public/web/WebSurroundingText.h"
+
+// TODO(xiaochengh): Rename this file as core/exported/WebSurroundingText.cpp
 
 #include <memory>
 #include "core/dom/Document.h"
@@ -18,7 +20,7 @@
 
 namespace blink {
 
-class SurroundingTextTest : public ::testing::Test {
+class WebSurroundingTextTest : public ::testing::Test {
  protected:
   Document& GetDocument() const { return dummy_page_holder_->GetDocument(); }
   void SetHTML(const String&);
@@ -31,249 +33,279 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder_;
 };
 
-void SurroundingTextTest::SetUp() {
+void WebSurroundingTextTest::SetUp() {
   dummy_page_holder_ = DummyPageHolder::Create(IntSize(800, 600));
 }
 
-void SurroundingTextTest::SetHTML(const String& content) {
+void WebSurroundingTextTest::SetHTML(const String& content) {
   GetDocument().body()->SetInnerHTMLFromString(content);
   GetDocument().UpdateStyleAndLayout();
 }
 
-EphemeralRange SurroundingTextTest::Select(int start, int end) {
+EphemeralRange WebSurroundingTextTest::Select(int start, int end) {
   Element* element = GetDocument().getElementById("selection");
   return EphemeralRange(Position(element->firstChild(), start),
                         Position(element->firstChild(), end));
 }
 
-TEST_F(SurroundingTextTest, BasicCaretSelection) {
+TEST_F(WebSurroundingTextTest, BasicCaretSelection) {
   SetHTML(String("<p id='selection'>foo bar</p>"));
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 1);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1);
 
-    EXPECT_EQ("f", surrounding_text.Content());
-    EXPECT_EQ(0u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(0u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("f", surrounding_text.TextContent());
+    EXPECT_EQ(0u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(0u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 5);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 5);
 
     // maxlength/2 is used on the left and right.
-    EXPECT_EQ("foo", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("foo",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 42);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 42);
 
-    EXPECT_EQ("foo bar", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("foo bar",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(7);
-    SurroundingText surrounding_text(selection, 42);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 42);
 
-    EXPECT_EQ("foo bar", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(8u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(8u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("foo bar",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(8u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(8u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(6);
-    SurroundingText surrounding_text(selection, 2);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 2);
 
-    EXPECT_EQ("ar", surrounding_text.Content());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("ar", surrounding_text.TextContent());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(6);
-    SurroundingText surrounding_text(selection, 42);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 42);
 
-    EXPECT_EQ("foo bar", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(7u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(7u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("foo bar",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(7u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(7u, surrounding_text.EndOffsetInTextContent());
   }
 }
 
-TEST_F(SurroundingTextTest, BasicRangeSelection) {
+TEST_F(WebSurroundingTextTest, BasicRangeSelection) {
   SetHTML(String("<p id='selection'>Lorem ipsum dolor sit amet</p>"));
 
   {
     EphemeralRange selection = Select(0, 5);
-    SurroundingText surrounding_text(selection, 1);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1);
 
-    EXPECT_EQ("Lorem ", surrounding_text.Content());
-    EXPECT_EQ(0u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(5u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("Lorem ", surrounding_text.TextContent());
+    EXPECT_EQ(0u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(5u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0, 5);
-    SurroundingText surrounding_text(selection, 5);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 5);
 
-    EXPECT_EQ("Lorem ip", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(6u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("Lorem ip",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(6u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0, 5);
-    SurroundingText surrounding_text(selection, 42);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 42);
 
     EXPECT_EQ("Lorem ipsum dolor sit amet",
-              surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(6u, surrounding_text.EndOffsetInContent());
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(6u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(6, 11);
-    SurroundingText surrounding_text(selection, 2);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 2);
 
-    EXPECT_EQ(" ipsum ", surrounding_text.Content());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(6u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ(" ipsum ", surrounding_text.TextContent());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(6u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(6, 11);
-    SurroundingText surrounding_text(selection, 42);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 42);
 
     EXPECT_EQ("Lorem ipsum dolor sit amet",
-              surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(7u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(12u, surrounding_text.EndOffsetInContent());
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(7u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(12u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     // Last word.
     EphemeralRange selection = Select(22, 26);
-    SurroundingText surrounding_text(selection, 8);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 8);
 
-    EXPECT_EQ("sit amet", surrounding_text.Content());
-    EXPECT_EQ(4u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(8u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("sit amet", surrounding_text.TextContent());
+    EXPECT_EQ(4u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(8u, surrounding_text.EndOffsetInTextContent());
   }
 }
 
-TEST_F(SurroundingTextTest, TreeCaretSelection) {
+TEST_F(WebSurroundingTextTest, TreeCaretSelection) {
   SetHTML(
       String("<div>This is outside of <p id='selection'>foo bar</p> the "
              "selected node</div>"));
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 1);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1);
 
-    EXPECT_EQ("f", surrounding_text.Content());
-    EXPECT_EQ(0u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(0u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("f", surrounding_text.TextContent());
+    EXPECT_EQ(0u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(0u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 5);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 5);
 
-    EXPECT_EQ("foo", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("foo",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 1337);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1337);
 
     EXPECT_EQ("This is outside of foo bar the selected node",
-              surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(20u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(20u, surrounding_text.EndOffsetInContent());
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(20u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(20u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(6);
-    SurroundingText surrounding_text(selection, 2);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 2);
 
-    EXPECT_EQ("ar", surrounding_text.Content());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("ar", surrounding_text.TextContent());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(6);
-    SurroundingText surrounding_text(selection, 1337);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1337);
 
     EXPECT_EQ("This is outside of foo bar the selected node",
-              surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(26u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(26u, surrounding_text.EndOffsetInContent());
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(26u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(26u, surrounding_text.EndOffsetInTextContent());
   }
 }
 
-TEST_F(SurroundingTextTest, TreeRangeSelection) {
+TEST_F(WebSurroundingTextTest, TreeRangeSelection) {
   SetHTML(
       String("<div>This is outside of <p id='selection'>foo bar</p> the "
              "selected node</div>"));
 
   {
     EphemeralRange selection = Select(0, 1);
-    SurroundingText surrounding_text(selection, 1);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1);
 
-    EXPECT_EQ("fo", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(0u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("fo",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(0u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0, 3);
-    SurroundingText surrounding_text(selection, 12);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 12);
 
-    EXPECT_EQ("e of foo bar", surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(5u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(8u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("e of foo bar",
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(5u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(8u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0, 3);
-    SurroundingText surrounding_text(selection, 1337);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1337);
 
     EXPECT_EQ("This is outside of foo bar the selected node",
-              surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(20u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(23u, surrounding_text.EndOffsetInContent());
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(20u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(23u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(4, 7);
-    SurroundingText surrounding_text(selection, 12);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 12);
 
     EXPECT_EQ("foo bar the se",
-              surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(5u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(8u, surrounding_text.EndOffsetInContent());
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(5u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(8u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0, 7);
-    SurroundingText surrounding_text(selection, 1337);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1337);
 
     EXPECT_EQ("This is outside of foo bar the selected node",
-              surrounding_text.Content().SimplifyWhiteSpace());
-    EXPECT_EQ(20u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(27u, surrounding_text.EndOffsetInContent());
+              String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+    EXPECT_EQ(20u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(27u, surrounding_text.EndOffsetInTextContent());
   }
 }
 
-TEST_F(SurroundingTextTest, TextAreaSelection) {
+TEST_F(WebSurroundingTextTest, TextAreaSelection) {
   SetHTML(
       String("<p>First paragraph</p>"
              "<textarea id='selection'>abc def ghi</textarea>"
@@ -285,14 +317,16 @@
   text_ctrl->SetSelectionRange(4, 7);
   EphemeralRange selection = text_ctrl->Selection().ComputeRange();
 
-  SurroundingText surrounding_text(selection, 20);
+  WebSurroundingText surrounding_text;
+  surrounding_text.InitializeFromRange(selection, 20);
 
-  EXPECT_EQ("abc def ghi", surrounding_text.Content().SimplifyWhiteSpace());
-  EXPECT_EQ(4u, surrounding_text.StartOffsetInContent());
-  EXPECT_EQ(7u, surrounding_text.EndOffsetInContent());
+  EXPECT_EQ("abc def ghi",
+            String(surrounding_text.TextContent()).SimplifyWhiteSpace());
+  EXPECT_EQ(4u, surrounding_text.StartOffsetInTextContent());
+  EXPECT_EQ(7u, surrounding_text.EndOffsetInTextContent());
 }
 
-TEST_F(SurroundingTextTest, EmptyInputElementWithChild) {
+TEST_F(WebSurroundingTextTest, EmptyInputElementWithChild) {
   SetHTML(String("<input type=\"text\" id=\"input_name\"/>"));
 
   TextControlElement* input_element =
@@ -311,11 +345,12 @@
   const Position end = Position(inner_editor, 0);
 
   // Surrounding text should not crash. See http://crbug.com/758438.
-  SurroundingText surrounding_text(EphemeralRange(start, end), 8);
-  EXPECT_TRUE(surrounding_text.Content().IsEmpty());
+  WebSurroundingText surrounding_text;
+  surrounding_text.InitializeFromRange(EphemeralRange(start, end), 8);
+  EXPECT_TRUE(surrounding_text.TextContent().IsEmpty());
 }
 
-TEST_F(SurroundingTextTest, ButtonsAndParagraph) {
+TEST_F(WebSurroundingTextTest, ButtonsAndParagraph) {
   SetHTML(
       String("<button>.</button>12345"
              "<p id='selection'>6789 12345</p>"
@@ -323,49 +358,54 @@
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 100);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 100);
 
-    EXPECT_EQ("12345\n6789 12345\n\n6789", surrounding_text.Content());
-    EXPECT_EQ(6u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(6u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("12345\n6789 12345\n\n6789", surrounding_text.TextContent());
+    EXPECT_EQ(6u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(6u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(5);
-    SurroundingText surrounding_text(selection, 6);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 6);
 
-    EXPECT_EQ("89 123", surrounding_text.Content());
-    EXPECT_EQ(3u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(3u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("89 123", surrounding_text.TextContent());
+    EXPECT_EQ(3u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(3u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(0);
-    SurroundingText surrounding_text(selection, 0);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 0);
 
-    EXPECT_TRUE(surrounding_text.Content().IsEmpty());
+    EXPECT_TRUE(surrounding_text.TextContent().IsEmpty());
   }
 
   {
     EphemeralRange selection = Select(5);
-    SurroundingText surrounding_text(selection, 1);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 1);
 
-    EXPECT_EQ("1", surrounding_text.Content());
-    EXPECT_EQ(0u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(0u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("1", surrounding_text.TextContent());
+    EXPECT_EQ(0u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(0u, surrounding_text.EndOffsetInTextContent());
   }
 
   {
     EphemeralRange selection = Select(6);
-    SurroundingText surrounding_text(selection, 2);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 2);
 
-    EXPECT_EQ("12", surrounding_text.Content());
-    EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-    EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+    EXPECT_EQ("12", surrounding_text.TextContent());
+    EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+    EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
   }
 }
 
-TEST_F(SurroundingTextTest, SelectElementAndText) {
+TEST_F(WebSurroundingTextTest, SelectElementAndText) {
   SetHTML(String(
       "<select>.</select>"
       "<div>57th Street and Lake Shore Drive</div>"
@@ -373,30 +413,32 @@
       "<select>.</select>"));
 
   EphemeralRange selection = Select(0);
-  SurroundingText surrounding_text(selection, 100);
+  WebSurroundingText surrounding_text;
+  surrounding_text.InitializeFromRange(selection, 100);
 
   EXPECT_STREQ(
       "\xEF\xBF\xBC\n57th Street and Lake Shore Drive\nChicago IL 60637",
-      surrounding_text.Content().Utf8().data());
-  EXPECT_EQ(43u, surrounding_text.StartOffsetInContent());
-  EXPECT_EQ(43u, surrounding_text.EndOffsetInContent());
+      surrounding_text.TextContent().Utf8().data());
+  EXPECT_EQ(43u, surrounding_text.StartOffsetInTextContent());
+  EXPECT_EQ(43u, surrounding_text.EndOffsetInTextContent());
 }
 
-TEST_F(SurroundingTextTest, FieldsetElementAndText) {
+TEST_F(WebSurroundingTextTest, FieldsetElementAndText) {
   SetHTML(
       String("<fieldset>.</fieldset>12345<button>abc</button>"
              "<p>6789<br><span id='selection'>12345</span></p>"
              "6789<textarea>abc</textarea>0123<fieldset>.</fieldset>"));
 
   EphemeralRange selection = Select(0);
-  SurroundingText surrounding_text(selection, 100);
+  WebSurroundingText surrounding_text;
+  surrounding_text.InitializeFromRange(selection, 100);
 
-  EXPECT_EQ("\n6789\n12345\n\n6789", surrounding_text.Content());
-  EXPECT_EQ(6u, surrounding_text.StartOffsetInContent());
-  EXPECT_EQ(6u, surrounding_text.EndOffsetInContent());
+  EXPECT_EQ("\n6789\n12345\n\n6789", surrounding_text.TextContent());
+  EXPECT_EQ(6u, surrounding_text.StartOffsetInTextContent());
+  EXPECT_EQ(6u, surrounding_text.EndOffsetInTextContent());
 }
 
-TEST_F(SurroundingTextTest, ButtonScriptAndComment) {
+TEST_F(WebSurroundingTextTest, ButtonScriptAndComment) {
   SetHTML(
       String("<button>.</button>"
              "<div id='selection'>This is <!-- comment --!>a test "
@@ -404,28 +446,30 @@
              "example<button>.</button>"));
 
   EphemeralRange selection = Select(0);
-  SurroundingText surrounding_text(selection, 100);
+  WebSurroundingText surrounding_text;
+  surrounding_text.InitializeFromRange(selection, 100);
 
-  EXPECT_EQ("\nThis is a test example", surrounding_text.Content());
-  EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-  EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+  EXPECT_EQ("\nThis is a test example", surrounding_text.TextContent());
+  EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+  EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
 }
 
-TEST_F(SurroundingTextTest, ButtonAndLongDiv) {
+TEST_F(WebSurroundingTextTest, ButtonAndLongDiv) {
   SetHTML(
       String("<button>.</button>"
              "<div id='selection'>012345678901234567890123456789</div>"
              "<button>.</button>"));
 
   EphemeralRange selection = Select(15);
-  SurroundingText surrounding_text(selection, 12);
+  WebSurroundingText surrounding_text;
+  surrounding_text.InitializeFromRange(selection, 12);
 
-  EXPECT_EQ("901234567890", surrounding_text.Content());
-  EXPECT_EQ(6u, surrounding_text.StartOffsetInContent());
-  EXPECT_EQ(6u, surrounding_text.EndOffsetInContent());
+  EXPECT_EQ("901234567890", surrounding_text.TextContent());
+  EXPECT_EQ(6u, surrounding_text.StartOffsetInTextContent());
+  EXPECT_EQ(6u, surrounding_text.EndOffsetInTextContent());
 }
 
-TEST_F(SurroundingTextTest, EmptySurroundingTextInOptionsAndButton) {
+TEST_F(WebSurroundingTextTest, EmptyWebSurroundingTextInOptionsAndButton) {
   SetHTML(
       String("<option>.</option>12345"
              "<button id='selection'>test</button>"
@@ -433,28 +477,31 @@
 
   {
     EphemeralRange selection = Select(1);
-    SurroundingText surrounding_text(selection, 100);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 100);
 
-    EXPECT_TRUE(surrounding_text.Content().IsEmpty());
+    EXPECT_TRUE(surrounding_text.TextContent().IsEmpty());
   }
 
   {
     EphemeralRange selection = Select(3);
-    SurroundingText surrounding_text(selection, 100);
+    WebSurroundingText surrounding_text;
+    surrounding_text.InitializeFromRange(selection, 100);
 
-    EXPECT_TRUE(surrounding_text.Content().IsEmpty());
+    EXPECT_TRUE(surrounding_text.TextContent().IsEmpty());
   }
 }
 
-TEST_F(SurroundingTextTest, SingleDotParagraph) {
+TEST_F(WebSurroundingTextTest, SingleDotParagraph) {
   SetHTML(String("<p id='selection'>.</p>"));
 
   EphemeralRange selection = Select(0);
-  SurroundingText surrounding_text(selection, 2);
+  WebSurroundingText surrounding_text;
+  surrounding_text.InitializeFromRange(selection, 2);
 
-  EXPECT_EQ("\n.", surrounding_text.Content());
-  EXPECT_EQ(1u, surrounding_text.StartOffsetInContent());
-  EXPECT_EQ(1u, surrounding_text.EndOffsetInContent());
+  EXPECT_EQ("\n.", surrounding_text.TextContent());
+  EXPECT_EQ(1u, surrounding_text.StartOffsetInTextContent());
+  EXPECT_EQ(1u, surrounding_text.EndOffsetInTextContent());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index 32a8e69..6a95cd7 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -830,7 +830,7 @@
                            HitTestRequest::kActive |
                            HitTestRequest::kIgnoreClipping;
   HitTestResult result(request, contents_point);
-  frame->GetDocument()->GetLayoutViewItem().HitTest(result);
+  frame->GetDocument()->GetLayoutView()->HitTest(result);
 
   if (Node* node = result.InnerNode()) {
     return CreateVisiblePosition(PositionRespectingEditingBoundary(
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
index 6a4e2658..d453cd7 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
@@ -482,6 +482,8 @@
     // will be moved.
     start = StartOfParagraph(original_start, kCanSkipOverEditingBoundary);
     end = EndOfParagraph(start, kCanSkipOverEditingBoundary);
+    // InsertListCommandTest.UnlistifyParagraphCrashOnRemoveStyle reaches here.
+    ABORT_EDITING_COMMAND_IF(start.DeepEquivalent() == end.DeepEquivalent());
     next_list_child = EnclosingListChild(
         NextPositionOf(end).DeepEquivalent().AnchorNode(), list_element);
     DCHECK_NE(next_list_child, list_child_node);
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertListCommandTest.cpp b/third_party/WebKit/Source/core/editing/commands/InsertListCommandTest.cpp
index 80450fc..e8a5740 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertListCommandTest.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertListCommandTest.cpp
@@ -48,4 +48,22 @@
       << "The insert ordered list command should have succeeded";
   EXPECT_EQ("<ol><li>d</li></ol>", GetDocument().body()->InnerHTMLAsString());
 }
+
+// Refer https://crbug.com/794356
+TEST_F(InsertListCommandTest, UnlistifyParagraphCrashOnVisuallyEmptyParagraph) {
+  GetDocument().setDesignMode("on");
+  Selection().SetSelection(
+      SetSelectionTextToBody("^<dl>"
+                             "<textarea style='float:left;'></textarea>"
+                             "</dl>|"));
+  InsertListCommand* command = InsertListCommand::Create(
+      GetDocument(), InsertListCommand::kUnorderedList);
+  // Crash happens here.
+  EXPECT_FALSE(command->Apply());
+  EXPECT_EQ(
+      "<dl><ul>"
+      "|<textarea style=\"float:left;\"></textarea>"
+      "</ul></dl>",
+      GetSelectionTextFromBody(Selection().GetSelectionInDOMTree()));
+}
 }
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp
index 1ec7ebe..7b685e9e 100644
--- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommandTest.cpp
@@ -111,12 +111,12 @@
 // Helper function to set autosizing multipliers on a document.
 bool SetTextAutosizingMultiplier(Document* document, float multiplier) {
   bool multiplier_set = false;
-  for (LayoutItem layout_item = document->GetLayoutViewItem();
-       !layout_item.IsNull(); layout_item = layout_item.NextInPreOrder()) {
-    if (layout_item.Style()) {
-      layout_item.MutableStyleRef().SetTextAutosizingMultiplier(multiplier);
+  for (LayoutObject* layout_object = document->GetLayoutView(); layout_object;
+       layout_object = layout_object->NextInPreOrder()) {
+    if (layout_object->Style()) {
+      layout_object->MutableStyleRef().SetTextAutosizingMultiplier(multiplier);
 
-      EXPECT_EQ(multiplier, layout_item.Style()->TextAutosizingMultiplier());
+      EXPECT_EQ(multiplier, layout_object->Style()->TextAutosizingMultiplier());
       multiplier_set = true;
     }
   }
diff --git a/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp
index d720db6..7c62be5 100644
--- a/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebDevToolsAgentImpl.cpp
@@ -525,7 +525,7 @@
   HitTestResult result(
       request, web_local_frame_impl_->GetFrameView()->RootFrameToContents(
                    transformed_point));
-  web_local_frame_impl_->GetFrame()->ContentLayoutItem().HitTest(result);
+  web_local_frame_impl_->GetFrame()->ContentLayoutObject()->HitTest(result);
   Node* node = result.InnerNode();
   if (!node && web_local_frame_impl_->GetFrame()->GetDocument())
     node = web_local_frame_impl_->GetFrame()->GetDocument()->documentElement();
diff --git a/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp b/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp
index 6457b13..17825f9e 100644
--- a/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp
+++ b/third_party/WebKit/Source/core/exported/WebFrameContentDumper.cpp
@@ -186,19 +186,14 @@
       continue;
     LocalFrame* cur_local_child = ToLocalFrame(cur_child);
     // Ignore the text of non-visible frames.
-    LayoutViewItem content_layout_item = cur_local_child->ContentLayoutItem();
-    LayoutEmbeddedContentItem owner_layout_item =
-        cur_local_child->OwnerLayoutItem();
-    if (content_layout_item.IsNull() || !content_layout_item.Size().Width() ||
-        !content_layout_item.Size().Height() ||
-        (content_layout_item.Location().X() +
-             content_layout_item.Size().Width() <=
-         0) ||
-        (content_layout_item.Location().Y() +
-             content_layout_item.Size().Height() <=
-         0) ||
-        (!owner_layout_item.IsNull() && owner_layout_item.Style() &&
-         owner_layout_item.Style()->Visibility() != EVisibility::kVisible)) {
+    LayoutView* layout_view = cur_local_child->ContentLayoutObject();
+    LayoutObject* owner_layout_object = cur_local_child->OwnerLayoutObject();
+    if (!layout_view || !layout_view->Size().Width() ||
+        !layout_view->Size().Height() ||
+        (layout_view->Location().X() + layout_view->Size().Width() <= 0) ||
+        (layout_view->Location().Y() + layout_view->Size().Height() <= 0) ||
+        (owner_layout_object && owner_layout_object->Style() &&
+         owner_layout_object->Style()->Visibility() != EVisibility::kVisible)) {
       continue;
     }
 
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
index c36ed9b..924bb76 100644
--- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -1114,12 +1114,12 @@
 // Helper function to set autosizing multipliers on a document.
 bool SetTextAutosizingMultiplier(Document* document, float multiplier) {
   bool multiplier_set = false;
-  for (LayoutItem layout_item = document->GetLayoutViewItem();
-       !layout_item.IsNull(); layout_item = layout_item.NextInPreOrder()) {
-    if (layout_item.Style()) {
-      layout_item.MutableStyleRef().SetTextAutosizingMultiplier(multiplier);
+  for (LayoutObject* layout_object = document->GetLayoutView(); layout_object;
+       layout_object = layout_object->NextInPreOrder()) {
+    if (layout_object->Style()) {
+      layout_object->MutableStyleRef().SetTextAutosizingMultiplier(multiplier);
 
-      EXPECT_EQ(multiplier, layout_item.Style()->TextAutosizingMultiplier());
+      EXPECT_EQ(multiplier, layout_object->Style()->TextAutosizingMultiplier());
       multiplier_set = true;
     }
   }
@@ -1129,10 +1129,10 @@
 // Helper function to check autosizing multipliers on a document.
 bool CheckTextAutosizingMultiplier(Document* document, float multiplier) {
   bool multiplier_checked = false;
-  for (LayoutItem layout_item = document->GetLayoutViewItem();
-       !layout_item.IsNull(); layout_item = layout_item.NextInPreOrder()) {
-    if (layout_item.Style() && layout_item.IsText()) {
-      EXPECT_EQ(multiplier, layout_item.Style()->TextAutosizingMultiplier());
+  for (LayoutObject* layout_object = document->GetLayoutView(); layout_object;
+       layout_object = layout_object->NextInPreOrder()) {
+    if (layout_object->Style() && layout_object->IsText()) {
+      EXPECT_EQ(multiplier, layout_object->Style()->TextAutosizingMultiplier());
       multiplier_checked = true;
     }
   }
@@ -1222,11 +1222,11 @@
       continue;
     EXPECT_TRUE(
         SetTextAutosizingMultiplier(ToLocalFrame(frame)->GetDocument(), 2));
-    for (LayoutItem layout_item =
-             ToLocalFrame(frame)->GetDocument()->GetLayoutViewItem();
-         !layout_item.IsNull(); layout_item = layout_item.NextInPreOrder()) {
-      if (layout_item.IsText())
-        EXPECT_FALSE(layout_item.NeedsLayout());
+    for (LayoutObject* layout_object =
+             ToLocalFrame(frame)->GetDocument()->GetLayoutView();
+         layout_object; layout_object = layout_object->NextInPreOrder()) {
+      if (layout_object->IsText())
+        EXPECT_FALSE(layout_object->NeedsLayout());
     }
   }
 
@@ -1235,11 +1235,11 @@
   for (Frame* frame = main_frame; frame; frame = frame->Tree().TraverseNext()) {
     if (!frame->IsLocalFrame())
       continue;
-    for (LayoutItem layout_item =
-             ToLocalFrame(frame)->GetDocument()->GetLayoutViewItem();
-         !layout_item.IsNull(); layout_item = layout_item.NextInPreOrder()) {
-      if (layout_item.IsText())
-        EXPECT_TRUE(layout_item.NeedsLayout());
+    for (LayoutObject* layout_object =
+             ToLocalFrame(frame)->GetDocument()->GetLayoutView();
+         !layout_object; layout_object = layout_object->NextInPreOrder()) {
+      if (layout_object->IsText())
+        EXPECT_TRUE(layout_object->NeedsLayout());
     }
   }
 }
@@ -2600,8 +2600,8 @@
 
   EXPECT_EQ(980,
             ToLocalFrame(web_view_helper.GetWebView()->GetPage()->MainFrame())
-                ->ContentLayoutItem()
-                .DocumentRect()
+                ->ContentLayoutObject()
+                ->DocumentRect()
                 .Width());
   EXPECT_EQ(980, web_view_helper.GetWebView()
                      ->MainFrameImpl()
@@ -8439,12 +8439,12 @@
   web_view_helper.Resize(WebSize(viewport_width, viewport_height));
   web_view_impl->UpdateAllLifecyclePhases();
 
-  LayoutViewItem layout_view_item = web_view_helper.GetWebView()
-                                        ->MainFrameImpl()
-                                        ->GetFrameView()
-                                        ->GetLayoutViewItem();
-  EXPECT_EQ(320, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(533, layout_view_item.LogicalHeight().Floor());
+  auto* layout_view = web_view_helper.GetWebView()
+                          ->MainFrameImpl()
+                          ->GetFrameView()
+                          ->GetLayoutView();
+  EXPECT_EQ(320, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(533, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.2, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.2, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(5.0, web_view_impl->MaximumPageScaleFactor());
@@ -8455,16 +8455,16 @@
   Fullscreen::RequestFullscreen(*frame->GetDocument()->documentElement());
   web_view_impl->DidEnterFullscreen();
   web_view_impl->UpdateAllLifecyclePhases();
-  EXPECT_EQ(384, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(640, layout_view_item.LogicalHeight().Floor());
+  EXPECT_EQ(384, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(640, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor());
 
   web_view_impl->DidExitFullscreen();
   web_view_impl->UpdateAllLifecyclePhases();
-  EXPECT_EQ(320, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(533, layout_view_item.LogicalHeight().Floor());
+  EXPECT_EQ(320, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(533, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.2, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.2, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(5.0, web_view_impl->MaximumPageScaleFactor());
@@ -8484,18 +8484,18 @@
   web_view_helper.Resize(WebSize(viewport_width, viewport_height));
   web_view_impl->UpdateAllLifecyclePhases();
 
-  LayoutViewItem layout_view_item = web_view_helper.GetWebView()
-                                        ->MainFrameImpl()
-                                        ->GetFrameView()
-                                        ->GetLayoutViewItem();
+  auto* layout_view = web_view_helper.GetWebView()
+                          ->MainFrameImpl()
+                          ->GetFrameView()
+                          ->GetLayoutView();
   LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame();
   std::unique_ptr<UserGestureIndicator> gesture =
       Frame::NotifyUserActivation(frame);
   Fullscreen::RequestFullscreen(*frame->GetDocument()->documentElement());
   web_view_impl->DidEnterFullscreen();
   web_view_impl->UpdateAllLifecyclePhases();
-  EXPECT_EQ(384, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(640, layout_view_item.LogicalHeight().Floor());
+  EXPECT_EQ(384, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(640, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor());
@@ -8506,16 +8506,16 @@
   client.screen_info_.rect.height = viewport_height;
   web_view_helper.Resize(WebSize(viewport_width, viewport_height));
   web_view_impl->UpdateAllLifecyclePhases();
-  EXPECT_EQ(640, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(384, layout_view_item.LogicalHeight().Floor());
+  EXPECT_EQ(640, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(384, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor());
 
   web_view_impl->DidExitFullscreen();
   web_view_impl->UpdateAllLifecyclePhases();
-  EXPECT_EQ(320, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(192, layout_view_item.LogicalHeight().Floor());
+  EXPECT_EQ(320, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(192, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(2, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(2, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(5.0, web_view_impl->MaximumPageScaleFactor());
@@ -8541,14 +8541,14 @@
   client.screen_info_.rect.height =
       screen_size_minus_status_bars_minus_url_bar.height;
   web_view_helper.Resize(screen_size_minus_status_bars_minus_url_bar);
-  LayoutViewItem layout_view_item = web_view_helper.GetWebView()
-                                        ->MainFrameImpl()
-                                        ->GetFrameView()
-                                        ->GetLayoutViewItem();
+  auto* layout_view = web_view_helper.GetWebView()
+                          ->MainFrameImpl()
+                          ->GetFrameView()
+                          ->GetLayoutView();
   EXPECT_EQ(screen_size_minus_status_bars_minus_url_bar.width,
-            layout_view_item.LogicalWidth().Floor());
+            layout_view->LogicalWidth().Floor());
   EXPECT_EQ(screen_size_minus_status_bars_minus_url_bar.height,
-            layout_view_item.LogicalHeight().Floor());
+            layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(5.0, web_view_impl->MaximumPageScaleFactor());
@@ -8568,8 +8568,8 @@
   client.screen_info_.rect.width = screen_size.width;
   client.screen_info_.rect.height = screen_size.height;
   web_view_helper.Resize(screen_size);
-  EXPECT_EQ(screen_size.width, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(screen_size.height, layout_view_item.LogicalHeight().Floor());
+  EXPECT_EQ(screen_size.width, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(screen_size.height, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor());
@@ -8585,9 +8585,9 @@
       screen_size_minus_status_bars_minus_url_bar.height;
   web_view_helper.Resize(screen_size_minus_status_bars_minus_url_bar);
   EXPECT_EQ(screen_size_minus_status_bars_minus_url_bar.width,
-            layout_view_item.LogicalWidth().Floor());
+            layout_view->LogicalWidth().Floor());
   EXPECT_EQ(screen_size_minus_status_bars_minus_url_bar.height,
-            layout_view_item.LogicalHeight().Floor());
+            layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(5.0, web_view_impl->MaximumPageScaleFactor());
@@ -8609,10 +8609,10 @@
   web_view_impl->UpdateAllLifecyclePhases();
 
   // viewport-tiny.html specifies a 320px layout width.
-  LayoutViewItem layout_view_item =
-      web_view_impl->MainFrameImpl()->GetFrameView()->GetLayoutViewItem();
-  EXPECT_EQ(320, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(640, layout_view_item.LogicalHeight().Floor());
+  auto* layout_view =
+      web_view_impl->MainFrameImpl()->GetFrameView()->GetLayoutView();
+  EXPECT_EQ(320, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(640, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(0.3125, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(0.3125, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(5.0, web_view_impl->MaximumPageScaleFactor());
@@ -8626,8 +8626,8 @@
 
   // Entering fullscreen causes layout size and page scale limits to be
   // overridden.
-  EXPECT_EQ(100, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(200, layout_view_item.LogicalHeight().Floor());
+  EXPECT_EQ(100, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(200, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor());
@@ -8643,10 +8643,9 @@
 
   // Make sure the new page's layout size and scale factor limits aren't
   // overridden.
-  layout_view_item =
-      web_view_impl->MainFrameImpl()->GetFrameView()->GetLayoutViewItem();
-  EXPECT_EQ(200, layout_view_item.LogicalWidth().Floor());
-  EXPECT_EQ(400, layout_view_item.LogicalHeight().Floor());
+  layout_view = web_view_impl->MainFrameImpl()->GetFrameView()->GetLayoutView();
+  EXPECT_EQ(200, layout_view->LogicalWidth().Floor());
+  EXPECT_EQ(400, layout_view->LogicalHeight().Floor());
   EXPECT_FLOAT_EQ(0.5, web_view_impl->MinimumPageScaleFactor());
   EXPECT_FLOAT_EQ(5.0, web_view_impl->MaximumPageScaleFactor());
 }
@@ -11278,8 +11277,7 @@
 
   Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument();
   LocalFrameView* frame_view = web_view->MainFrameImpl()->GetFrameView();
-  PaintLayerCompositor* compositor =
-      frame_view->GetLayoutViewItem().Compositor();
+  PaintLayerCompositor* compositor = frame_view->GetLayoutView()->Compositor();
 
   EXPECT_EQ(kViewportHeight - kBrowserControlsHeight,
             compositor->RootLayer()->BoundingBoxForCompositing().Height());
diff --git a/third_party/WebKit/Source/core/exported/WebPagePopupImpl.cpp b/third_party/WebKit/Source/core/exported/WebPagePopupImpl.cpp
index 7c44847..bd22ce2 100644
--- a/third_party/WebKit/Source/core/exported/WebPagePopupImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebPagePopupImpl.cpp
@@ -352,8 +352,7 @@
     return nullptr;
   AXObjectCache* cache = document->GetOrCreateAXObjectCache();
   DCHECK(cache);
-  return ToAXObjectCacheBase(cache)->GetOrCreate(ToLayoutView(
-      LayoutAPIShim::LayoutObjectFrom(document->GetLayoutViewItem())));
+  return ToAXObjectCacheBase(cache)->GetOrCreate(document->GetLayoutView());
 }
 
 void WebPagePopupImpl::SetWindowRect(const IntRect& rect_in_screen) {
diff --git a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp
index 01779965..400da7c 100644
--- a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp
@@ -1043,9 +1043,9 @@
   LayoutRect layout_window_rect =
       LayoutRect(element_->GetDocument()
                      .View()
-                     ->GetLayoutViewItem()
-                     .LocalToAbsoluteQuad(FloatQuad(FloatRect(frame_rect_)),
-                                          kTraverseDocumentBoundaries)
+                     ->GetLayoutView()
+                     ->LocalToAbsoluteQuad(FloatQuad(FloatRect(frame_rect_)),
+                                           kTraverseDocumentBoundaries)
                      .BoundingBox());
   // Finally, adjust for scrolling of the root frame, which the above does not
   // take into account.
@@ -1079,10 +1079,7 @@
   // document().layoutView() can be null when we receive messages from the
   // plugins while we are destroying a frame.
   // FIXME: Can we just check m_element->document().isActive() ?
-  if (!element_->GetLayoutObject()
-           ->GetDocument()
-           .GetLayoutViewItem()
-           .IsNull()) {
+  if (element_->GetLayoutObject()->GetDocument().GetLayoutView()) {
     // Take our element and get the clip rect from the enclosing layer and
     // frame view.
     ComputeClipRectsForPlugin(element_, window_rect, clip_rect,
diff --git a/third_party/WebKit/Source/core/exported/WebSurroundingText.cpp b/third_party/WebKit/Source/core/exported/WebSurroundingText.cpp
index 6e02ae2..62b516e1 100644
--- a/third_party/WebKit/Source/core/exported/WebSurroundingText.cpp
+++ b/third_party/WebKit/Source/core/exported/WebSurroundingText.cpp
@@ -26,24 +26,20 @@
 #include "public/web/WebSurroundingText.h"
 
 #include "core/dom/Element.h"
-#include "core/dom/Node.h"
-#include "core/dom/Range.h"
-#include "core/dom/Text.h"
+#include "core/editing/EditingUtilities.h"
 #include "core/editing/EphemeralRange.h"
 #include "core/editing/FrameSelection.h"
-#include "core/editing/SurroundingText.h"
 #include "core/editing/VisibleSelection.h"
+#include "core/editing/iterators/BackwardsCharacterIterator.h"
+#include "core/editing/iterators/CharacterIterator.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/WebLocalFrameImpl.h"
-#include "core/layout/LayoutObject.h"
-#include "public/platform/WebPoint.h"
-#include "public/web/WebHitTestResult.h"
+#include "core/html/forms/HTMLFormControlElement.h"
 
 namespace blink {
 
-WebSurroundingText::WebSurroundingText() {}
-
-WebSurroundingText::~WebSurroundingText() {}
+WebSurroundingText::WebSurroundingText()
+    : start_offset_in_text_content_(0), end_offset_in_text_content_(0) {}
 
 void WebSurroundingText::InitializeFromCurrentSelection(WebLocalFrame* frame,
                                                         size_t max_length) {
@@ -58,30 +54,91 @@
                                    .ToNormalizedEphemeralRange();
   if (range.IsNull())
     return;
-  // TODO(xiaochengh): The followinng SurroundingText can hold a null Range,
-  // in which case we should prevent it from being stored in |m_private|.
-  private_.reset(new SurroundingText(range, max_length));
+  InitializeFromRange(range, max_length);
+}
+
+void WebSurroundingText::InitializeFromRange(const EphemeralRange& range,
+                                             size_t max_length) {
+  const Position start_position = range.StartPosition();
+  const Position end_position = range.EndPosition();
+  const unsigned half_max_length = max_length / 2;
+
+  Document* document = start_position.GetDocument();
+
+  // The position will have no document if it is null (as in no position).
+  if (!document || !document->documentElement())
+    return;
+  DCHECK(!document->NeedsLayoutTreeUpdate());
+
+  // The forward range starts at the selection end and ends at the document's
+  // or the input element's end. It will then be updated to only contain the
+  // text in the right range around the selection.
+  DCHECK_EQ(RootEditableElementOf(start_position),
+            RootEditableElementOf(end_position));
+  Element* const root_editable = RootEditableElementOf(start_position);
+  Element* const root_element =
+      root_editable ? root_editable : document->documentElement();
+
+  // Do not create surrounding text if start or end position is within a
+  // control.
+  if (HTMLFormControlElement::EnclosingFormControlElement(
+          start_position.ComputeContainerNode()) ||
+      HTMLFormControlElement::EnclosingFormControlElement(
+          end_position.ComputeContainerNode()))
+    return;
+
+  CharacterIterator forward_iterator(
+      end_position,
+      Position::LastPositionInNode(*root_element).ParentAnchoredEquivalent(),
+      TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build());
+  if (!forward_iterator.AtEnd())
+    forward_iterator.Advance(max_length - half_max_length);
+
+  // Same as with the forward range but with the backward range. The range
+  // starts at the document's or input element's start and ends at the selection
+  // start and will be updated.
+  BackwardsCharacterIterator backwards_iterator(
+      EphemeralRange(Position::FirstPositionInNode(*root_element)
+                         .ParentAnchoredEquivalent(),
+                     start_position),
+      TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build());
+  if (!backwards_iterator.AtEnd())
+    backwards_iterator.Advance(half_max_length);
+
+  // Upon some conditions backwards iterator yields invalid EndPosition() which
+  // causes a crash in TextIterator::RangeLength().
+  // TODO(editing-dev): Fix BackwardsCharacterIterator, http://crbug.com/758438.
+  if (backwards_iterator.EndPosition() > start_position ||
+      end_position > forward_iterator.StartPosition())
+    return;
+
+  const TextIteratorBehavior behavior =
+      TextIteratorBehavior::NoTrailingSpaceRangeLengthBehavior();
+  const Position content_start = backwards_iterator.EndPosition();
+  const Position content_end = forward_iterator.StartPosition();
+  start_offset_in_text_content_ =
+      TextIterator::RangeLength(content_start, start_position, behavior);
+  end_offset_in_text_content_ =
+      TextIterator::RangeLength(content_start, end_position, behavior);
+  text_content_ = PlainText(
+      EphemeralRange(content_start, content_end),
+      TextIteratorBehavior::EmitsObjectReplacementCharacterBehavior());
 }
 
 WebString WebSurroundingText::TextContent() const {
-  return private_->Content();
-}
-
-size_t WebSurroundingText::HitOffsetInTextContent() const {
-  DCHECK_EQ(private_->StartOffsetInContent(), private_->EndOffsetInContent());
-  return private_->StartOffsetInContent();
+  return text_content_;
 }
 
 size_t WebSurroundingText::StartOffsetInTextContent() const {
-  return private_->StartOffsetInContent();
+  return start_offset_in_text_content_;
 }
 
 size_t WebSurroundingText::EndOffsetInTextContent() const {
-  return private_->EndOffsetInContent();
+  return end_offset_in_text_content_;
 }
 
 bool WebSurroundingText::IsNull() const {
-  return !private_.get();
+  return text_content_.IsEmpty();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/exported/WebViewImpl.cpp b/third_party/WebKit/Source/core/exported/WebViewImpl.cpp
index 6c146e7..1c5a4de9 100644
--- a/third_party/WebKit/Source/core/exported/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebViewImpl.cpp
@@ -2971,11 +2971,11 @@
 IntSize WebViewImpl::ContentsSize() const {
   if (!GetPage()->MainFrame()->IsLocalFrame())
     return IntSize();
-  LayoutViewItem root =
-      GetPage()->DeprecatedLocalMainFrame()->ContentLayoutItem();
-  if (root.IsNull())
+  auto* layout_view =
+      GetPage()->DeprecatedLocalMainFrame()->ContentLayoutObject();
+  if (!layout_view)
     return IntSize();
-  return root.DocumentRect().Size();
+  return layout_view->DocumentRect().Size();
 }
 
 WebSize WebViewImpl::ContentsPreferredMinimumSize() {
@@ -2989,15 +2989,14 @@
   Document* document = page_->MainFrame()->IsLocalFrame()
                            ? page_->DeprecatedLocalMainFrame()->GetDocument()
                            : nullptr;
-  if (!document || document->GetLayoutViewItem().IsNull() ||
-      !document->documentElement() ||
+  if (!document || !document->GetLayoutView() || !document->documentElement() ||
       !document->documentElement()->GetLayoutBox())
     return WebSize();
 
   // Needed for computing MinPreferredWidth.
   FontCachePurgePreventer fontCachePurgePreventer;
-  int width_scaled = document->GetLayoutViewItem()
-                         .MinPreferredLogicalWidth()
+  int width_scaled = document->GetLayoutView()
+                         ->MinPreferredLogicalWidth()
                          .Round();  // Already accounts for zoom.
   int height_scaled =
       document->documentElement()->GetLayoutBox()->ScrollHeight().Round();
@@ -3642,10 +3641,10 @@
     return nullptr;
 
   Document* document = frame->GetFrame()->GetDocument();
-  if (!document || document->GetLayoutViewItem().IsNull())
+  if (!document || !document->GetLayoutView())
     return nullptr;
 
-  return document->GetLayoutViewItem().Compositor();
+  return document->GetLayoutView()->Compositor();
 }
 
 GraphicsLayer* WebViewImpl::RootGraphicsLayer() {
diff --git a/third_party/WebKit/Source/core/exported/WebViewTest.cpp b/third_party/WebKit/Source/core/exported/WebViewTest.cpp
index 0f984b0..4ca843c 100644
--- a/third_party/WebKit/Source/core/exported/WebViewTest.cpp
+++ b/third_party/WebKit/Source/core/exported/WebViewTest.cpp
@@ -506,7 +506,7 @@
   // Paint the root of the main frame in the way that CompositedLayerMapping
   // would.
   LocalFrameView* view = web_view_helper_.LocalMainFrame()->GetFrameView();
-  PaintLayer* root_layer = view->GetLayoutViewItem().Layer();
+  PaintLayer* root_layer = view->GetLayoutView()->Layer();
   LayoutRect paint_rect(0, 0, kWidth, kHeight);
   PaintLayerPaintingInfo painting_info(root_layer, paint_rect,
                                        kGlobalPaintNormalPhase, LayoutSize());
diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp
index 71ebc58a..23557dda 100644
--- a/third_party/WebKit/Source/core/frame/Frame.cpp
+++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -159,10 +159,6 @@
   return DeprecatedLocalOwner()->GetLayoutEmbeddedContent();
 }
 
-LayoutEmbeddedContentItem Frame::OwnerLayoutItem() const {
-  return LayoutEmbeddedContentItem(OwnerLayoutObject());
-}
-
 Settings* Frame::GetSettings() const {
   if (GetPage())
     return &GetPage()->GetSettings();
diff --git a/third_party/WebKit/Source/core/frame/Frame.h b/third_party/WebKit/Source/core/frame/Frame.h
index 4bc6821b..5e542a4 100644
--- a/third_party/WebKit/Source/core/frame/Frame.h
+++ b/third_party/WebKit/Source/core/frame/Frame.h
@@ -51,7 +51,6 @@
 class FrameOwner;
 class HTMLFrameOwnerElement;
 class LayoutEmbeddedContent;
-class LayoutEmbeddedContentItem;
 class LocalFrame;
 class KURL;
 class Page;
@@ -123,11 +122,8 @@
   // otherwise.
   virtual bool PrepareForCommit() = 0;
 
-  // TODO(pilgrim): Replace all instances of ownerLayoutObject() with
-  // ownerLayoutItem(), https://crbug.com/499321
-  LayoutEmbeddedContent* OwnerLayoutObject()
-      const;  // LayoutObject for the element that contains this frame.
-  LayoutEmbeddedContentItem OwnerLayoutItem() const;
+  // LayoutObject for the element that contains this frame.
+  LayoutEmbeddedContent* OwnerLayoutObject() const;
 
   Settings* GetSettings() const;  // can be null
 
diff --git a/third_party/WebKit/Source/core/frame/FrameViewAutoSizeInfo.cpp b/third_party/WebKit/Source/core/frame/FrameViewAutoSizeInfo.cpp
index a18d67f..91dc064 100644
--- a/third_party/WebKit/Source/core/frame/FrameViewAutoSizeInfo.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameViewAutoSizeInfo.cpp
@@ -8,7 +8,6 @@
 #include "core/frame/LocalFrameView.h"
 #include "core/layout/LayoutBox.h"
 #include "core/layout/LayoutView.h"
-#include "core/layout/api/LayoutViewItem.h"
 #include "platform/wtf/AutoReset.h"
 
 namespace blink {
@@ -65,11 +64,11 @@
     // Update various sizes including contentsSize, scrollHeight, etc.
     document->UpdateStyleAndLayoutIgnorePendingStylesheets();
 
-    LayoutViewItem layout_view_item = document->GetLayoutViewItem();
-    if (layout_view_item.IsNull())
+    auto* layout_view = document->GetLayoutView();
+    if (!layout_view)
       return;
 
-    int width = layout_view_item.MinPreferredLogicalWidth().ToInt();
+    int width = layout_view->MinPreferredLogicalWidth().ToInt();
 
     LayoutBox* document_layout_box = document_element->GetLayoutBox();
     if (!document_layout_box)
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index 5314c37..db596ad7 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -194,7 +194,7 @@
     frame_view->SetParentVisible(true);
 
   // FIXME: Not clear what the right thing for OOPI is here.
-  if (!OwnerLayoutItem().IsNull()) {
+  if (OwnerLayoutObject()) {
     HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
     DCHECK(owner);
     // FIXME: OOPI might lead to us temporarily lying to a frame and telling it
@@ -443,10 +443,6 @@
   return GetDocument() ? GetDocument()->GetLayoutView() : nullptr;
 }
 
-LayoutViewItem LocalFrame::ContentLayoutItem() const {
-  return LayoutViewItem(ContentLayoutObject());
-}
-
 void LocalFrame::DidChangeVisibilityState() {
   if (GetDocument())
     GetDocument()->DidChangeVisibilityState();
@@ -563,10 +559,11 @@
 FloatSize LocalFrame::ResizePageRectsKeepingRatio(
     const FloatSize& original_size,
     const FloatSize& expected_size) const {
-  if (ContentLayoutItem().IsNull())
+  auto* layout_object = ContentLayoutObject();
+  if (!layout_object)
     return FloatSize();
 
-  bool is_horizontal = ContentLayoutItem().Style()->IsHorizontalWritingMode();
+  bool is_horizontal = layout_object->StyleRef().IsHorizontalWritingMode();
   float width = original_size.Width();
   float height = original_size.Height();
   if (!is_horizontal)
@@ -698,7 +695,7 @@
 
   LayoutPoint pt = View()->RootFrameToContents(point_in_root_frame);
 
-  if (ContentLayoutItem().IsNull())
+  if (!ContentLayoutObject())
     return nullptr;
   HitTestResult result = GetEventHandler().HitTestResultAtPoint(
       pt, HitTestRequest::kReadOnly | HitTestRequest::kActive);
@@ -746,14 +743,14 @@
 }
 
 String LocalFrame::GetLayerTreeAsTextForTesting(unsigned flags) const {
-  if (ContentLayoutItem().IsNull())
+  if (!ContentLayoutObject())
     return String();
 
   std::unique_ptr<JSONObject> layers;
   if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
     layers = View()->CompositedLayersAsJSON(static_cast<LayerTreeFlags>(flags));
   } else {
-    layers = ContentLayoutItem().Compositor()->LayerTreeAsJSON(
+    layers = ContentLayoutObject()->Compositor()->LayerTreeAsJSON(
         static_cast<LayerTreeFlags>(flags));
   }
 
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.h b/third_party/WebKit/Source/core/frame/LocalFrame.h
index 0a7818c..e6b97eb 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.h
@@ -69,7 +69,6 @@
 class IntPoint;
 class IntSize;
 class LayoutView;
-class LayoutViewItem;
 class LocalDOMWindow;
 class LocalWindowProxy;
 class LocalFrameClient;
@@ -149,7 +148,6 @@
 
   // Root of the layout tree for the document contained in this frame.
   LayoutView* ContentLayoutObject() const;
-  LayoutViewItem ContentLayoutItem() const;
 
   Editor& GetEditor() const;
   EventHandler& GetEventHandler() const;
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
index 5a9900b4..3ced3d6 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -570,15 +570,15 @@
 }
 
 void LocalFrameView::InvalidateRect(const IntRect& rect) {
-  LayoutEmbeddedContentItem layout_item = frame_->OwnerLayoutItem();
-  if (layout_item.IsNull())
+  auto* layout_object = frame_->OwnerLayoutObject();
+  if (!layout_object)
     return;
 
   IntRect paint_invalidation_rect = rect;
   paint_invalidation_rect.Move(
-      (layout_item.BorderLeft() + layout_item.PaddingLeft()).ToInt(),
-      (layout_item.BorderTop() + layout_item.PaddingTop()).ToInt());
-  layout_item.InvalidatePaintRectangle(LayoutRect(paint_invalidation_rect));
+      (layout_object->BorderLeft() + layout_object->PaddingLeft()).ToInt(),
+      (layout_object->BorderTop() + layout_object->PaddingTop()).ToInt());
+  layout_object->InvalidatePaintRectangle(LayoutRect(paint_invalidation_rect));
 }
 
 void LocalFrameView::SetFrameRect(const IntRect& frame_rect) {
@@ -601,8 +601,8 @@
     SetNeedsPaintPropertyUpdate();
   }
 
-  if (auto layout_view_item = this->GetLayoutViewItem())
-    layout_view_item.SetMayNeedPaintInvalidation();
+  if (auto* layout_view = GetLayoutView())
+    layout_view->SetMayNeedPaintInvalidation();
 
   if (width_changed || height_changed) {
     ViewportSizeChanged(width_changed, height_changed);
@@ -622,10 +622,6 @@
   return GetFrame().ContentLayoutObject();
 }
 
-LayoutViewItem LocalFrameView::GetLayoutViewItem() const {
-  return LayoutViewItem(GetFrame().ContentLayoutObject());
-}
-
 ScrollingCoordinator* LocalFrameView::GetScrollingCoordinator() const {
   Page* p = GetPage();
   return p ? p->GetScrollingCoordinator() : nullptr;
@@ -755,13 +751,13 @@
   if (suppress_adjust_view_size_)
     return;
 
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  if (layout_view_item.IsNull())
+  LayoutView* layout_view = GetLayoutView();
+  if (!layout_view)
     return;
 
   DCHECK_EQ(frame_->View(), this);
 
-  const IntRect rect = layout_view_item.DocumentRect();
+  const IntRect rect = layout_view->DocumentRect();
   const IntSize& size = rect.Size();
 
   if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
@@ -783,17 +779,17 @@
 }
 
 void LocalFrameView::UpdateAcceleratedCompositingSettings() {
-  if (LayoutViewItem layout_view_item = this->GetLayoutViewItem())
-    layout_view_item.Compositor()->UpdateAcceleratedCompositingSettings();
+  if (auto* layout_view = GetLayoutView())
+    layout_view->Compositor()->UpdateAcceleratedCompositingSettings();
 }
 
 void LocalFrameView::RecalcOverflowAfterStyleChange() {
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  CHECK(!layout_view_item.IsNull());
-  if (!layout_view_item.NeedsOverflowRecalcAfterStyleChange())
+  auto* layout_view = this->GetLayoutView();
+  CHECK(layout_view);
+  if (!layout_view->NeedsOverflowRecalcAfterStyleChange())
     return;
 
-  layout_view_item.RecalcOverflowAfterStyleChange();
+  layout_view->RecalcOverflowAfterStyleChange();
 
   // Changing overflow should notify scrolling coordinator to ensures that it
   // updates non-fast scroll rects even if there is no layout.
@@ -802,7 +798,7 @@
     SetScrollGestureRegionIsDirty(true);
   }
 
-  IntRect document_rect = layout_view_item.DocumentRect();
+  IntRect document_rect = layout_view->DocumentRect();
   if (ScrollOrigin() == -document_rect.Location() &&
       ContentsSize() == document_rect.Size())
     return;
@@ -813,7 +809,7 @@
   // If the visualViewport supplies scrollbars, we won't get a paint
   // invalidation from computeScrollbarExistence so we need to force one.
   if (VisualViewportSuppliesScrollbars())
-    layout_view_item.SetMayNeedPaintInvalidation();
+    layout_view->SetMayNeedPaintInvalidation();
 
   // TODO(pdr): This should be refactored to just block scrollbar updates as
   // we are not in a scrollbar update here and m_inUpdateScrollbars has other
@@ -844,18 +840,18 @@
 }
 
 void LocalFrameView::UpdateCountersAfterStyleChange() {
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  DCHECK(!layout_view_item.IsNull());
-  layout_view_item.UpdateCounters();
+  auto* layout_view = GetLayoutView();
+  DCHECK(layout_view);
+  layout_view->UpdateCounters();
 }
 
 bool LocalFrameView::UsesCompositedScrolling() const {
-  LayoutViewItem layout_view = this->GetLayoutViewItem();
-  if (layout_view.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return false;
   if (frame_->GetSettings() &&
       frame_->GetSettings()->GetPreferCompositingToLCDTextEnabled())
-    return layout_view.Compositor()->InCompositingMode();
+    return layout_view->Compositor()->InCompositingMode();
   return false;
 }
 
@@ -866,31 +862,31 @@
 }
 
 GraphicsLayer* LocalFrameView::LayerForScrolling() const {
-  LayoutViewItem layout_view = this->GetLayoutViewItem();
-  if (layout_view.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return nullptr;
-  return layout_view.Compositor()->FrameScrollLayer();
+  return layout_view->Compositor()->FrameScrollLayer();
 }
 
 GraphicsLayer* LocalFrameView::LayerForHorizontalScrollbar() const {
-  LayoutViewItem layout_view = this->GetLayoutViewItem();
-  if (layout_view.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return nullptr;
-  return layout_view.Compositor()->LayerForHorizontalScrollbar();
+  return layout_view->Compositor()->LayerForHorizontalScrollbar();
 }
 
 GraphicsLayer* LocalFrameView::LayerForVerticalScrollbar() const {
-  LayoutViewItem layout_view = this->GetLayoutViewItem();
-  if (layout_view.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return nullptr;
-  return layout_view.Compositor()->LayerForVerticalScrollbar();
+  return layout_view->Compositor()->LayerForVerticalScrollbar();
 }
 
 GraphicsLayer* LocalFrameView::LayerForScrollCorner() const {
-  LayoutViewItem layout_view = this->GetLayoutViewItem();
-  if (layout_view.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return nullptr;
-  return layout_view.Compositor()->LayerForScrollCorner();
+  return layout_view->Compositor()->LayerForScrollCorner();
 }
 
 bool LocalFrameView::IsEnclosedInCompositingLayer() const {
@@ -898,9 +894,9 @@
   // is called. crbug.com/366314
   DisableCompositingQueryAsserts disabler;
 
-  LayoutItem frame_owner_layout_item = frame_->OwnerLayoutItem();
-  return !frame_owner_layout_item.IsNull() &&
-         frame_owner_layout_item.EnclosingLayer()
+  auto* frame_owner_layout_object = frame_->OwnerLayoutObject();
+  return frame_owner_layout_object &&
+         frame_owner_layout_object->EnclosingLayer()
              ->EnclosingLayerForPaintInvalidationCrossingFrameBoundaries();
 }
 
@@ -921,8 +917,8 @@
 
 inline void LocalFrameView::ForceLayoutParentViewIfNeeded() {
   AutoReset<bool> prevent_update_layout(&forcing_layout_parent_view_, true);
-  LayoutEmbeddedContentItem owner_layout_item = frame_->OwnerLayoutItem();
-  if (owner_layout_item.IsNull() || !owner_layout_item.GetFrame())
+  auto* owner_layout_object = frame_->OwnerLayoutObject();
+  if (!owner_layout_object || !owner_layout_object->GetFrame())
     return;
 
   LayoutReplaced* content_box = EmbeddedReplacedContent();
@@ -943,11 +939,12 @@
   // LayoutSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying out
   // for the first time, or when the LayoutSVGRoot size has changed dynamically
   // (eg. via <script>).
-  LocalFrameView* frame_view = owner_layout_item.GetFrame()->View();
+  LocalFrameView* frame_view = owner_layout_object->GetFrame()->View();
 
   // Mark the owner layoutObject as needing layout.
-  owner_layout_item.SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
-      LayoutInvalidationReason::kUnknown);
+  owner_layout_object
+      ->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+          LayoutInvalidationReason::kUnknown);
 
   // Synchronously enter layout, to layout the view containing the host
   // object/embed/iframe.
@@ -1008,9 +1005,21 @@
          !frame_->GetDocument()->FinishingOrIsPrinting();
 }
 
-static inline void LayoutFromRootObject(LayoutObject& root) {
+void LocalFrameView::LayoutFromRootObject(LayoutObject& root) {
   LayoutState layout_state(root);
-  root.UpdateLayout();
+  if (!root.IsBoxModelObject()) {
+    root.UpdateLayout();
+  } else {
+    // Laying out the root may change its visual overflow. If so, that
+    // visual overflow needs to propagate to its containing block.
+    LayoutBoxModelObject& box_object = ToLayoutBoxModelObject(root);
+    LayoutRect previous_visual_overflow_rect = box_object.VisualOverflowRect();
+    box_object.UpdateLayout();
+    if (box_object.VisualOverflowRect() != previous_visual_overflow_rect) {
+      box_object.SetNeedsOverflowRecalcAfterStyleChange();
+      RecalcOverflowAfterStyleChange();
+    }
+  }
 }
 
 void LocalFrameView::PrepareLayoutAnalyzer() {
@@ -1030,13 +1039,12 @@
   if (!analyzer_)
     return TracedValue::Create();
   std::unique_ptr<TracedValue> value = analyzer_->ToTracedValue();
-  value->SetString("host",
-                   GetLayoutViewItem().GetDocument().location()->host());
+  value->SetString("host", GetLayoutView()->GetDocument().location()->host());
   value->SetString(
       "frame",
       String::Format("0x%" PRIxPTR, reinterpret_cast<uintptr_t>(frame_.Get())));
   value->SetInteger("contentsHeightAfterLayout",
-                    GetLayoutViewItem().DocumentRect().Height());
+                    GetLayoutView()->DocumentRect().Height());
   value->SetInteger("visibleHeight", VisibleHeight());
   value->SetInteger("approximateBlankCharacterCount",
                     FontFaceSetDocument::ApproximateBlankCharacterCount(
@@ -1050,8 +1058,7 @@
 bool LocalFrameView::PerformLayout(bool in_subtree_layout) {
   DCHECK(in_subtree_layout || layout_subtree_root_list_.IsEmpty());
 
-  int contents_height_before_layout =
-      GetLayoutViewItem().DocumentRect().Height();
+  int contents_height_before_layout = GetLayoutView()->DocumentRect().Height();
   TRACE_EVENT_BEGIN1(
       PERFORM_LAYOUT_TRACE_CATEGORIES, "LocalFrameView::performLayout",
       "contentsHeightBeforeLayout", contents_height_before_layout);
@@ -1118,7 +1125,7 @@
   FirstMeaningfulPaintDetector::From(*frame_->GetDocument())
       .MarkNextPaintAsMeaningfulIfNeeded(
           layout_object_counter_, contents_height_before_layout,
-          GetLayoutViewItem().DocumentRect().Height(), VisibleHeight());
+          GetLayoutView()->DocumentRect().Height(), VisibleHeight());
   return true;
 }
 
@@ -1196,9 +1203,9 @@
     // If the layout view was marked as needing layout after we added items in
     // the subtree roots we need to clear the roots and do the layout from the
     // layoutView.
-    if (GetLayoutViewItem().NeedsLayout())
+    if (GetLayoutView()->NeedsLayout())
       ClearLayoutSubtreeRootsAndMarkContainingBlocks();
-    GetLayoutViewItem().ClearHitTestCache();
+    GetLayoutView()->ClearHitTestCache();
 
     bool in_subtree_layout = IsSubtreeLayout();
 
@@ -1239,7 +1246,7 @@
 
         first_layout_ = false;
         last_viewport_size_ = GetLayoutSize(kIncludeScrollbars);
-        last_zoom_factor_ = GetLayoutViewItem().Style()->Zoom();
+        last_zoom_factor_ = GetLayoutView()->Style()->Zoom();
 
         // Set the initial vMode to AlwaysOn if we're auto.
         if (v_mode == kScrollbarAuto) {
@@ -1326,13 +1333,13 @@
 
   // FIXME: Could find the common ancestor layer of all dirty subtrees and mark
   // from there. crbug.com/462719
-  GetLayoutViewItem().EnclosingLayer()->UpdateLayerPositionsAfterLayout();
+  GetLayoutView()->EnclosingLayer()->UpdateLayerPositionsAfterLayout();
 
   TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
       TRACE_DISABLED_BY_DEFAULT("blink.debug.layout.trees"), "LayoutTree", this,
       TracedLayoutObject::Create(*GetLayoutView(), true));
 
-  GetLayoutViewItem().Compositor()->DidLayout();
+  GetLayoutView()->Compositor()->DidLayout();
 
   layout_count_++;
 
@@ -1414,13 +1421,13 @@
   if (!frame_->GetDocument() || !frame_->GetDocument()->Printing())
     zoom = GetFrame().PageZoomFactor();
 
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  if (layout_view_item.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return FloatSize();
 
   FloatSize layout_size;
-  layout_size.SetWidth(layout_view_item.ViewWidth(kIncludeScrollbars) / zoom);
-  layout_size.SetHeight(layout_view_item.ViewHeight(kIncludeScrollbars) / zoom);
+  layout_size.SetWidth(layout_view->ViewWidth(kIncludeScrollbars) / zoom);
+  layout_size.SetHeight(layout_view->ViewHeight(kIncludeScrollbars) / zoom);
 
   BrowserControls& browser_controls = frame_->GetPage()->GetBrowserControls();
   if (browser_controls.PermittedState() != kWebBrowserControlsHidden) {
@@ -1456,11 +1463,11 @@
 }
 
 LayoutReplaced* LocalFrameView::EmbeddedReplacedContent() const {
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  if (layout_view_item.IsNull())
+  auto* layout_view = this->GetLayoutView();
+  if (!layout_view)
     return nullptr;
 
-  LayoutObject* first_child = GetLayoutView()->FirstChild();
+  LayoutObject* first_child = layout_view->FirstChild();
   if (!first_child || !first_child->IsBox())
     return nullptr;
 
@@ -1480,7 +1487,7 @@
   for (const auto& view : views) {
     // Script or plugins could detach the frame so abort processing if that
     // happens.
-    if (GetLayoutViewItem().IsNull())
+    if (!GetLayoutView())
       break;
 
     view->UpdateGeometry();
@@ -1578,9 +1585,9 @@
 }
 
 bool LocalFrameView::ContentsInCompositedLayer() const {
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  return !layout_view_item.IsNull() &&
-         layout_view_item.GetCompositingState() == kPaintsIntoOwnBacking;
+  auto* layout_view = this->GetLayoutView();
+  return layout_view &&
+         layout_view->GetCompositingState() == kPaintsIntoOwnBacking;
 }
 
 void LocalFrameView::AddBackgroundAttachmentFixedObject(LayoutObject* object) {
@@ -1699,10 +1706,11 @@
       // URL bar will expose area outside the current LayoutView so we need to
       // paint additional background. If RLS is on, we've already invalidated
       // above.
-      LayoutViewItem lvi = GetLayoutViewItem();
-      DCHECK(!lvi.IsNull());
-      if (lvi.DocumentRect().Height() < lvi.ViewRect().Height()) {
-        lvi.SetShouldDoFullPaintInvalidation(
+      auto* layout_view = GetLayoutView();
+      DCHECK(layout_view);
+      if (layout_view->DocumentRect().Height() <
+          layout_view->ViewRect().Height()) {
+        layout_view->SetShouldDoFullPaintInvalidation(
             PaintInvalidationReason::kGeometry);
       }
     }
@@ -1857,21 +1865,18 @@
   // all of the objects.
   // FIXME: Find out what are enough to invalidate in slow path scrolling.
   // crbug.com/451090#9.
-  DCHECK(!GetLayoutViewItem().IsNull());
+  auto* layout_view = GetLayoutView();
+  DCHECK(layout_view);
   if (ContentsInCompositedLayer()) {
-    GetLayoutViewItem()
-        .Layer()
-        ->GetCompositedLayerMapping()
-        ->SetContentsNeedDisplay();
+    layout_view->Layer()->GetCompositedLayerMapping()->SetContentsNeedDisplay();
   } else {
-    GetLayoutViewItem()
-        .SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+    layout_view
+        ->SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
   }
 
   if (ContentsInCompositedLayer()) {
     IntRect update_rect = VisibleContentRect();
-    DCHECK(!GetLayoutViewItem().IsNull());
-    GetLayoutViewItem().InvalidatePaintRectangle(LayoutRect(update_rect));
+    layout_view->InvalidatePaintRectangle(LayoutRect(update_rect));
   }
 }
 
@@ -1981,8 +1986,8 @@
 
   // If layout is needed, we will scroll in performPostLayoutTasks. Otherwise,
   // scroll immediately.
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  if (!layout_view_item.IsNull() && layout_view_item.NeedsLayout())
+  auto* layout_view = this->GetLayoutView();
+  if (layout_view && layout_view->NeedsLayout())
     UpdateLayout();
   else
     ScrollToFragmentAnchor();
@@ -2042,8 +2047,7 @@
 }
 
 void LocalFrameView::DidScrollTimerFired(TimerBase*) {
-  if (frame_->GetDocument() &&
-      !frame_->GetDocument()->GetLayoutViewItem().IsNull())
+  if (frame_->GetDocument() && frame_->GetDocument()->GetLayoutView())
     frame_->GetDocument()->Fetcher()->UpdateAllImageResourcePriorities();
 
   GetFrame().Loader().SaveScrollAnchor();
@@ -2090,9 +2094,8 @@
   // only if we're not inside of layout.
   if (!nested_layout_count_) {
     UpdateGeometries();
-    LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-    if (!layout_view_item.IsNull())
-      layout_view_item.Layer()->SetNeedsCompositingInputsUpdate();
+    if (auto* layout_view = this->GetLayoutView())
+      layout_view->Layer()->SetNeedsCompositingInputsUpdate();
   }
 }
 
@@ -2176,8 +2179,10 @@
 
 void LocalFrameView::SetNeedsCompositingUpdate(
     CompositingUpdateType update_type) {
-  if (!GetLayoutViewItem().IsNull() && frame_->GetDocument()->IsActive())
-    GetLayoutViewItem().Compositor()->SetNeedsCompositingUpdate(update_type);
+  if (auto* layout_view = GetLayoutView()) {
+    if (frame_->GetDocument()->IsActive())
+      layout_view->Compositor()->SetNeedsCompositingUpdate(update_type);
+  }
 }
 
 PlatformChromeClient* LocalFrameView::GetChromeClient() const {
@@ -2223,11 +2228,12 @@
   if (!uses_overlay_scrollbars && NeedsLayout())
     UpdateLayout();
 
-  if (!GetLayoutViewItem().IsNull() && GetLayoutViewItem().UsesCompositing()) {
-    GetLayoutViewItem().Compositor()->FrameViewScrollbarsExistenceDidChange();
+  auto* layout_view = GetLayoutView();
+  if (layout_view && layout_view->UsesCompositing()) {
+    layout_view->Compositor()->FrameViewScrollbarsExistenceDidChange();
 
     if (!uses_overlay_scrollbars)
-      GetLayoutViewItem().Compositor()->FrameViewDidChangeSize();
+      layout_view->Compositor()->FrameViewDidChangeSize();
   }
 }
 
@@ -2399,29 +2405,27 @@
   // Document::shouldScheduleLayout takes care of preventing us from scheduling
   // layout in that case.
 
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  return LayoutPending() ||
-         (!layout_view_item.IsNull() && layout_view_item.NeedsLayout()) ||
+  auto* layout_view = GetLayoutView();
+  return LayoutPending() || (layout_view && layout_view->NeedsLayout()) ||
          IsSubtreeLayout();
 }
 
 NOINLINE bool LocalFrameView::CheckDoesNotNeedLayout() const {
   CHECK_FOR_DIRTY_LAYOUT(!LayoutPending());
-  CHECK_FOR_DIRTY_LAYOUT(GetLayoutViewItem().IsNull() ||
-                         !GetLayoutViewItem().NeedsLayout());
+  CHECK_FOR_DIRTY_LAYOUT(!GetLayoutView() || !GetLayoutView()->NeedsLayout());
   CHECK_FOR_DIRTY_LAYOUT(!IsSubtreeLayout());
   return true;
 }
 
 void LocalFrameView::SetNeedsLayout() {
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  if (layout_view_item.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return;
   // TODO(crbug.com/590856): It's still broken if we choose not to crash when
   // the check fails.
   if (!CheckLayoutInvalidationIsAllowed())
     return;
-  layout_view_item.SetNeedsLayout(LayoutInvalidationReason::kUnknown);
+  layout_view->SetNeedsLayout(LayoutInvalidationReason::kUnknown);
 }
 
 bool LocalFrameView::HasOpaqueBackground() const {
@@ -2438,15 +2442,16 @@
 
   base_background_color_ = background_color;
 
-  if (!GetLayoutViewItem().IsNull() &&
-      GetLayoutViewItem().Layer()->HasCompositedLayerMapping()) {
-    CompositedLayerMapping* composited_layer_mapping =
-        GetLayoutViewItem().Layer()->GetCompositedLayerMapping();
-    composited_layer_mapping->UpdateContentsOpaque();
-    if (composited_layer_mapping->MainGraphicsLayer())
-      composited_layer_mapping->MainGraphicsLayer()->SetNeedsDisplay();
-    if (composited_layer_mapping->ScrollingContentsLayer())
-      composited_layer_mapping->ScrollingContentsLayer()->SetNeedsDisplay();
+  if (auto* layout_view = GetLayoutView()) {
+    if (layout_view->Layer()->HasCompositedLayerMapping()) {
+      CompositedLayerMapping* composited_layer_mapping =
+          layout_view->Layer()->GetCompositedLayerMapping();
+      composited_layer_mapping->UpdateContentsOpaque();
+      if (composited_layer_mapping->MainGraphicsLayer())
+        composited_layer_mapping->MainGraphicsLayer()->SetNeedsDisplay();
+      if (composited_layer_mapping->ScrollingContentsLayer())
+        composited_layer_mapping->ScrollingContentsLayer()->SetNeedsDisplay();
+    }
   }
   RecalculateScrollbarOverlayColorTheme(DocumentBackgroundColor());
 
@@ -2615,7 +2620,7 @@
   UpdateGeometries();
 
   // Plugins could have torn down the page inside updateGeometries().
-  if (GetLayoutViewItem().IsNull())
+  if (!GetLayoutView())
     return;
 
   ScheduleUpdatePluginsIfNecessary();
@@ -2638,26 +2643,25 @@
 
 bool LocalFrameView::WasViewportResized() {
   DCHECK(frame_);
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  if (layout_view_item.IsNull())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view)
     return false;
-  DCHECK(layout_view_item.Style());
   return (GetLayoutSize(kIncludeScrollbars) != last_viewport_size_ ||
-          layout_view_item.Style()->Zoom() != last_zoom_factor_);
+          layout_view->StyleRef().Zoom() != last_zoom_factor_);
 }
 
 void LocalFrameView::SendResizeEventIfNeeded() {
   DCHECK(frame_);
 
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  if (layout_view_item.IsNull() || layout_view_item.GetDocument().Printing())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view || layout_view->GetDocument().Printing())
     return;
 
   if (!WasViewportResized())
     return;
 
   last_viewport_size_ = GetLayoutSize(kIncludeScrollbars);
-  last_zoom_factor_ = layout_view_item.Style()->Zoom();
+  last_zoom_factor_ = layout_view->StyleRef().Zoom();
 
   if (RuntimeEnabledFeatures::VisualViewportAPIEnabled())
     frame_->GetDocument()->EnqueueVisualViewportResizeEvent();
@@ -2722,9 +2726,8 @@
 
 void LocalFrameView::ScrollbarVisibilityChanged() {
   UpdateScrollbarEnabledState();
-  LayoutViewItem view_item = GetLayoutViewItem();
-  if (!view_item.IsNull())
-    view_item.ClearHitTestCache();
+  if (auto* layout_view = GetLayoutView())
+    layout_view->ClearHitTestCache();
 }
 
 void LocalFrameView::ScrollbarFrameRectChanged() {
@@ -2732,11 +2735,11 @@
 }
 
 IntRect LocalFrameView::ScrollableAreaBoundingBox() const {
-  LayoutEmbeddedContentItem owner_layout_item = GetFrame().OwnerLayoutItem();
-  if (owner_layout_item.IsNull())
+  auto* owner_layout_object = GetFrame().OwnerLayoutObject();
+  if (!owner_layout_object)
     return FrameRect();
 
-  return owner_layout_item.AbsoluteContentQuad(kTraverseDocumentBoundaries)
+  return owner_layout_object->AbsoluteContentQuad(kTraverseDocumentBoundaries)
       .EnclosingBoundingBox();
 }
 
@@ -2919,10 +2922,11 @@
     if (!corner_style) {
       // If we have an owning ipage/LocalFrame element, then it can set the
       // custom scrollbar also.
-      LayoutEmbeddedContentItem layout_item = frame_->OwnerLayoutItem();
-      if (!layout_item.IsNull()) {
-        corner_style = layout_item.GetUncachedPseudoStyle(
-            PseudoStyleRequest(kPseudoIdScrollbarCorner), layout_item.Style());
+      auto* layout_object = frame_->OwnerLayoutObject();
+      if (layout_object) {
+        corner_style = layout_object->GetUncachedPseudoStyle(
+            PseudoStyleRequest(kPseudoIdScrollbarCorner),
+            layout_object->Style());
       }
     }
   }
@@ -2944,10 +2948,10 @@
   // background color of the LocalFrameView. This should match the color drawn
   // by ViewPainter::paintBoxDecorationBackground.
   Color result = BaseBackgroundColor();
-  LayoutItem document_layout_object = GetLayoutViewItem();
-  if (!document_layout_object.IsNull()) {
+  auto* layout_view = GetLayoutView();
+  if (layout_view) {
     result = result.Blend(
-        document_layout_object.ResolveColor(GetCSSPropertyBackgroundColor()));
+        layout_view->ResolveColor(GetCSSPropertyBackgroundColor()));
   }
   return result;
 }
@@ -3215,7 +3219,7 @@
         [](LocalFrameView& frame_view) { frame_view.NotifyResizeObservers(); });
   }
 
-  if (LayoutViewItem view = GetLayoutViewItem()) {
+  if (auto* layout_view = GetLayoutView()) {
     ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
       frame_view.CheckDoesNotNeedLayout();
       frame_view.allows_layout_invalidation_after_layout_clean_ = false;
@@ -3226,7 +3230,7 @@
                    InspectorUpdateLayerTreeEvent::Data(frame_.Get()));
 
       if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
-        view.Compositor()->UpdateIfNeededRecursive(target_state);
+        layout_view->Compositor()->UpdateIfNeededRecursive(target_state);
       } else {
         ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
           frame_view.GetLayoutView()->Layer()->UpdateDescendantDependentFlags();
@@ -3244,7 +3248,7 @@
 
       if (target_state >= DocumentLifecycle::kPrePaintClean) {
         if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
-          if (view.Compositor()->InCompositingMode()) {
+          if (layout_view->Compositor()->InCompositingMode()) {
             GetScrollingCoordinator()->UpdateAfterCompositingChangeIfNeeded(
                 this);
           }
@@ -3330,8 +3334,8 @@
       // we need to propagate the flags into the ancestor chain so that
       // PrePaintTreeWalk can reach this frame.
       frame_view.SetNeedsPaintPropertyUpdate();
-      if (auto owner = frame_view.GetFrame().OwnerLayoutItem())
-        owner.SetMayNeedPaintInvalidation();
+      if (auto* owner = frame_view.GetFrame().OwnerLayoutObject())
+        owner->SetMayNeedPaintInvalidation();
     }
   });
 
@@ -3352,8 +3356,8 @@
   DCHECK(GetFrame() == GetPage()->MainFrame() ||
          (!GetFrame().Tree().Parent()->IsLocalFrame()));
 
-  LayoutViewItem view = GetLayoutViewItem();
-  DCHECK(!view.IsNull());
+  auto* layout_view = GetLayoutView();
+  DCHECK(layout_view);
   paint_frame_count_++;
   ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
     frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPaint);
@@ -3385,7 +3389,7 @@
     // frame view of a page overlay. The page overlay is in the layer tree of
     // the host page and will be painted during painting of the host page.
     if (GraphicsLayer* root_graphics_layer =
-            view.Compositor()->RootGraphicsLayer())
+            layout_view->Compositor()->RootGraphicsLayer())
       root_graphics_layer->PaintRecursively();
 
     // TODO(sataya.m):Main frame doesn't create RootFrameViewport in some
@@ -3405,9 +3409,8 @@
 
   ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
     frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kPaintClean);
-    LayoutViewItem layout_view_item = frame_view.GetLayoutViewItem();
-    if (!layout_view_item.IsNull())
-      layout_view_item.Layer()->ClearNeedsRepaintRecursively();
+    if (auto* layout_view = frame_view.GetLayoutView())
+      layout_view->Layer()->ClearNeedsRepaintRecursively();
   });
 }
 
@@ -3643,19 +3646,19 @@
   AdjustViewSizeAndLayout();
 }
 
-IntRect LocalFrameView::ConvertFromLayoutItem(
-    const LayoutItem& layout_item,
+IntRect LocalFrameView::ConvertFromLayoutObject(
+    const LayoutObject& layout_object,
     const IntRect& layout_object_rect) const {
   // Convert from page ("absolute") to LocalFrameView coordinates.
   LayoutRect rect = EnclosingLayoutRect(
-      layout_item.LocalToAbsoluteQuad(FloatRect(layout_object_rect))
+      layout_object.LocalToAbsoluteQuad(FloatRect(layout_object_rect))
           .BoundingBox());
   rect.Move(LayoutSize(-GetScrollOffset()));
   return PixelSnappedIntRect(rect);
 }
 
-IntRect LocalFrameView::ConvertToLayoutItem(const LayoutItem& layout_item,
-                                            const IntRect& frame_rect) const {
+IntRect LocalFrameView::ConvertToLayoutObject(const LayoutObject& layout_object,
+                                              const IntRect& frame_rect) const {
   IntRect rect_in_content = FrameToContents(frame_rect);
 
   // Convert from LocalFrameView coords into page ("absolute") coordinates.
@@ -3663,38 +3666,38 @@
 
   // FIXME: we don't have a way to map an absolute rect down to a local quad, so
   // just move the rect for now.
-  rect_in_content.SetLocation(RoundedIntPoint(
-      layout_item.AbsoluteToLocal(rect_in_content.Location(), kUseTransforms)));
+  rect_in_content.SetLocation(RoundedIntPoint(layout_object.AbsoluteToLocal(
+      rect_in_content.Location(), kUseTransforms)));
   return rect_in_content;
 }
 
-IntPoint LocalFrameView::ConvertFromLayoutItem(
-    const LayoutItem& layout_item,
+IntPoint LocalFrameView::ConvertFromLayoutObject(
+    const LayoutObject& layout_object,
     const IntPoint& layout_object_point) const {
   return RoundedIntPoint(
-      ConvertFromLayoutItem(layout_item, LayoutPoint(layout_object_point)));
+      ConvertFromLayoutObject(layout_object, LayoutPoint(layout_object_point)));
 }
 
-IntPoint LocalFrameView::ConvertToLayoutItem(
-    const LayoutItem& layout_item,
+IntPoint LocalFrameView::ConvertToLayoutObject(
+    const LayoutObject& layout_object,
     const IntPoint& frame_point) const {
   return RoundedIntPoint(
-      ConvertToLayoutItem(layout_item, LayoutPoint(frame_point)));
+      ConvertToLayoutObject(layout_object, LayoutPoint(frame_point)));
 }
 
-LayoutPoint LocalFrameView::ConvertFromLayoutItem(
-    const LayoutItem& layout_item,
+LayoutPoint LocalFrameView::ConvertFromLayoutObject(
+    const LayoutObject& layout_object,
     const LayoutPoint& layout_object_point) const {
-  LayoutPoint point(layout_item.LocalToAbsolute(FloatPoint(layout_object_point),
-                                                kUseTransforms));
+  LayoutPoint point(layout_object.LocalToAbsolute(
+      FloatPoint(layout_object_point), kUseTransforms));
 
   // Convert from page ("absolute") to LocalFrameView coordinates.
   point.Move(-LayoutSize(GetScrollOffset()));
   return point;
 }
 
-LayoutPoint LocalFrameView::ConvertToLayoutItem(
-    const LayoutItem& layout_item,
+LayoutPoint LocalFrameView::ConvertToLayoutObject(
+    const LayoutObject& layout_object,
     const LayoutPoint& frame_point) const {
   LayoutPoint point = frame_point;
 
@@ -3702,7 +3705,7 @@
   point += LayoutSize(ScrollX(), ScrollY());
 
   return LayoutPoint(
-      layout_item.AbsoluteToLocal(FloatPoint(point), kUseTransforms));
+      layout_object.AbsoluteToLocal(FloatPoint(point), kUseTransforms));
 }
 
 IntPoint LocalFrameView::ConvertSelfToChild(const EmbeddedContentView& child,
@@ -3746,7 +3749,7 @@
 DoublePoint LocalFrameView::DocumentToAbsolute(
     const DoublePoint& point_in_document) const {
   return point_in_document -
-         GetLayoutViewItem().GetScrollableArea()->GetScrollOffset();
+         GetLayoutView()->GetScrollableArea()->GetScrollOffset();
 }
 
 FloatPoint LocalFrameView::DocumentToAbsolute(
@@ -3757,16 +3760,16 @@
 IntRect LocalFrameView::ConvertToContainingEmbeddedContentView(
     const IntRect& local_rect) const {
   if (LocalFrameView* parent = ParentFrameView()) {
-    // Get our layoutObject in the parent view
-    LayoutEmbeddedContentItem layout_item = frame_->OwnerLayoutItem();
-    if (layout_item.IsNull())
+    auto* layout_object = frame_->OwnerLayoutObject();
+    if (!layout_object)
       return local_rect;
 
     IntRect rect(local_rect);
-    // Add borders and padding??
-    rect.Move((layout_item.BorderLeft() + layout_item.PaddingLeft()).ToInt(),
-              (layout_item.BorderTop() + layout_item.PaddingTop()).ToInt());
-    return parent->ConvertFromLayoutItem(layout_item, rect);
+    // Add borders and padding
+    rect.Move(
+        (layout_object->BorderLeft() + layout_object->PaddingLeft()).ToInt(),
+        (layout_object->BorderTop() + layout_object->PaddingTop()).ToInt());
+    return parent->ConvertFromLayoutObject(*layout_object, rect);
   }
 
   return local_rect;
@@ -3787,17 +3790,16 @@
 LayoutPoint LocalFrameView::ConvertToContainingEmbeddedContentView(
     const LayoutPoint& local_point) const {
   if (LocalFrameView* parent = ParentFrameView()) {
-    // Get our layoutObject in the parent view
-    LayoutEmbeddedContentItem layout_item = frame_->OwnerLayoutItem();
-    if (layout_item.IsNull())
+    auto* layout_object = frame_->OwnerLayoutObject();
+    if (!layout_object)
       return local_point;
 
     LayoutPoint point(local_point);
 
     // Add borders and padding
-    point.Move((layout_item.BorderLeft() + layout_item.PaddingLeft()),
-               (layout_item.BorderTop() + layout_item.PaddingTop()));
-    return parent->ConvertFromLayoutItem(layout_item, point);
+    point.Move((layout_object->BorderLeft() + layout_object->PaddingLeft()),
+               (layout_object->BorderTop() + layout_object->PaddingTop()));
+    return parent->ConvertFromLayoutObject(*layout_object, point);
   }
 
   return local_point;
@@ -3807,14 +3809,15 @@
     const LayoutPoint& parent_point) const {
   if (LocalFrameView* parent = ParentFrameView()) {
     // Get our layoutObject in the parent view
-    LayoutEmbeddedContentItem layout_item = frame_->OwnerLayoutItem();
-    if (layout_item.IsNull())
+    auto* layout_object = frame_->OwnerLayoutObject();
+    if (!layout_object)
       return parent_point;
 
-    LayoutPoint point = parent->ConvertToLayoutItem(layout_item, parent_point);
+    LayoutPoint point =
+        parent->ConvertToLayoutObject(*layout_object, parent_point);
     // Subtract borders and padding
-    point.Move((-layout_item.BorderLeft() - layout_item.PaddingLeft()),
-               (-layout_item.BorderTop() - layout_item.PaddingTop()));
+    point.Move((-layout_object->BorderLeft() - layout_object->PaddingLeft()),
+               (-layout_object->BorderTop() - layout_object->PaddingTop()));
     return point;
   }
 
@@ -3850,8 +3853,8 @@
        frame = frame->Tree().TraverseNext()) {
     if (!frame->IsLocalFrame())
       continue;
-    if (LayoutViewItem layout_view = ToLocalFrame(frame)->ContentLayoutItem()) {
-      layout_view.GetFrameView()->tracked_object_paint_invalidations_ =
+    if (auto* layout_view = ToLocalFrame(frame)->ContentLayoutObject()) {
+      layout_view->GetFrameView()->tracked_object_paint_invalidations_ =
           WTF::WrapUnique(track_paint_invalidations
                               ? new Vector<ObjectPaintInvalidation>
                               : nullptr);
@@ -3865,7 +3868,7 @@
               track_paint_invalidations);
         }
       } else {
-        layout_view.Compositor()->UpdateTrackingRasterInvalidations();
+        layout_view->Compositor()->UpdateTrackingRasterInvalidations();
       }
     }
   }
@@ -3896,11 +3899,11 @@
        frame = frame->Tree().TraverseNext()) {
     if (!frame->IsLocalFrame())
       continue;
-    if (LayoutViewItem layout_view = ToLocalFrame(frame)->ContentLayoutItem()) {
-      if (!layout_view.GetFrameView()->tracked_object_paint_invalidations_)
+    if (auto* layout_view = ToLocalFrame(frame)->ContentLayoutObject()) {
+      if (!layout_view->GetFrameView()->tracked_object_paint_invalidations_)
         continue;
       for (const auto& item :
-           *layout_view.GetFrameView()->tracked_object_paint_invalidations_) {
+           *layout_view->GetFrameView()->tracked_object_paint_invalidations_) {
         std::unique_ptr<JSONObject> item_json = JSONObject::Create();
         item_json->SetString("object", item.name);
         item_json->SetString("reason",
@@ -4109,11 +4112,11 @@
 }
 
 PaintLayer* LocalFrameView::Layer() const {
-  LayoutViewItem layout_view = GetLayoutViewItem();
-  if (layout_view.IsNull() || !layout_view.Compositor())
+  auto* layout_view = GetLayoutView();
+  if (!layout_view || !layout_view->Compositor())
     return nullptr;
 
-  return layout_view.Compositor()->RootLayer();
+  return layout_view->Compositor()->RootLayer();
 }
 
 IntSize LocalFrameView::MaximumScrollOffsetInt() const {
@@ -4274,11 +4277,11 @@
       page->GetChromeClient().ClearToolTip(*frame_);
   }
 
-  LayoutViewItem layout_view_item = document->GetLayoutViewItem();
-  if (!layout_view_item.IsNull()) {
-    if (layout_view_item.UsesCompositing())
-      layout_view_item.Compositor()->FrameViewDidScroll();
-    layout_view_item.ClearHitTestCache();
+  auto* layout_view = GetLayoutView();
+  if (layout_view) {
+    if (layout_view->UsesCompositing())
+      layout_view->Compositor()->FrameViewDidScroll();
+    layout_view->ClearHitTestCache();
   }
 
   did_scroll_timer_.StartOneShot(kResourcePriorityUpdateDelayAfterScroll,
@@ -4857,9 +4860,9 @@
   if (ScrollOriginChanged()) {
     // If the scroll origin changed, we need to update the layer position on
     // the compositor since the offset itself might not have changed.
-    LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-    if (!layout_view_item.IsNull() && layout_view_item.UsesCompositing())
-      layout_view_item.Compositor()->FrameViewDidScroll();
+    auto* layout_view = GetLayoutView();
+    if (layout_view && layout_view->UsesCompositing())
+      layout_view->Compositor()->FrameViewDidScroll();
     ResetScrollOriginChanged();
   }
   return false;
@@ -5205,9 +5208,8 @@
   if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled())
     return this;
 
-  LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-  return layout_view_item.IsNull() ? nullptr
-                                   : layout_view_item.GetScrollableArea();
+  auto* layout_view = this->GetLayoutView();
+  return layout_view ? layout_view->GetScrollableArea() : nullptr;
 }
 
 RootFrameViewport* LocalFrameView::GetRootFrameViewport() {
@@ -5338,9 +5340,9 @@
     // Force a full repaint of this frame to ensure we are not left with a
     // partially painted version of this frame's contents if we skipped
     // painting them while the frame was throttled.
-    LayoutViewItem layout_view_item = this->GetLayoutViewItem();
-    if (!layout_view_item.IsNull())
-      layout_view_item.InvalidatePaintForViewAndCompositedLayers();
+    auto* layout_view = GetLayoutView();
+    if (layout_view)
+      layout_view->InvalidatePaintForViewAndCompositedLayers();
     // Also need to update all paint properties that might be skipped while
     // the frame was throttled.
     SetSubtreeNeedsPaintPropertyUpdate();
@@ -5484,8 +5486,8 @@
   if (!GetFrame().Loader().StateMachine()->CommittedFirstRealDocumentLoad())
     return;
   lifecycle_updates_throttled_ = false;
-  if (auto owner = GetFrame().OwnerLayoutItem())
-    owner.SetMayNeedPaintInvalidation();
+  if (auto* owner = GetFrame().OwnerLayoutObject())
+    owner->SetMayNeedPaintInvalidation();
 
   LayoutView* layout_view = GetLayoutView();
   bool layout_view_is_empty = layout_view && !layout_view->FirstChild();
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.h b/third_party/WebKit/Source/core/frame/LocalFrameView.h
index 204cc74..48f0387 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameView.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrameView.h
@@ -77,8 +77,6 @@
 class JSONArray;
 class JSONObject;
 class LayoutEmbeddedContent;
-class LayoutItem;
-class LayoutViewItem;
 class LocalFrame;
 class KURL;
 class Node;
@@ -141,10 +139,7 @@
 
   Page* GetPage() const;
 
-  // TODO(pilgrim) replace all instances of layoutView() with layoutViewItem()
-  // https://crbug.com/499321
   LayoutView* GetLayoutView() const;
-  LayoutViewItem GetLayoutViewItem() const;
 
   // If false, prevents scrollbars on the viewport even if web content would
   // make them appear. Also prevents user-input scrolls (but not programmatic
@@ -360,14 +355,15 @@
   void ClearFragmentAnchor();
 
   // Methods to convert points and rects between the coordinate space of the
-  // layoutItem, and this view.
-  IntRect ConvertFromLayoutItem(const LayoutItem&, const IntRect&) const;
-  IntRect ConvertToLayoutItem(const LayoutItem&, const IntRect&) const;
-  IntPoint ConvertFromLayoutItem(const LayoutItem&, const IntPoint&) const;
-  IntPoint ConvertToLayoutItem(const LayoutItem&, const IntPoint&) const;
-  LayoutPoint ConvertFromLayoutItem(const LayoutItem&,
+  // layoutObject, and this view.
+  IntRect ConvertFromLayoutObject(const LayoutObject&, const IntRect&) const;
+  IntRect ConvertToLayoutObject(const LayoutObject&, const IntRect&) const;
+  IntPoint ConvertFromLayoutObject(const LayoutObject&, const IntPoint&) const;
+  IntPoint ConvertToLayoutObject(const LayoutObject&, const IntPoint&) const;
+  LayoutPoint ConvertFromLayoutObject(const LayoutObject&,
+                                      const LayoutPoint&) const;
+  LayoutPoint ConvertToLayoutObject(const LayoutObject&,
                                     const LayoutPoint&) const;
-  LayoutPoint ConvertToLayoutItem(const LayoutItem&, const LayoutPoint&) const;
 
   bool IsFrameViewScrollCorner(LayoutScrollbarPart* scroll_corner) const {
     return scroll_corner_ == scroll_corner;
@@ -1171,6 +1167,8 @@
 
   PaintController* GetPaintController() { return paint_controller_.get(); }
 
+  void LayoutFromRootObject(LayoutObject& root);
+
   LayoutSize size_;
 
   typedef HashSet<scoped_refptr<LayoutEmbeddedObject>> EmbeddedObjectSet;
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
index e8c12aac..7bd4fc3 100644
--- a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
@@ -158,7 +158,7 @@
 
   SetView(RemoteFrameView::Create(this));
 
-  if (!OwnerLayoutItem().IsNull())
+  if (OwnerLayoutObject())
     DeprecatedLocalOwner()->SetEmbeddedContentView(view_);
 }
 
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp b/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
index 63dca7c7..6984c5ea 100644
--- a/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
@@ -106,14 +106,14 @@
 }
 
 void RemoteFrameView::InvalidateRect(const IntRect& rect) {
-  LayoutEmbeddedContentItem layout_item = remote_frame_->OwnerLayoutItem();
-  if (layout_item.IsNull())
+  auto* object = remote_frame_->OwnerLayoutObject();
+  if (!object)
     return;
 
   LayoutRect repaint_rect(rect);
-  repaint_rect.Move(layout_item.BorderLeft() + layout_item.PaddingLeft(),
-                    layout_item.BorderTop() + layout_item.PaddingTop());
-  layout_item.InvalidatePaintRectangle(repaint_rect);
+  repaint_rect.Move(object->BorderLeft() + object->PaddingLeft(),
+                    object->BorderTop() + object->PaddingTop());
+  object->InvalidatePaintRectangle(repaint_rect);
 }
 
 void RemoteFrameView::SetFrameRect(const IntRect& frame_rect) {
diff --git a/third_party/WebKit/Source/core/frame/VisualViewportTest.cpp b/third_party/WebKit/Source/core/frame/VisualViewportTest.cpp
index 96397336..d9404b5 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewportTest.cpp
+++ b/third_party/WebKit/Source/core/frame/VisualViewportTest.cpp
@@ -395,7 +395,7 @@
   NavigateTo("about:blank");
   WebView()->UpdateAllLifecyclePhases();
   main_frame_widget->SetRootGraphicsLayer(
-      frame_view.GetLayoutViewItem().Compositor()->RootGraphicsLayer());
+      frame_view.GetLayoutView()->Compositor()->RootGraphicsLayer());
 
   VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
   EXPECT_FLOAT_SIZE_EQ(FloatSize(320, 240),
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp
index 1fc26d0..ed48ac55 100644
--- a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp
+++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp
@@ -1023,11 +1023,10 @@
 
 PaintLayerCompositor* WebFrameWidgetImpl::Compositor() const {
   LocalFrame* frame = local_root_->GetFrame();
-  if (!frame || !frame->GetDocument() ||
-      frame->GetDocument()->GetLayoutViewItem().IsNull())
+  if (!frame || !frame->GetDocument() || !frame->GetDocument()->GetLayoutView())
     return nullptr;
 
-  return frame->GetDocument()->GetLayoutViewItem().Compositor();
+  return frame->GetDocument()->GetLayoutView()->Compositor();
 }
 
 void WebFrameWidgetImpl::SetRootGraphicsLayer(GraphicsLayer* layer) {
diff --git a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
index 172a5a0..753e3e3 100644
--- a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
@@ -284,12 +284,12 @@
   float SpoolSinglePage(WebCanvas* canvas, int page_number) {
     DispatchEventsForPrintingOnAllFrames();
     if (!GetFrame()->GetDocument() ||
-        GetFrame()->GetDocument()->GetLayoutViewItem().IsNull())
+        !GetFrame()->GetDocument()->GetLayoutView())
       return 0;
 
     GetFrame()->View()->UpdateLifecyclePhasesForPrinting();
     if (!GetFrame()->GetDocument() ||
-        GetFrame()->GetDocument()->GetLayoutViewItem().IsNull())
+        !GetFrame()->GetDocument()->GetLayoutView())
       return 0;
 
     // The page rect gets scaled and translated, so specify the entire
@@ -308,12 +308,12 @@
       const FloatSize& page_size_in_pixels) {
     DispatchEventsForPrintingOnAllFrames();
     if (!GetFrame()->GetDocument() ||
-        GetFrame()->GetDocument()->GetLayoutViewItem().IsNull())
+        !GetFrame()->GetDocument()->GetLayoutView())
       return;
 
     GetFrame()->View()->UpdateLifecyclePhasesForPrinting();
     if (!GetFrame()->GetDocument() ||
-        GetFrame()->GetDocument()->GetLayoutViewItem().IsNull())
+        !GetFrame()->GetDocument()->GetLayoutView())
       return;
 
     ComputePageRects(page_size_in_pixels);
@@ -599,9 +599,9 @@
 }
 
 bool WebLocalFrameImpl::HasVisibleContent() const {
-  LayoutEmbeddedContentItem layout_item = GetFrame()->OwnerLayoutItem();
-  if (!layout_item.IsNull() &&
-      layout_item.Style()->Visibility() != EVisibility::kVisible) {
+  auto* layout_object = GetFrame()->OwnerLayoutObject();
+  if (layout_object &&
+      layout_object->StyleRef().Visibility() != EVisibility::kVisible) {
     return false;
   }
 
diff --git a/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.cpp b/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.cpp
index 5801381..48fae1c 100644
--- a/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.cpp
+++ b/third_party/WebKit/Source/core/geometry/DOMMatrixReadOnly.cpp
@@ -493,8 +493,8 @@
 
   const ComputedStyle& initial_style = ComputedStyle::InitialStyle();
   TransformOperations operations = TransformBuilder::CreateTransformOperations(
-      *value, CSSToLengthConversionData(&initial_style, &initial_style,
-                                        LayoutViewItem(nullptr), 1.0f));
+      *value,
+      CSSToLengthConversionData(&initial_style, &initial_style, nullptr, 1.0f));
 
   if (operations.DependsOnBoxSize()) {
     exception_state.ThrowDOMException(
diff --git a/third_party/WebKit/Source/core/html/HTMLMetaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMetaElement.cpp
index 124ac06..0185d68 100644
--- a/third_party/WebKit/Source/core/html/HTMLMetaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMetaElement.cpp
@@ -32,6 +32,8 @@
 #include "core/html_names.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/loader/HttpEquiv.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
 #include "platform/wtf/text/StringToNumber.h"
 
 namespace blink {
@@ -197,6 +199,10 @@
   if (value < 0)
     return Length();  // auto
 
+  if (document && document->GetPage()) {
+    value =
+        document->GetPage()->GetChromeClient().WindowToViewportScalar(value);
+  }
   return Length(ClampLengthValue(value), kFixed);
 }
 
diff --git a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
index 021974ce..5623a6a 100644
--- a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
@@ -3559,7 +3559,7 @@
   // Cache this in case the player is destroyed before leaving fullscreen.
   in_overlay_fullscreen_video_ = UsesOverlayFullscreenVideo();
   if (in_overlay_fullscreen_video_) {
-    GetDocument().GetLayoutViewItem().Compositor()->SetNeedsCompositingUpdate(
+    GetDocument().GetLayoutView()->Compositor()->SetNeedsCompositingUpdate(
         kCompositingUpdateRebuildTree);
   }
 }
@@ -3573,7 +3573,7 @@
   }
 
   if (in_overlay_fullscreen_video_) {
-    GetDocument().GetLayoutViewItem().Compositor()->SetNeedsCompositingUpdate(
+    GetDocument().GetLayoutView()->Compositor()->SetNeedsCompositingUpdate(
         kCompositingUpdateRebuildTree);
   }
   in_overlay_fullscreen_video_ = false;
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 278a65a3..761bad5 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -275,11 +275,11 @@
   // page.  Furthermore, mousemove events before the first layout should not
   // lead to a premature layout() happening, which could show a flash of white.
   // See also the similar code in Document::performMouseEventHitTest.
-  if (frame_->ContentLayoutItem().IsNull() || !frame_->View() ||
+  if (!frame_->ContentLayoutObject() || !frame_->View() ||
       !frame_->View()->DidFirstLayout())
     return result;
 
-  frame_->ContentLayoutItem().HitTest(result);
+  frame_->ContentLayoutObject()->HitTest(result);
   if (!request.ReadOnly())
     frame_->GetDocument()->UpdateHoverActiveState(request,
                                                   result.InnerElement());
@@ -344,8 +344,8 @@
   if (!view || !view->ShouldSetCursor())
     return;
 
-  LayoutViewItem layout_view_item = view->GetLayoutViewItem();
-  if (layout_view_item.IsNull())
+  auto* layout_view = view->GetLayoutView();
+  if (!layout_view)
     return;
 
   frame_->GetDocument()->UpdateStyleAndLayout();
@@ -355,7 +355,7 @@
   HitTestResult result(request,
                        view->RootFrameToContents(
                            mouse_event_manager_->LastKnownMousePosition()));
-  layout_view_item.HitTest(result);
+  layout_view->HitTest(result);
 
   if (LocalFrame* frame = result.InnerNodeFrame()) {
     EventHandler::OptionalCursor optional_cursor =
@@ -1933,13 +1933,13 @@
   DCHECK(frame_);
   DCHECK(frame_->GetDocument());
 
-  if (LayoutViewItem layout_item = frame_->ContentLayoutItem()) {
+  if (auto* layout_object = frame_->ContentLayoutObject()) {
     if (LocalFrameView* view = frame_->View()) {
       HitTestRequest request(HitTestRequest::kMove);
       HitTestResult result(request,
                            view->RootFrameToContents(
                                mouse_event_manager_->LastKnownMousePosition()));
-      layout_item.HitTest(result);
+      layout_object->HitTest(result);
       frame_->GetDocument()->UpdateHoverActiveState(request,
                                                     result.InnerElement());
     }
diff --git a/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp b/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp
index 5b18387..784676b4 100644
--- a/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandlingUtil.cpp
@@ -21,14 +21,14 @@
     HitTestRequest::HitTestRequestType hit_type) {
   HitTestResult result(HitTestRequest(hit_type), point);
 
-  if (!frame || frame->ContentLayoutItem().IsNull())
+  if (!frame || !frame->ContentLayoutObject())
     return result;
   if (frame->View()) {
     IntRect rect = frame->View()->VisibleContentRect(kIncludeScrollbars);
     if (!rect.Contains(RoundedIntPoint(point)))
       return result;
   }
-  frame->ContentLayoutItem().HitTest(result);
+  frame->ContentLayoutObject()->HitTest(result);
   return result;
 }
 
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.cpp b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
index 317750e7..b0dc8a8 100644
--- a/third_party/WebKit/Source/core/input/MouseEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
@@ -441,10 +441,12 @@
     const HitTestResult& hit_test_result,
     InputDeviceCapabilities* source_capabilities) {
   // If clicking on a frame scrollbar, do not mess up with content focus.
-  if (hit_test_result.GetScrollbar() && !frame_->ContentLayoutItem().IsNull()) {
-    if (hit_test_result.GetScrollbar()->GetScrollableArea() ==
-        frame_->ContentLayoutItem().GetScrollableArea())
-      return WebInputEventResult::kNotHandled;
+  if (auto* layout_view = frame_->ContentLayoutObject()) {
+    if (hit_test_result.GetScrollbar() && frame_->ContentLayoutObject()) {
+      if (hit_test_result.GetScrollbar()->GetScrollableArea() ==
+          layout_view->GetScrollableArea())
+        return WebInputEventResult::kNotHandled;
+    }
   }
 
   // The layout needs to be up to date to determine if an element is focusable.
@@ -863,7 +865,7 @@
   if (mouse_down_may_start_drag_) {
     HitTestRequest request(HitTestRequest::kReadOnly);
     HitTestResult result(request, mouse_down_pos_);
-    frame_->ContentLayoutItem().HitTest(result);
+    frame_->ContentLayoutObject()->HitTest(result);
     Node* node = result.InnerNode();
     if (node) {
       DragController::SelectionDragPolicy selection_drag_policy =
diff --git a/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp b/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp
index 0497e3c..a438d58c 100644
--- a/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp
@@ -34,7 +34,7 @@
       RuntimeEnabledFeatures::TouchpadAndWheelScrollLatchingEnabled();
 
   Document* doc = frame_->GetDocument();
-  if (!doc || doc->GetLayoutViewItem().IsNull())
+  if (!doc || !doc->GetLayoutView())
     return WebInputEventResult::kNotHandled;
 
   LocalFrameView* view = frame_->View();
@@ -119,13 +119,13 @@
 Node* MouseWheelEventManager::FindTargetNode(const WebMouseWheelEvent& event,
                                              const Document* doc,
                                              const LocalFrameView* view) {
-  DCHECK(doc && !doc->GetLayoutViewItem().IsNull() && view);
+  DCHECK(doc && doc->GetLayoutView() && view);
   LayoutPoint v_point =
       view->RootFrameToContents(FlooredIntPoint(event.PositionInRootFrame()));
 
   HitTestRequest request(HitTestRequest::kReadOnly);
   HitTestResult result(request, v_point);
-  doc->GetLayoutViewItem().HitTest(result);
+  doc->GetLayoutView()->HitTest(result);
 
   Node* node = result.InnerNode();
   // Wheel events should not dispatch to text nodes.
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.cpp b/third_party/WebKit/Source/core/input/ScrollManager.cpp
index 0e92dff..39dcd6d 100644
--- a/third_party/WebKit/Source/core/input/ScrollManager.cpp
+++ b/third_party/WebKit/Source/core/input/ScrollManager.cpp
@@ -188,8 +188,8 @@
     node = mouse_press_node;
 
   if ((!node || !node->GetLayoutObject()) && frame_->View() &&
-      !frame_->View()->GetLayoutViewItem().IsNull())
-    node = frame_->View()->GetLayoutViewItem().GetNode();
+      frame_->View()->GetLayoutView())
+    node = frame_->View()->GetLayoutView()->GetNode();
 
   if (!node)
     return false;
@@ -313,7 +313,7 @@
     const WebGestureEvent& gesture_event) {
   Document* document = frame_->GetDocument();
 
-  if (document->GetLayoutViewItem().IsNull())
+  if (!document->GetLayoutView())
     return WebInputEventResult::kNotHandled;
 
   // If there's no layoutObject on the node, send the event to the nearest
@@ -558,7 +558,7 @@
 
   if (!event_target) {
     Document* document = frame_->GetDocument();
-    if (document->GetLayoutViewItem().IsNull())
+    if (!document->GetLayoutView())
       return WebInputEventResult::kNotHandled;
 
     LocalFrameView* view = frame_->View();
@@ -566,7 +566,7 @@
         FlooredIntPoint(gesture_event.PositionInRootFrame()));
     HitTestRequest request(HitTestRequest::kReadOnly);
     HitTestResult result(request, view_point);
-    document->GetLayoutViewItem().HitTest(result);
+    document->GetLayoutView()->HitTest(result);
 
     event_target = result.InnerNode();
 
diff --git a/third_party/WebKit/Source/core/input/TouchActionTest.cpp b/third_party/WebKit/Source/core/input/TouchActionTest.cpp
index 01da42f..1bd07835 100644
--- a/third_party/WebKit/Source/core/input/TouchActionTest.cpp
+++ b/third_party/WebKit/Source/core/input/TouchActionTest.cpp
@@ -224,8 +224,9 @@
   LayoutRect clip_rect(
       LayoutPoint(),
       LayoutSize(frame_view.VisibleContentSize(kExcludeScrollbars)));
-  frame_view.GetLayoutViewItem().MapToVisualRectInAncestorSpace(
-      &frame_view.GetLayoutView()->ContainerForPaintInvalidation(), clip_rect);
+  frame_view.GetLayoutView()->MapToVisualRectInAncestorSpace(
+      &frame_view.GetLayoutView()->ContainerForPaintInvalidation(), clip_rect,
+      0, kDefaultVisualRectFlags);
   return EnclosingIntRect(clip_rect);
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
index ded791e..4ca3d97 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -155,7 +155,7 @@
   top_padding = bottom_padding = (rect.Height() / 2).ToUnsigned();
   HitTestResult result(request, center, top_padding, right_padding,
                        bottom_padding, left_padding);
-  document.GetFrame()->ContentLayoutItem().HitTest(result);
+  document.GetFrame()->ContentLayoutObject()->HitTest(result);
   HeapVector<Member<Element>> elements;
   Node* previous_node = nullptr;
   for (const auto hit_test_result_node : result.ListBasedTestResult()) {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index ecc5427..447386d1 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -1313,7 +1313,7 @@
   HitTestRequest request(HitTestRequest::kMove | HitTestRequest::kReadOnly |
                          HitTestRequest::kAllowChildFrameContent);
   HitTestResult result(request, IntPoint(x, y));
-  document_->GetFrame()->ContentLayoutItem().HitTest(result);
+  document_->GetFrame()->ContentLayoutObject()->HitTest(result);
   if (!include_user_agent_shadow_dom)
     result.SetToShadowHostIfInRestrictedShadowRoot();
   Node* node = result.InnerPossiblyPseudoNode();
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
index 7286ec0f..5530aee 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -335,10 +335,10 @@
       ToLayoutEmbeddedContent(root->GetLayoutObject()).ChildFrameView();
   if (!child_frame_view)
     return;
-  LayoutViewItem child_layout_view_item = child_frame_view->GetLayoutViewItem();
-  if (child_layout_view_item.IsNull())
+  LayoutView* child_layout_view = child_frame_view->GetLayoutView();
+  if (!child_layout_view)
     return;
-  PaintLayerCompositor* child_compositor = child_layout_view_item.Compositor();
+  PaintLayerCompositor* child_compositor = child_layout_view->Compositor();
   if (!child_compositor)
     return;
   BuildLayerIdToNodeIdMap(child_compositor->RootLayer(),
@@ -367,9 +367,9 @@
 }
 
 PaintLayerCompositor* InspectorLayerTreeAgent::GetPaintLayerCompositor() {
-  LayoutViewItem layout_view = inspected_frames_->Root()->ContentLayoutItem();
+  auto* layout_view = inspected_frames_->Root()->ContentLayoutObject();
   PaintLayerCompositor* compositor =
-      layout_view.IsNull() ? nullptr : layout_view.Compositor();
+      layout_view ? layout_view->Compositor() : nullptr;
   return compositor;
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.cpp
index 4f04520..e2a9fd61 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorOverlayAgent.cpp
@@ -98,7 +98,7 @@
   HitTestRequest request(hit_type);
   HitTestResult result(request,
                        frame->View()->RootFrameToContents(point_in_root_frame));
-  frame->ContentLayoutItem().HitTest(result);
+  frame->ContentLayoutObject()->HitTest(result);
   Node* node = result.InnerPossiblyPseudoNode();
   while (node && node->getNodeType() == Node::kTextNode)
     node = node->parentNode();
@@ -1013,7 +1013,7 @@
   }
 
   LocalFrame* frame = frame_impl_->GetFrame();
-  if (!frame || !frame->View() || frame->ContentLayoutItem().IsNull())
+  if (!frame || !frame->View() || !frame->ContentLayoutObject())
     return false;
   Node* node = HoveredNodeForEvent(
       frame, event, event.GetModifiers() & WebInputEvent::kShiftKey);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorSession.h b/third_party/WebKit/Source/core/inspector/InspectorSession.h
index 537ea8a..5330fe1 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorSession.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorSession.h
@@ -68,10 +68,6 @@
       std::unique_ptr<v8_inspector::StringBuffer> message) override;
   void sendNotification(
       std::unique_ptr<v8_inspector::StringBuffer> message) override;
-  // TODO(kozyatinskiy): remove it.
-  void SendProtocolResponse(int call_id,
-                            const v8_inspector::StringView& message) {}
-  void SendProtocolNotification(const v8_inspector::StringView& message) {}
 
   void SendProtocolResponse(int call_id, const String& message);
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index 8850b93e..4b2d9ce 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -4768,11 +4768,14 @@
                                           const InlineBox* marked_box2,
                                           const char* marked_label2,
                                           const LayoutObject* obj) const {
-  ShowLayoutObject();
+  StringBuilder string_blockflow;
+  DumpLayoutObject(string_blockflow);
   for (const RootInlineBox* root = FirstRootBox(); root;
-       root = root->NextRootBox())
-    root->ShowLineTreeAndMark(marked_box1, marked_label1, marked_box2,
-                              marked_label2, obj, 1);
+       root = root->NextRootBox()) {
+    root->DumpLineTreeAndMark(string_blockflow, marked_box1, marked_label1,
+                              marked_box2, marked_label2, obj, 1);
+  }
+  DLOG(INFO) << "\n" << string_blockflow.ToString().Utf8().data();
 }
 
 #endif
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 7d86d45..33e1ac34 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -292,7 +292,12 @@
 
   // Our opaqueness might have changed without triggering layout.
   if (diff.NeedsFullPaintInvalidation()) {
+    // Invalidate self.
+    InvalidateBackgroundObscurationStatus();
     LayoutObject* parent_to_invalidate = Parent();
+    // Also invalidate up to kBackgroundObscurationTestMaxDepth parents.
+    // This constant corresponds to a descendant walk of the same depth;
+    // see ComputeBackgroundIsKnownToBeObscured.
     for (unsigned i = 0;
          i < kBackgroundObscurationTestMaxDepth && parent_to_invalidate; ++i) {
       parent_to_invalidate->InvalidateBackgroundObscurationStatus();
@@ -1921,10 +1926,8 @@
 bool LayoutBox::IntersectsVisibleViewport() const {
   LayoutRect rect = VisualOverflowRect();
   LayoutView* layout_view = View();
-  while (!layout_view->GetFrame()->OwnerLayoutItem().IsNull())
-    layout_view = LayoutAPIShim::LayoutObjectFrom(
-                      layout_view->GetFrame()->OwnerLayoutItem())
-                      ->View();
+  while (layout_view->GetFrame()->OwnerLayoutObject())
+    layout_view = layout_view->GetFrame()->OwnerLayoutObject()->View();
   MapToVisualRectInAncestorSpace(layout_view, rect);
   return rect.Intersects(LayoutRect(
       layout_view->GetFrameView()->GetScrollableArea()->VisibleContentRect()));
diff --git a/third_party/WebKit/Source/core/layout/LayoutEmbeddedContent.cpp b/third_party/WebKit/Source/core/layout/LayoutEmbeddedContent.cpp
index d8016b6..2a2e5c5f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutEmbeddedContent.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutEmbeddedContent.cpp
@@ -135,9 +135,9 @@
     return true;
 
   if (Document* content_document = element->contentDocument()) {
-    LayoutViewItem view_item = content_document->GetLayoutViewItem();
-    if (!view_item.IsNull())
-      return view_item.UsesCompositing();
+    auto* layout_view = content_document->GetLayoutView();
+    if (layout_view)
+      return layout_view->UsesCompositing();
   }
 
   return false;
@@ -190,10 +190,10 @@
             DocumentLifecycle::kCompositingClean);
 
   if (action == kHitTestForeground) {
-    LayoutViewItem child_root_item = frame_view->GetLayoutViewItem();
+    auto* child_layout_view = frame_view->GetLayoutView();
 
     if (VisibleToHitTestRequest(result.GetHitTestRequest()) &&
-        !child_root_item.IsNull()) {
+        child_layout_view) {
       LayoutPoint adjusted_location = accumulated_offset + Location();
       LayoutPoint content_offset = LayoutPoint(BorderLeft() + PaddingLeft(),
                                                BorderTop() + PaddingTop()) -
@@ -207,7 +207,7 @@
 
       // The frame's layout and style must be up to date if we reach here.
       bool is_inside_child_frame =
-          child_root_item.HitTestNoLifecycleUpdate(child_frame_result);
+          child_layout_view->HitTestNoLifecycleUpdate(child_frame_result);
 
       if (result.GetHitTestRequest().ListBased()) {
         result.Append(child_frame_result);
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 558d07a..7151fa5 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -461,8 +461,9 @@
   // If the startLine is the start line of a collapsed track we need to go
   // backwards till we reach a non collapsed track. If we find a non collapsed
   // track we need to add that gap.
+  size_t non_empty_tracks_before_start_line = 0;
   if (start_line && grid.IsEmptyAutoRepeatTrack(direction, start_line)) {
-    size_t non_empty_tracks_before_start_line = start_line;
+    non_empty_tracks_before_start_line = start_line;
     auto begin = grid.AutoRepeatEmptyTracks(direction)->begin();
     for (auto it = begin; *it != start_line; ++it) {
       DCHECK(non_empty_tracks_before_start_line);
@@ -487,8 +488,17 @@
       DCHECK(non_empty_tracks_after_end_line);
       --non_empty_tracks_after_end_line;
     }
-    if (non_empty_tracks_after_end_line)
-      gap_accumulator += gap;
+    if (non_empty_tracks_after_end_line) {
+      // We shouldn't count the gap twice if the span starts and ends
+      // in a collapsed track bewtween two non-empty tracks.
+      if (!non_empty_tracks_before_start_line)
+        gap_accumulator += gap;
+    } else if (non_empty_tracks_before_start_line) {
+      // We shouldn't count the gap if the the span starts and ends in
+      // a collapsed but there isn't non-empty tracks afterwards (it's
+      // at the end of the grid).
+      gap_accumulator -= gap;
+    }
   }
 
   return gap_accumulator;
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index fd889677..fa96e597 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -1118,8 +1118,7 @@
   // frame's LayoutView so that we generate invalidations on the window.
   const LayoutView* layout_view = View();
   while (const LayoutObject* owner_object =
-             LayoutAPIShim::ConstLayoutObjectFrom(
-                 layout_view->GetFrame()->OwnerLayoutItem()))
+             layout_view->GetFrame()->OwnerLayoutObject())
     layout_view = owner_object->View();
 
   DCHECK(layout_view);
@@ -1600,7 +1599,7 @@
     SetNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::kStyleChange);
 }
 
-void LayoutObject::MarkAncestorsForOverflowRecalcIfNeeded() {
+void LayoutObject::MarkContainerChainForOverflowRecalcIfNeeded() {
   LayoutObject* object = this;
   do {
     // Cell and row need to propagate the flag to their containing section and
@@ -1619,7 +1618,7 @@
   SetSelfNeedsOverflowRecalcAfterStyleChange();
   SetMayNeedPaintInvalidation();
   if (!needed_recalc)
-    MarkAncestorsForOverflowRecalcIfNeeded();
+    MarkContainerChainForOverflowRecalcIfNeeded();
 }
 
 DISABLE_CFI_PERF
@@ -1894,7 +1893,7 @@
     // Ditto.
     if (NeedsOverflowRecalcAfterStyleChange() &&
         old_style->GetPosition() != style_->GetPosition())
-      MarkAncestorsForOverflowRecalcIfNeeded();
+      MarkContainerChainForOverflowRecalcIfNeeded();
 
     SetNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::kStyleChange);
   } else if (diff.NeedsPositionedMovementLayout()) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index de7bc2f..ead3910 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -1738,6 +1738,8 @@
   // Returns the bounding box of the visual rects of all fragments.
   LayoutRect FragmentsVisualRectBoundingBox() const;
 
+  void SetNeedsOverflowRecalcAfterStyleChange();
+
   // Painters can use const methods only, except for these explicitly declared
   // methods.
   class CORE_EXPORT MutableForPainting {
@@ -2129,15 +2131,11 @@
   void CheckCounterChanges(const ComputedStyle* old_style,
                            const ComputedStyle* new_style);
 
-  void SetNeedsOverflowRecalcAfterStyleChange();
-
   // Walk up the parent chain and find the first scrolling block to disable
   // scroll anchoring on.
   void SetScrollAnchorDisablingStyleChangedOnAncestor();
 
-  // FIXME: This should be 'markContaingBoxChainForOverflowRecalc when we make
-  // LayoutBox recomputeOverflow-capable. crbug.com/437012 and crbug.com/434700.
-  inline void MarkAncestorsForOverflowRecalcIfNeeded();
+  inline void MarkContainerChainForOverflowRecalcIfNeeded();
 
   inline void MarkAncestorsForPaintInvalidation();
   inline void SetNeedsPaintOffsetAndVisualRectUpdate();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 0716a70..4e9364fa 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -1379,7 +1379,7 @@
   RecalcSectionsIfNeeded();
 
   // Find the section and row to look in
-  unsigned r = cell.RowIndex() + cell.RowSpan() - 1;
+  unsigned r = cell.RowIndex() + cell.ResolvedRowSpan() - 1;
   LayoutTableSection* section = nullptr;
   unsigned r_below = 0;
   if (r < cell.Section()->NumRows() - 1) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
index 975f630..3381d22 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
@@ -947,7 +947,7 @@
 
   // Now check row groups.
   LayoutTableSection* curr_section = Section();
-  if (RowIndex() + RowSpan() >= curr_section->NumRows()) {
+  if (RowIndex() + ResolvedRowSpan() >= curr_section->NumRows()) {
     // (5) Our row group's after border.
     result = ChooseBorder(
         result,
@@ -1087,7 +1087,7 @@
     return;
 
   // Invalidate the rows which will paint the collapsed borders.
-  auto row_span = RowSpan();
+  auto row_span = ResolvedRowSpan();
   for (auto r = RowIndex(); r < RowIndex() + row_span; ++r) {
     if (auto* row = Section()->RowLayoutObjectAt(r))
       row->SetShouldDoFullPaintInvalidation(PaintInvalidationReason::kStyle);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.h b/third_party/WebKit/Source/core/layout/LayoutTableCell.h
index 49eceab9..f5803ed 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCell.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.h
@@ -100,7 +100,7 @@
       return 1;
     return ParseRowSpanFromDOM();
   }
-  unsigned RowSpan() const {
+  unsigned ResolvedRowSpan() const {
     unsigned row_span = ParsedRowSpan();
     if (!row_span) {
       DCHECK(!Section()->NeedsCellRecalc());
@@ -328,8 +328,8 @@
     return other && RowIndex() == other->RowIndex();
   }
   bool EndsAtSameRow(const LayoutTableCell* other) const {
-    return other &&
-           RowIndex() + RowSpan() == other->RowIndex() + other->RowSpan();
+    return other && RowIndex() + ResolvedRowSpan() ==
+                        other->RowIndex() + other->ResolvedRowSpan();
   }
 
   void SetIsSpanningCollapsedRow(bool spanningCollapsedRow) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp
index 6b45161f..2d7cdc4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCellTest.cpp
@@ -98,12 +98,12 @@
 
 TEST_F(LayoutTableCellTest, ResetRowspanIfTooBig) {
   SetBodyInnerHTML("<table><td id='cell' rowspan='70000'></td></table>");
-  ASSERT_EQ(GetCellByElementId("cell")->RowSpan(), 65534U);
+  ASSERT_EQ(GetCellByElementId("cell")->ResolvedRowSpan(), 65534U);
 }
 
 TEST_F(LayoutTableCellTest, DoNotResetRowspanJustBelowBoundary) {
   SetBodyInnerHTML("<table><td id='cell' rowspan='65534'></td></table>");
-  ASSERT_EQ(GetCellByElementId("cell")->RowSpan(), 65534U);
+  ASSERT_EQ(GetCellByElementId("cell")->ResolvedRowSpan(), 65534U);
 }
 
 TEST_F(LayoutTableCellTest,
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
index b43d1f8..a9abe265 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
@@ -109,7 +109,7 @@
           continue;
         unsigned rowIndex = RowIndex();
         unsigned spanStart = cell->RowIndex();
-        unsigned spanEnd = spanStart + cell->RowSpan();
+        unsigned spanEnd = spanStart + cell->ResolvedRowSpan();
         if (spanStart <= rowIndex && rowIndex <= spanEnd)
           cell->SetCellChildrenNeedLayout();
       }
@@ -300,7 +300,7 @@
   // rows, the row's visual rect should be expanded to cover the cell.
   // Here don't check background existence to avoid requirement to invalidate
   // overflow on change of background existence.
-  if (cell->RowSpan() > 1) {
+  if (cell->ResolvedRowSpan() > 1) {
     LayoutRect cell_background_rect = cell->FrameRect();
     cell_background_rect.MoveBy(-Location());
     AddSelfVisualOverflow(cell_background_rect);
@@ -323,7 +323,7 @@
 
   // Should propagate cell's overflow to row if the cell has row span or has
   // overflow.
-  if (cell->RowSpan() == 1 && !cell->HasOverflowModel())
+  if (cell->ResolvedRowSpan() == 1 && !cell->HasOverflowModel())
     return;
 
   LayoutRect cell_visual_overflow_rect =
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
index 1dea33f..2bab6b5 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -53,7 +53,7 @@
 void LayoutTableSection::TableGridRow::UpdateLogicalHeightForCell(
     const LayoutTableCell* cell) {
   // We ignore height settings on rowspan cells.
-  if (cell->RowSpan() != 1)
+  if (cell->ResolvedRowSpan() != 1)
     return;
 
   Length cell_logical_height = cell->StyleRef().LogicalHeight();
@@ -238,7 +238,7 @@
     return;
 
   DCHECK(cell);
-  unsigned r_span = cell->RowSpan();
+  unsigned r_span = cell->ResolvedRowSpan();
   unsigned c_span = cell->ColSpan();
   if (r_span > 1 || c_span > 1)
     has_spanning_cells_ = true;
@@ -306,7 +306,7 @@
     if (!grid_cell.HasCells())
       return false;
 
-    if (grid_cell.Cells()[0]->RowSpan() == 1)
+    if (grid_cell.Cells()[0]->ResolvedRowSpan() == 1)
       return false;
   }
 
@@ -316,7 +316,7 @@
 void LayoutTableSection::PopulateSpanningRowsHeightFromCell(
     LayoutTableCell* cell,
     struct SpanningRowsHeight& spanning_rows_height) {
-  const unsigned row_span = cell->RowSpan();
+  const unsigned row_span = cell->ResolvedRowSpan();
   const unsigned row_index = cell->RowIndex();
 
   spanning_rows_height.spanning_cell_height_ignoring_border_spacing =
@@ -353,7 +353,7 @@
   if (!extra_row_spanning_height || !total_percent)
     return;
 
-  const unsigned row_span = cell->RowSpan();
+  const unsigned row_span = cell->ResolvedRowSpan();
   const unsigned row_index = cell->RowIndex();
   float percent = std::min(total_percent, 100.0f);
   const int table_height = row_pos_[grid_.size()] + extra_row_spanning_height;
@@ -413,7 +413,7 @@
   if (!extra_row_spanning_height || !total_percent)
     return;
 
-  const unsigned row_span = cell->RowSpan();
+  const unsigned row_span = cell->ResolvedRowSpan();
   const unsigned row_index = cell->RowIndex();
   double remainder = 0;
 
@@ -441,7 +441,7 @@
   if (!extra_row_spanning_height || !total_auto_rows_height)
     return;
 
-  const unsigned row_span = cell->RowSpan();
+  const unsigned row_span = cell->ResolvedRowSpan();
   const unsigned row_index = cell->RowIndex();
   int accumulated_position_increase = 0;
   double remainder = 0;
@@ -471,7 +471,7 @@
   if (!extra_row_spanning_height || !total_remaining_rows_height)
     return;
 
-  const unsigned row_span = cell->RowSpan();
+  const unsigned row_span = cell->ResolvedRowSpan();
   const unsigned row_index = cell->RowIndex();
   int accumulated_position_increase = 0;
   double remainder = 0;
@@ -497,8 +497,8 @@
 static bool CellIsFullyIncludedInOtherCell(const LayoutTableCell* cell1,
                                            const LayoutTableCell* cell2) {
   return (cell1->RowIndex() >= cell2->RowIndex() &&
-          (cell1->RowIndex() + cell1->RowSpan()) <=
-              (cell2->RowIndex() + cell2->RowSpan()));
+          (cell1->RowIndex() + cell1->ResolvedRowSpan()) <=
+              (cell2->RowIndex() + cell2->ResolvedRowSpan()));
 }
 
 // To avoid unneeded extra height distributions, we apply the following sorting
@@ -509,7 +509,7 @@
   // Sorting bigger height cell first if cells are at same index with same span
   // because we will skip smaller height cell to distribute it's extra height.
   if (cell1->RowIndex() == cell2->RowIndex() &&
-      cell1->RowSpan() == cell2->RowSpan())
+      cell1->ResolvedRowSpan() == cell2->ResolvedRowSpan())
     return (cell1->LogicalHeightForRowSizing() >
             cell2->LogicalHeightForRowSizing());
   // Sorting inner most cell first because if inner spanning cell'e extra height
@@ -540,10 +540,10 @@
   for (const auto& row_span_cell : grid_[row].grid_cells) {
     DCHECK(row_span_cell.HasCells());
     LayoutTableCell* cell = row_span_cell.Cells()[0];
-    DCHECK_GE(cell->RowSpan(), 2u);
+    DCHECK_GE(cell->ResolvedRowSpan(), 2u);
 
     const unsigned cell_row_index = cell->RowIndex();
-    const unsigned cell_row_span = cell->RowSpan();
+    const unsigned cell_row_span = cell->ResolvedRowSpan();
 
     // As we are going from the top of the table to the bottom to calculate the
     // row heights for rows that only contain spanning cells and all previous
@@ -590,7 +590,7 @@
   DCHECK(spanning_rows_height.row_height.size());
 
   int accumulated_position_increase = 0;
-  const unsigned row_span = cell->RowSpan();
+  const unsigned row_span = cell->ResolvedRowSpan();
   const unsigned row_index = cell->RowIndex();
 
   DCHECK_EQ(row_span, spanning_rows_height.row_height.size());
@@ -644,7 +644,7 @@
 
     unsigned row_index = cell->RowIndex();
 
-    unsigned row_span = cell->RowSpan();
+    unsigned row_span = cell->ResolvedRowSpan();
 
     unsigned spanning_cell_end_index = row_index + row_span;
     unsigned last_spanning_cell_end_index = last_row_index + last_row_span;
@@ -799,7 +799,7 @@
     grid_[row].baseline = std::max(grid_[row].baseline, baseline_position);
 
     LayoutUnit cell_start_row_baseline_descent;
-    if (cell->RowSpan() == 1) {
+    if (cell->ResolvedRowSpan() == 1) {
       baseline_descent =
           std::max(baseline_descent,
                    cell->LogicalHeightForRowSizing() - baseline_position);
@@ -886,14 +886,14 @@
           // we'll stay in this mode until we get to a row where we're past all
           // rowspanned cells that we encountered while in this mode.
           DCHECK(state.IsPaginated());
-          unsigned row_index_below_cell = r + cell->RowSpan();
+          unsigned row_index_below_cell = r + cell->ResolvedRowSpan();
           index_of_first_stretchable_row =
               std::max(index_of_first_stretchable_row, row_index_below_cell);
-        } else if (cell->RowSpan() > 1) {
+        } else if (cell->ResolvedRowSpan() > 1) {
           DCHECK(!row_span_cells.Contains(cell));
 
           cell->SetIsSpanningCollapsedRow(false);
-          unsigned end_row = cell->RowSpan() + r;
+          unsigned end_row = cell->ResolvedRowSpan() + r;
           for (unsigned spanning = r; spanning < end_row; spanning++) {
             if (RowHasVisibilityCollapse(spanning)) {
               cell->SetIsSpanningCollapsedRow(true);
@@ -910,7 +910,7 @@
           cell->ForceChildLayout();
         }
 
-        if (cell->RowSpan() == 1)
+        if (cell->ResolvedRowSpan() == 1)
           row_pos_[r + 1] = std::max(
               row_pos_[r + 1], row_pos_[r] + cell->LogicalHeightForRowSizing());
 
@@ -1210,7 +1210,7 @@
 
       int r_height;
       int row_logical_top;
-      unsigned row_span = std::max(1U, cell->RowSpan());
+      unsigned row_span = std::max(1U, cell->ResolvedRowSpan());
       unsigned end_row_index = std::min(r + row_span, total_rows) - 1;
       LayoutTableRow* last_row_object = grid_[end_row_index].row;
       if (last_row_object && row) {
@@ -1241,7 +1241,7 @@
       // Calculate total collapsed height affecting one cell.
       int collapsed_height = 0;
       if (is_any_row_collapsed_) {
-        unsigned end_row = cell->RowSpan() + r;
+        unsigned end_row = cell->ResolvedRowSpan() + r;
         for (unsigned spanning = r; spanning < end_row; spanning++) {
           collapsed_height += row_collapsed_height_[spanning];
         }
@@ -1663,7 +1663,7 @@
       // For rowspan, "the value zero means that the cell is to span all the
       // remaining rows in the row group." Calculate the size of the full
       // row grid now so that we can use it to count the remaining rows in
-      // RowSpan().
+      // ResolvedRowSpan().
       if (!cell->ParsedRowSpan() && !resized_grid) {
         unsigned c_row = row->RowIndex() + 1;
         for (LayoutTableRow* remaining_row = row; remaining_row;
@@ -1937,7 +1937,7 @@
     const LayoutTableCell* cell = grid_cell.PrimaryCell();
     if (!cell || grid_cell.InColSpan())
       continue;
-    unsigned row_span = cell->RowSpan();
+    unsigned row_span = cell->ResolvedRowSpan();
     if (row_span == 1) {
       logical_height =
           std::max(logical_height, cell->LogicalHeightForRowSizing());
diff --git a/third_party/WebKit/Source/core/layout/LayoutTestHelper.h b/third_party/WebKit/Source/core/layout/LayoutTestHelper.h
index 9549344..805fe25 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTestHelper.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTestHelper.h
@@ -83,8 +83,7 @@
   void TearDown() override;
 
   LayoutView& GetLayoutView() const {
-    return *ToLayoutView(LayoutAPIShim::LayoutObjectFrom(
-        GetDocument().View()->GetLayoutViewItem()));
+    return *GetDocument().View()->GetLayoutView();
   }
 
   Document& ChildDocument() {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
index d2586db..270876f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
@@ -260,7 +260,7 @@
   if (o.IsTableCell()) {
     const LayoutTableCell& c = ToLayoutTableCell(o);
     ts << " [r=" << c.RowIndex() << " c=" << c.AbsoluteColumnIndex()
-       << " rs=" << c.RowSpan() << " cs=" << c.ColSpan() << "]";
+       << " rs=" << c.ResolvedRowSpan() << " cs=" << c.ColSpan() << "]";
   }
 
   if (o.IsDetailsMarker()) {
@@ -509,10 +509,9 @@
   if (o.IsLayoutEmbeddedContent()) {
     LocalFrameView* frame_view = ToLayoutEmbeddedContent(o).ChildFrameView();
     if (frame_view) {
-      LayoutViewItem root_item = frame_view->GetLayoutViewItem();
-      if (!root_item.IsNull()) {
-        root_item.UpdateStyleAndLayout();
-        if (auto* layer = root_item.Layer()) {
+      if (auto* layout_view = frame_view->GetLayoutView()) {
+        layout_view->GetDocument().UpdateStyleAndLayout();
+        if (auto* layer = layout_view->Layer()) {
           LayoutTreeAsText::WriteLayers(
               ts, layer, layer, layer->RectIgnoringNeedsPositionUpdate(),
               indent + 1, behavior);
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.cpp b/third_party/WebKit/Source/core/layout/LayoutView.cpp
index 8dbda507..212f7a2 100644
--- a/third_party/WebKit/Source/core/layout/LayoutView.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutView.cpp
@@ -189,9 +189,9 @@
 
 void LayoutView::ClearHitTestCache() {
   hit_test_cache_->Clear();
-  LayoutEmbeddedContentItem frame_layout_item = GetFrame()->OwnerLayoutItem();
-  if (!frame_layout_item.IsNull())
-    frame_layout_item.View().ClearHitTestCache();
+  auto* object = GetFrame()->OwnerLayoutObject();
+  if (object)
+    object->View()->ClearHitTestCache();
 }
 
 void LayoutView::ComputeLogicalHeight(
@@ -364,9 +364,8 @@
     return;
 
   if (mode & kTraverseDocumentBoundaries) {
-    LayoutEmbeddedContentItem parent_doc_layout_item =
-        GetFrame()->OwnerLayoutItem();
-    if (!parent_doc_layout_item.IsNull()) {
+    auto* parent_doc_layout_object = GetFrame()->OwnerLayoutObject();
+    if (parent_doc_layout_object) {
       if (!(mode & kInputIsInFrameCoordinates)) {
         transform_state.Move(
             LayoutSize(-GetFrame()->View()->GetScrollOffset()));
@@ -375,10 +374,10 @@
         mode &= ~kInputIsInFrameCoordinates;
       }
 
-      transform_state.Move(parent_doc_layout_item.ContentBoxOffset());
+      transform_state.Move(parent_doc_layout_object->ContentBoxOffset());
 
-      parent_doc_layout_item.MapLocalToAncestor(ancestor, transform_state,
-                                                mode);
+      parent_doc_layout_object->MapLocalToAncestor(ancestor, transform_state,
+                                                   mode);
     } else {
       GetFrameView()->ApplyTransformForTopFrameSpace(transform_state);
     }
@@ -392,9 +391,7 @@
   LayoutObject* container = nullptr;
 
   if (geometry_map.GetMapCoordinatesFlags() & kTraverseDocumentBoundaries) {
-    if (LayoutEmbeddedContent* parent_doc_layout_object =
-            ToLayoutEmbeddedContent(LayoutAPIShim::LayoutObjectFrom(
-                GetFrame()->OwnerLayoutItem()))) {
+    if (auto* parent_doc_layout_object = GetFrame()->OwnerLayoutObject()) {
       offset = -LayoutSize(frame_view_->GetScrollOffset());
       offset += parent_doc_layout_object->ContentBoxOffset();
       container = parent_doc_layout_object;
@@ -422,9 +419,7 @@
                                     TransformState& transform_state,
                                     MapCoordinatesFlags mode) const {
   if (this != ancestor && (mode & kTraverseDocumentBoundaries)) {
-    if (LayoutEmbeddedContent* parent_doc_layout_object =
-            ToLayoutEmbeddedContent(LayoutAPIShim::LayoutObjectFrom(
-                GetFrame()->OwnerLayoutItem()))) {
+    if (auto* parent_doc_layout_object = GetFrame()->OwnerLayoutObject()) {
       // A LayoutView is a containing block for fixed-position elements, so
       // don't carry this state across frames.
       parent_doc_layout_object->MapAncestorToLocal(ancestor, transform_state,
diff --git a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
index d0ae6aff..8a4f08b 100644
--- a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
+++ b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
@@ -560,9 +560,9 @@
   if (!page_info_.setting_enabled_ || document_->Printing()) {
     page_info_.page_needs_autosizing_ = false;
   } else {
-    LayoutViewItem layout_view_item = document_->GetLayoutViewItem();
+    auto* layout_view = document_->GetLayoutView();
     bool horizontal_writing_mode =
-        IsHorizontalWritingMode(layout_view_item.Style()->GetWritingMode());
+        IsHorizontalWritingMode(layout_view->StyleRef().GetWritingMode());
 
     // FIXME: With out-of-process iframes, the top frame can be remote and
     // doesn't have sizing information. Just return if this is the case.
@@ -594,8 +594,7 @@
              ->GetViewportDescription()
              .IsSpecifiedByAuthor()) {
       page_info_.device_scale_adjustment_ =
-          document_->GetPage()->GetChromeClient().WindowToViewportScalar(
-              document_->GetSettings()->GetDeviceScaleAdjustment());
+          document_->GetSettings()->GetDeviceScaleAdjustment();
     } else {
       page_info_.device_scale_adjustment_ = 1.0f;
     }
@@ -638,8 +637,7 @@
 }
 
 void TextAutosizer::ResetMultipliers() {
-  LayoutObject* layout_object =
-      LayoutAPIShim::LayoutObjectFrom(document_->GetLayoutViewItem());
+  LayoutObject* layout_object = document_->GetLayoutView();
   while (layout_object) {
     if (const ComputedStyle* style = layout_object->Style()) {
       if (style->TextAutosizingMultiplier() != 1)
diff --git a/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp b/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp
index 1d9897e..ffc8c6c 100644
--- a/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp
+++ b/third_party/WebKit/Source/core/layout/TextAutosizerTest.cpp
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "core/frame/LocalFrame.h"
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutTestHelper.h"
+#include "core/layout/TextAutosizer.h"
 #include "core/loader/EmptyClients.h"
 #include "platform/PlatformFrameView.h"
 #include "platform/geometry/IntRect.h"
@@ -41,6 +43,13 @@
                         (TextAutosizerClient::Create()));
     return client;
   }
+  void set_device_scale_factor(float device_scale_factor) {
+    GetTextAutosizerClient().set_device_scale_factor(device_scale_factor);
+
+    // This fake ChromeClient cannot update device scale factor (DSF). We apply
+    // DSF to the zoom factor manually.
+    GetDocument().GetFrame()->SetPageZoomFactor(device_scale_factor);
+  }
 
  private:
   void SetUp() override {
@@ -938,10 +947,8 @@
 }
 
 TEST_F(TextAutosizerTest, ScaledbyDSF) {
-  GetTextAutosizerClient().set_device_scale_factor(1.f);
-  // Change setting triggers updating device scale factor
-  GetDocument().GetSettings()->SetTextAutosizingWindowSizeOverride(
-      IntSize(400, 300));
+  const float device_scale = 3;
+  set_device_scale_factor(device_scale);
   SetBodyInnerHTML(R"HTML(
     <style>
       html { font-size: 16px; }
@@ -960,32 +967,14 @@
       </div>
     </body>
   )HTML");
-
   Element* target = GetDocument().getElementById("target");
   // (specified font-size = 16px) * (thread flow layout width = 800px) /
-  // (window width = 400px) = 32px.
-  EXPECT_FLOAT_EQ(32.0f,
-                  target->GetLayoutObject()->Style()->ComputedFontSize());
-
-  const float device_scale = 3.5f;
-  GetTextAutosizerClient().set_device_scale_factor(device_scale);
-  // Change setting triggers updating device scale factor
-  GetDocument().GetSettings()->SetTextAutosizingWindowSizeOverride(
-      IntSize(200, 150));
-  GetDocument().View()->UpdateAllLifecyclePhases();
-
-  // (specified font-size = 16px) * (thread flow layout width = 800px) /
-  // (window width = 200px) * (device scale factor) = 64px * device_scale.
-  EXPECT_FLOAT_EQ(64.0f * device_scale,
+  // (window width = 320px) * (device scale factor) = 40px * device_scale.
+  EXPECT_FLOAT_EQ(40.0f * device_scale,
                   target->GetLayoutObject()->Style()->ComputedFontSize());
 }
 
-TEST_F(TextAutosizerTest, ClusterHasEnoughTextToAutosizeForZoomDSF) {
-  GetTextAutosizerClient().set_device_scale_factor(1.f);
-  // Change setting triggers updating device scale factor
-  GetDocument().GetSettings()->SetTextAutosizingWindowSizeOverride(
-      IntSize(800, 600));
-  GetDocument().GetSettings()->SetAccessibilityFontScaleFactor(4);
+TEST_F(TextAutosizerTest, ClusterHasNotEnoughTextToAutosizeForZoomDSF) {
   SetBodyInnerHTML(R"HTML(
     <style>
       html { font-size: 8px; }
@@ -999,24 +988,48 @@
       </div>
     </body>
   )HTML");
-
   Element* target = GetDocument().getElementById("target");
   // ClusterHasEnoughTextToAutosize() returns false because
   // minimum_text_length_to_autosize < length. Thus, ClusterMultiplier()
   // returns 1 (not multiplied by the accessibility font scale factor).
   // computed font-size = specified font-size = 8px.
   EXPECT_FLOAT_EQ(8.0f, target->GetLayoutObject()->Style()->ComputedFontSize());
+}
 
-  GetTextAutosizerClient().set_device_scale_factor(3);
-  // Change setting triggers updating device scale factor
-  GetDocument().GetSettings()->SetAccessibilityFontScaleFactor(2);
-  GetDocument().View()->UpdateAllLifecyclePhases();
-
-  // (accessibility font scale factor = 2) * (specified font-size = 8px) *
-  // (device scale factor = 3) = 48.
+// TODO(jaebaek): Unit tests ClusterHasNotEnoughTextToAutosizeForZoomDSF and
+// ClusterHasEnoughTextToAutosizeForZoomDSF must be updated.
+// The return value of TextAutosizer::ClusterHasEnoughTextToAutosize() must not
+// be the same regardless of DSF. In real world
+// TextAutosizer::ClusterHasEnoughTextToAutosize(),
+// minimum_text_length_to_autosize is in physical pixel scale. However, in
+// these unit tests, it is in DIP scale, which makes
+// ClusterHasEnoughTextToAutosizeForZoomDSF not fail. We need a trick to update
+// the minimum_text_length_to_autosize in these unit test and check the return
+// value change of TextAutosizer::ClusterHasEnoughTextToAutosize() depending on
+// the length of text even when DSF is not 1 (e.g., letting DummyPageHolder
+// update the view size according to the change of DSF).
+TEST_F(TextAutosizerTest, ClusterHasEnoughTextToAutosizeForZoomDSF) {
+  const float device_scale = 3;
+  set_device_scale_factor(device_scale);
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      html { font-size: 8px; }
+    </style>
+    <body>
+      <div id='target'>
+        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed
+        do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+        Ut enim ad minim veniam, quis nostrud exercitation ullamco
+        laboris nisi ut aliquip ex ea commodo consequat.
+      </div>
+    </body>
+  )HTML");
+  Element* target = GetDocument().getElementById("target");
+  // (specified font-size = 8px) * (thread flow layout width = 800px) /
+  // (window width = 320px) * (device scale factor) = 20px * device_scale.
   // ClusterHasEnoughTextToAutosize() returns true and both accessibility font
   // scale factor and device scale factor are multiplied.
-  EXPECT_FLOAT_EQ(48.0f,
+  EXPECT_FLOAT_EQ(20.0f * device_scale,
                   target->GetLayoutObject()->Style()->ComputedFontSize());
 }
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/TracedLayoutObject.cpp b/third_party/WebKit/Source/core/layout/TracedLayoutObject.cpp
index 58c32f9..903ce10 100644
--- a/third_party/WebKit/Source/core/layout/TracedLayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/TracedLayoutObject.cpp
@@ -75,8 +75,8 @@
       const LayoutTableCell& c = ToLayoutTableCell(object);
       traced_value->SetDouble("row", c.RowIndex());
       traced_value->SetDouble("col", c.AbsoluteColumnIndex());
-      if (c.RowSpan() != 1)
-        traced_value->SetDouble("rowSpan", c.RowSpan());
+      if (c.ResolvedRowSpan() != 1)
+        traced_value->SetDouble("rowSpan", c.ResolvedRowSpan());
       if (c.ColSpan() != 1)
         traced_value->SetDouble("colSpan", c.ColSpan());
     } else {
diff --git a/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h b/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h
index 5f7094b..2e0cbe7 100644
--- a/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h
+++ b/third_party/WebKit/Source/core/layout/api/LayoutViewItem.h
@@ -10,8 +10,6 @@
 
 namespace blink {
 
-class PaintLayerCompositor;
-
 class LayoutViewItem : public LayoutBlockItem {
  public:
   explicit LayoutViewItem(LayoutView* layout_view)
@@ -25,56 +23,18 @@
 
   LayoutViewItem() {}
 
-  bool UsesCompositing() const { return ToView()->UsesCompositing(); }
-
-  PaintLayerCompositor* Compositor() { return ToView()->Compositor(); }
-
-  IntRect DocumentRect() const { return ToView()->DocumentRect(); }
-
-  LayoutRect ViewRect() const { return ToView()->ViewRect(); }
-
-  IntSize GetLayoutSize(
-      IncludeScrollbarsInRect scrollbars = kExcludeScrollbars) const {
-    return ToView()->GetLayoutSize(scrollbars);
-  }
-
-  LayoutRect OverflowClipRect(const LayoutPoint& location) const {
-    return ToView()->OverflowClipRect(location);
-  }
-
   bool HitTest(HitTestResult& result) { return ToView()->HitTest(result); }
 
   bool HitTestNoLifecycleUpdate(HitTestResult& result) {
     return ToView()->HitTestNoLifecycleUpdate(result);
   }
 
-  //    bool hitTest(HitTestResult&);
-  //    bool hitTestNoLifecycleUpdate(HitTestResult&);
-
   unsigned HitTestCount() const { return ToView()->HitTestCount(); }
 
   unsigned HitTestCacheHits() const { return ToView()->HitTestCacheHits(); }
 
   void ClearHitTestCache() { ToView()->ClearHitTestCache(); }
 
-  void InvalidatePaintForViewAndCompositedLayers() {
-    ToView()->InvalidatePaintForViewAndCompositedLayers();
-  }
-
-  int ViewHeight(
-      IncludeScrollbarsInRect scrollbar_inclusion = kExcludeScrollbars) const {
-    return ToView()->ViewHeight(scrollbar_inclusion);
-  }
-
-  int ViewWidth(
-      IncludeScrollbarsInRect scrollbar_inclusion = kExcludeScrollbars) const {
-    return ToView()->ViewWidth(scrollbar_inclusion);
-  }
-
-  FloatSize ViewportSizeForViewportUnits() const {
-    return ToView()->ViewportSizeForViewportUnits();
-  }
-
   void UpdateCounters() { ToView()->UpdateCounters(); }
 
  private:
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
index 8c535730..5991a42 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
@@ -113,35 +113,39 @@
   GetLineLayoutItem().ContainingBlock().ShowLineTreeAndMark(this, "*");
 }
 
-void InlineBox::ShowLineTreeAndMark(const InlineBox* marked_box1,
+void InlineBox::DumpLineTreeAndMark(StringBuilder& string_builder,
+                                    const InlineBox* marked_box1,
                                     const char* marked_label1,
                                     const InlineBox* marked_box2,
                                     const char* marked_label2,
                                     const LayoutObject* obj,
                                     int depth) const {
-  int printed_characters = 0;
+  StringBuilder string_inlinebox;
   if (this == marked_box1)
-    printed_characters += fprintf(stderr, "%s", marked_label1);
+    string_inlinebox.Append(marked_label1);
   if (this == marked_box2)
-    printed_characters += fprintf(stderr, "%s", marked_label2);
+    string_inlinebox.Append(marked_label2);
   if (GetLineLayoutItem().IsEqual(obj))
-    printed_characters += fprintf(stderr, "*");
-  for (; printed_characters < depth * 2; printed_characters++)
-    fputc(' ', stderr);
+    string_inlinebox.Append("*");
+  while ((int)string_inlinebox.length() < (depth * 2))
+    string_inlinebox.Append(" ");
 
-  ShowBox(printed_characters);
+  DumpBox(string_inlinebox);
+  string_builder.Append('\n');
+  string_builder.Append(string_inlinebox);
 }
 
-void InlineBox::ShowBox(int printed_characters) const {
-  printed_characters += fprintf(stderr, "%s %p", BoxName(), this);
-  for (; printed_characters < kShowTreeCharacterOffset; printed_characters++)
-    fputc(' ', stderr);
-  fprintf(stderr, "\t%s %p {pos=%g,%g size=%g,%g} baseline=%i/%i\n",
-          GetLineLayoutItem().DecoratedName().Ascii().data(),
-          GetLineLayoutItem().DebugPointer(), X().ToFloat(), Y().ToFloat(),
-          Width().ToFloat(), Height().ToFloat(),
-          BaselinePosition(kAlphabeticBaseline).ToInt(),
-          BaselinePosition(kIdeographicBaseline).ToInt());
+void InlineBox::DumpBox(StringBuilder& string_inlinebox) const {
+  string_inlinebox.Append(String::Format("%s %p", BoxName(), this));
+  while (string_inlinebox.length() < kShowTreeCharacterOffset)
+    string_inlinebox.Append(" ");
+  string_inlinebox.Append(
+      String::Format("\t%s %p {pos=%g,%g size=%g,%g} baseline=%i/%i",
+                     GetLineLayoutItem().DecoratedName().Ascii().data(),
+                     GetLineLayoutItem().DebugPointer(), X().ToFloat(),
+                     Y().ToFloat(), Width().ToFloat(), Height().ToFloat(),
+                     BaselinePosition(kAlphabeticBaseline).ToInt(),
+                     BaselinePosition(kIdeographicBaseline).ToInt()));
 }
 #endif
 
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.h b/third_party/WebKit/Source/core/layout/line/InlineBox.h
index fa138360..ac65ae85 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.h
@@ -124,8 +124,9 @@
   void ShowTreeForThis() const;
   void ShowLineTreeForThis() const;
 
-  virtual void ShowBox(int = 0) const;
-  virtual void ShowLineTreeAndMark(const InlineBox* = nullptr,
+  virtual void DumpBox(StringBuilder&) const;
+  virtual void DumpLineTreeAndMark(StringBuilder&,
+                                   const InlineBox* = nullptr,
                                    const char* = nullptr,
                                    const InlineBox* = nullptr,
                                    const char* = nullptr,
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index 757064f2..b013f46 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -1691,17 +1691,19 @@
 
 #ifndef NDEBUG
 
-void InlineFlowBox::ShowLineTreeAndMark(const InlineBox* marked_box1,
+void InlineFlowBox::DumpLineTreeAndMark(StringBuilder& string_builder,
+                                        const InlineBox* marked_box1,
                                         const char* marked_label1,
                                         const InlineBox* marked_box2,
                                         const char* marked_label2,
                                         const LayoutObject* obj,
                                         int depth) const {
-  InlineBox::ShowLineTreeAndMark(marked_box1, marked_label1, marked_box2,
-                                 marked_label2, obj, depth);
-  for (const InlineBox* box = FirstChild(); box; box = box->NextOnLine())
-    box->ShowLineTreeAndMark(marked_box1, marked_label1, marked_box2,
-                             marked_label2, obj, depth + 1);
+  InlineBox::DumpLineTreeAndMark(string_builder, marked_box1, marked_label1,
+                                 marked_box2, marked_label2, obj, depth);
+  for (const InlineBox* box = FirstChild(); box; box = box->NextOnLine()) {
+    box->DumpLineTreeAndMark(string_builder, marked_box1, marked_label1,
+                             marked_box2, marked_label2, obj, depth + 1);
+  }
 }
 
 #endif
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
index 31a59cd..65c685ea 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
@@ -83,7 +83,8 @@
 #endif
 
 #ifndef NDEBUG
-  void ShowLineTreeAndMark(const InlineBox* = nullptr,
+  void DumpLineTreeAndMark(StringBuilder&,
+                           const InlineBox* = nullptr,
                            const char* = nullptr,
                            const InlineBox* = nullptr,
                            const char* = nullptr,
diff --git a/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp
index cb4312d..c496626 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineTextBox.cpp
@@ -779,22 +779,21 @@
 
 #ifndef NDEBUG
 
-void InlineTextBox::ShowBox(int printed_characters) const {
+void InlineTextBox::DumpBox(StringBuilder& string_inlinetextbox) const {
   String value = GetText();
   value.Replace('\\', "\\\\");
   value.Replace('\n', "\\n");
-  printed_characters += fprintf(stderr, "%s %p", BoxName(), this);
-  for (; printed_characters < kShowTreeCharacterOffset; printed_characters++)
-    fputc(' ', stderr);
+  string_inlinetextbox.Append(String::Format("%s %p", BoxName(), this));
+  while (string_inlinetextbox.length() < kShowTreeCharacterOffset)
+    string_inlinetextbox.Append(" ");
   const LineLayoutText obj = GetLineLayoutItem();
-  printed_characters =
-      fprintf(stderr, "\t%s %p", obj.GetName(), obj.DebugPointer());
+  string_inlinetextbox.Append(
+      String::Format("\t%s %p", obj.GetName(), obj.DebugPointer()));
   const int kLayoutObjectCharacterOffset = 75;
-  for (; printed_characters < kLayoutObjectCharacterOffset;
-       printed_characters++)
-    fputc(' ', stderr);
-  fprintf(stderr, "(%d,%d) \"%s\"\n", Start(), Start() + Len(),
-          value.Utf8().data());
+  while (string_inlinetextbox.length() < kLayoutObjectCharacterOffset)
+    string_inlinetextbox.Append(" ");
+  string_inlinetextbox.Append(String::Format(
+      "(%d,%d) \"%s\"", Start(), Start() + Len(), value.Utf8().data()));
 }
 
 #endif
diff --git a/third_party/WebKit/Source/core/layout/line/InlineTextBox.h b/third_party/WebKit/Source/core/layout/line/InlineTextBox.h
index 9c24935..f181c5b1 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineTextBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineTextBox.h
@@ -113,7 +113,7 @@
       StringBuilder* characters_with_hyphen = nullptr) const;
 
 #ifndef NDEBUG
-  void ShowBox(int = 0) const override;
+  void DumpBox(StringBuilder&) const override;
 #endif
   const char* BoxName() const override;
   String DebugName() const override;
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.cc
index cf0c6ea7..0b713073 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.cc
@@ -38,9 +38,8 @@
     // space that we cannot compute percent for text-indent.
     const Length& length = line_style_->TextIndent();
     LayoutUnit maximum_value;
-    if (length.IsPercentOrCalc() &&
-        constraint_space.ParentPercentageResolutionInlineSize().has_value())
-      maximum_value = *constraint_space.ParentPercentageResolutionInlineSize();
+    if (length.IsPercentOrCalc())
+      maximum_value = constraint_space.ParentPercentageResolutionInlineSize();
     text_indent_ = MinimumValueForLength(length, maximum_value);
   } else {
     text_indent_ = LayoutUnit();
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 fc33c54..1debd2b 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
@@ -53,7 +53,21 @@
 bool NGLineBreaker::IsFirstFormattedLine() const {
   if (item_index_ || offset_)
     return false;
-  return node_.GetLayoutBlockFlow()->CanContainFirstFormattedLine();
+
+  // TODO(kojii): In LayoutNG, leading OOF creates an anonymous block box,
+  // and that |CanContainFirstFormattedLine()| does not work.
+  // crbug.com/734554
+  // return node_.GetLayoutBlockFlow()->CanContainFirstFormattedLine();
+  LayoutObject* layout_object = node_.GetLayoutBlockFlow();
+  if (!layout_object->IsAnonymousBlock())
+    return true;
+  for (;;) {
+    layout_object = layout_object->PreviousSibling();
+    if (!layout_object)
+      return true;
+    if (!layout_object->IsFloatingOrOutOfFlowPositioned())
+      return false;
+  }
 }
 
 // Compute the base direction for bidi algorithm for this line.
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
index 8fe9a534..03157793 100644
--- a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
+++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
@@ -114,6 +114,7 @@
   // physical in a single variable.
   LayoutUnit static_inline;
   LayoutUnit static_block;
+  LayoutBoxModelObject* css_container = ToLayoutBoxModelObject(Container());
 
   if (container_style->IsDisplayFlexibleOrGridBox()) {
     static_inline = Layer()->StaticInlinePosition();
@@ -123,9 +124,12 @@
     Length logical_right;
     Length logical_top;
     Length logical_bottom;
-    ComputeInlineStaticDistance(logical_left, logical_right, this, container,
-                                container->LogicalWidth());
-    ComputeBlockStaticDistance(logical_top, logical_bottom, this, container);
+
+    ComputeInlineStaticDistance(
+        logical_left, logical_right, this, css_container,
+        ContainingBlockLogicalWidthForPositioned(css_container));
+    ComputeBlockStaticDistance(logical_top, logical_bottom, this,
+                               css_container);
     if (parent_style->IsLeftToRightDirection()) {
       if (!logical_left.IsAuto())
         static_inline = ValueForLength(logical_left, container->LogicalWidth());
@@ -164,7 +168,6 @@
       NGStaticPosition::Create(parent_style->GetWritingMode(),
                                parent_style->Direction(), static_location);
 
-  LayoutObject* css_container = Container();
   // Set correct container for inline containing blocks.
   container_builder.AddOutOfFlowLegacyCandidate(
       NGBlockNode(this), static_position,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index 62313666..d58082b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -1189,6 +1189,15 @@
 }
 
 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
+  if (first_overflowing_line_ && !fit_all_lines_) {
+    // A line box overflowed the fragmentainer, but we continued layout anyway,
+    // in order to determine where to break in order to honor the widows
+    // request. We never got around to actually breaking, before we ran out of
+    // lines. So do it now.
+    intrinsic_block_size_ = FragmentainerSpaceAvailable();
+    container_builder_.SetDidBreak();
+  }
+
   LayoutUnit used_block_size =
       BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit();
   LayoutUnit block_size = ComputeBlockSizeForFragment(
@@ -1220,9 +1229,23 @@
     // need to prepare a break token.
     container_builder_.SetUsedBlockSize(std::min(space_left, block_size) +
                                         used_block_size);
-    container_builder_.SetDidBreak();
     container_builder_.SetBlockSize(std::min(space_left, block_size));
     container_builder_.SetIntrinsicBlockSize(space_left);
+
+    if (first_overflowing_line_) {
+      int line_number;
+      if (fit_all_lines_) {
+        line_number = first_overflowing_line_;
+      } else {
+        // We managed to finish layout of all the lines for the node, which
+        // means that we won't have enough widows, unless we break earlier than
+        // where we overflowed.
+        int line_count = container_builder_.LineCount();
+        line_number = std::max(line_count - Style().Widows(),
+                               std::min(line_count, int(Style().Orphans())));
+      }
+      container_builder_.AddBreakBeforeLine(line_number);
+    }
     return;
   }
 
@@ -1249,6 +1272,59 @@
   if (!ShouldBreakBeforeChild(child, layout_result, block_offset))
     return false;
 
+  if (child.IsInline()) {
+    // Attempt to honor orphans and widows requests.
+    if (int line_count = container_builder_.LineCount()) {
+      if (!first_overflowing_line_)
+        first_overflowing_line_ = line_count;
+      bool is_first_fragment = !BreakToken();
+      // Figure out how many lines we need before the break. That entails to
+      // attempt to honor the orphans request.
+      int minimum_line_count = Style().Orphans();
+      if (!is_first_fragment) {
+        // If this isn't the first fragment, it means that there's a break both
+        // before and after this fragment. So what was seen as trailing widows
+        // in the previous fragment is essentially orphans for us now.
+        minimum_line_count =
+            std::max(minimum_line_count, static_cast<int>(Style().Widows()));
+      }
+      if (line_count < minimum_line_count) {
+        if (is_first_fragment) {
+          // Not enough orphans. Our only hope is if we can break before the
+          // start of this block to improve on the situation. That's not
+          // something we can determine at this point though. Permit the break,
+          // but mark it as undesirable.
+          container_builder_.SetHasLastResortBreak();
+        }
+        // We're already failing with orphans, so don't even try to deal with
+        // widows.
+        fit_all_lines_ = true;
+      } else {
+        // There are enough lines before the break. Try to make sure that
+        // there'll be enough lines after the break as well. Attempt to honor
+        // the widows request.
+        DCHECK_GE(line_count, first_overflowing_line_);
+        int widows_found = line_count - first_overflowing_line_ + 1;
+        if (widows_found < Style().Widows()) {
+          // Although we're out of space, we have to continue layout to figure
+          // out exactly where to break in order to honor the widows
+          // request. We'll make sure that we're going to leave at least as many
+          // lines as specified by the 'widows' property for the next fragment
+          // (if at all possible), which means that lines that could fit in the
+          // current fragment (that we have already laid out) may have to be
+          // saved for the next fragment.
+          return false;
+        } else {
+          // We have determined that there are plenty of lines for the next
+          // fragment, so we can just break exactly where we ran out of space,
+          // rather than pushing some of the line boxes over to the next
+          // fragment.
+          fit_all_lines_ = true;
+        }
+      }
+    }
+  }
+
   // The remaining part of the fragmentainer (the unusable space for child
   // content, due to the break) should still be occupied by this container.
   // TODO(mstensho): Figure out if we really need to <0 here. It doesn't seem
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
index 2f0ac61..87a0b6f 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -199,6 +199,17 @@
   NGBoxStrut border_scrollbar_padding_;
   LayoutUnit intrinsic_block_size_;
 
+  // The line box index at which we ran out of space. This where we'll actually
+  // end up breaking, unless we determine that we should break earlier in order
+  // to satisfy the widows request.
+  int first_overflowing_line_ = 0;
+
+  // Set if we should fit as many lines as there's room for, i.e. no early
+  // break. In that case we'll break before first_overflowing_line_. In this
+  // case there'll either be enough widows for the next fragment, or we have
+  // determined that we're unable to fulfill the widows request.
+  bool fit_all_lines_ = false;
+
   bool abort_when_bfc_resolved_;
   bool has_processed_first_child_ = false;
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm_test.cc
index b4673bb..9c08205 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -1388,6 +1388,398 @@
   EXPECT_EQ(expectation, dump);
 }
 
+TEST_F(NGColumnLayoutAlgorithmTest, Orphans) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 90px;
+        line-height: 20px;
+        orphans: 3;
+        widows: 1;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <div style="height:40px;"></div>
+        <div style="width:77px;">
+          <br>
+          <br>
+          <br>
+        </div>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x90
+    offset:0,0 size:320x90
+      offset:0,0 size:100x90
+        offset:0,0 size:100x40
+      offset:110,0 size:100x60
+        offset:0,0 size:77x60
+          offset:0,0 size:0x20
+            offset:0,9 size:0x1
+          offset:0,20 size:0x20
+            offset:0,9 size:0x1
+          offset:0,40 size:0x20
+            offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, OrphansUnsatisfiable) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 90px;
+        line-height: 20px;
+        orphans: 100;
+        widows: 1;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x90
+    offset:0,0 size:320x90
+      offset:0,0 size:100x90
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:0x20
+          offset:0,9 size:0x1
+        offset:0,60 size:0x20
+          offset:0,9 size:0x1
+      offset:110,0 size:100x40
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, Widows) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 110px;
+        line-height: 20px;
+        orphans: 1;
+        widows: 3;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x110
+    offset:0,0 size:320x110
+      offset:0,0 size:100x110
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:0x20
+          offset:0,9 size:0x1
+        offset:0,60 size:0x20
+          offset:0,9 size:0x1
+      offset:110,0 size:100x60
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:0x20
+          offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, WidowsUnsatisfiable) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 90px;
+        line-height: 20px;
+        orphans: 1;
+        widows: 100;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+        <br>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x90
+    offset:0,0 size:320x90
+      offset:0,0 size:100x90
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+      offset:110,0 size:100x90
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:0x20
+          offset:0,9 size:0x1
+        offset:0,60 size:0x20
+          offset:0,9 size:0x1
+      offset:220,0 size:100x90
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:0x20
+          offset:0,9 size:0x1
+        offset:0,60 size:0x20
+          offset:0,9 size:0x1
+      offset:330,0 size:100x90
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:0x20
+          offset:0,9 size:0x1
+        offset:0,60 size:0x20
+          offset:0,9 size:0x1
+      offset:440,0 size:100x20
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, OrphansAndUnsatisfiableWidows) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 70px;
+        line-height: 20px;
+        orphans: 2;
+        widows: 3;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <br>
+        <br>
+        <br>
+        <br>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x70
+    offset:0,0 size:320x70
+      offset:0,0 size:100x70
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+      offset:110,0 size:100x40
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, UnsatisfiableOrphansAndWidows) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 70px;
+        line-height: 20px;
+        orphans: 4;
+        widows: 4;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <br>
+        <br>
+        <br>
+        <br>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x70
+    offset:0,0 size:320x70
+      offset:0,0 size:100x70
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:0x20
+          offset:0,9 size:0x1
+      offset:110,0 size:100x20
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, FloatInBlockMovedByOrphans) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 70px;
+        line-height: 20px;
+        orphans: 2;
+        widows: 1;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <div style="width:11px; height:40px;"></div>
+        <div style="width:77px;">
+          <br>
+          <div style="float:left; width:10px; height:10px;"></div>
+          <br>
+        </div>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x70
+    offset:0,0 size:320x70
+      offset:0,0 size:100x70
+        offset:0,0 size:11x40
+      offset:110,0 size:100x40
+        offset:0,0 size:77x40
+          offset:0,0 size:0x20
+            offset:0,9 size:0x1
+          offset:0,20 size:10x10
+          offset:10,20 size:0x20
+            offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, FloatMovedWithWidows) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #parent {
+        columns: 3;
+        column-fill: auto;
+        column-gap: 10px;
+        width: 320px;
+        height: 90px;
+        line-height: 20px;
+        orphans: 1;
+        widows: 4;
+      }
+    </style>
+    <div id="container">
+      <div id="parent">
+        <br>
+        <br>
+        <br>
+        <div style="float:left; width:10px; height:10px;"></div>
+        <br>
+        <br>
+      </div>
+    </div>
+  )HTML");
+
+  String dump = DumpFragmentTree(GetElementById("container"));
+  String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+  offset:unplaced size:1000x90
+    offset:0,0 size:320x90
+      offset:0,0 size:100x90
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+      offset:110,0 size:100x80
+        offset:0,0 size:0x20
+          offset:0,9 size:0x1
+        offset:0,20 size:0x20
+          offset:0,9 size:0x1
+        offset:0,40 size:10x10
+        offset:10,40 size:0x20
+          offset:0,9 size:0x1
+        offset:0,60 size:0x20
+          offset:0,9 size:0x1
+)DUMP";
+  EXPECT_EQ(expectation, dump);
+}
+
 TEST_F(NGColumnLayoutAlgorithmTest, BorderAndPadding) {
   SetBodyInnerHTML(R"HTML(
     <style>
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
index 80b13c6..18b9862 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -32,7 +32,7 @@
     TextDirection direction,
     NGLogicalSize available_size,
     NGLogicalSize percentage_resolution_size,
-    Optional<LayoutUnit> parent_percentage_resolution_inline_size,
+    LayoutUnit parent_percentage_resolution_inline_size,
     NGPhysicalSize initial_containing_block_size,
     LayoutUnit fragmentainer_block_size,
     LayoutUnit fragmentainer_space_at_bfc_start,
@@ -183,12 +183,9 @@
   return InitialContainingBlockSize().width;
 }
 
-Optional<LayoutUnit> NGConstraintSpace::ParentPercentageResolutionInlineSize()
-    const {
-  if (!parent_percentage_resolution_inline_size_.has_value())
-    return {};
-  if (*parent_percentage_resolution_inline_size_ != NGSizeIndefinite)
-    return *parent_percentage_resolution_inline_size_;
+LayoutUnit NGConstraintSpace::ParentPercentageResolutionInlineSize() const {
+  if (parent_percentage_resolution_inline_size_ != NGSizeIndefinite)
+    return parent_percentage_resolution_inline_size_;
   return initial_containing_block_size_.ConvertToLogical(GetWritingMode())
       .inline_size;
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
index 4713302d..afc7a97 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -68,7 +68,7 @@
 
   // Parent's PercentageResolutionInlineSize().
   // This is not always available.
-  Optional<LayoutUnit> ParentPercentageResolutionInlineSize() const;
+  LayoutUnit ParentPercentageResolutionInlineSize() const;
 
   // The available space size.
   // See: https://drafts.csswg.org/css-sizing/#available
@@ -202,7 +202,7 @@
       TextDirection,
       NGLogicalSize available_size,
       NGLogicalSize percentage_resolution_size,
-      Optional<LayoutUnit> parent_percentage_resolution_inline_size,
+      LayoutUnit parent_percentage_resolution_inline_size,
       NGPhysicalSize initial_containing_block_size,
       LayoutUnit fragmentainer_block_size,
       LayoutUnit fragmentainer_space_at_bfc_start,
@@ -225,7 +225,7 @@
 
   NGLogicalSize available_size_;
   NGLogicalSize percentage_resolution_size_;
-  Optional<LayoutUnit> parent_percentage_resolution_inline_size_;
+  LayoutUnit parent_percentage_resolution_inline_size_;
   NGPhysicalSize initial_containing_block_size_;
 
   LayoutUnit fragmentainer_block_size_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
index cb8f0f7..65fe50c 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
@@ -11,7 +11,9 @@
 NGConstraintSpaceBuilder::NGConstraintSpaceBuilder(
     const NGConstraintSpace& parent_space)
     : NGConstraintSpaceBuilder(parent_space.GetWritingMode(),
-                               parent_space.InitialContainingBlockSize()) {}
+                               parent_space.InitialContainingBlockSize()) {
+  parent_percentage_resolution_size_ = parent_space.PercentageResolutionSize();
+}
 
 NGConstraintSpaceBuilder::NGConstraintSpaceBuilder(WritingMode writing_mode,
                                                    NGPhysicalSize icb_size)
@@ -168,13 +170,12 @@
 
   NGLogicalSize available_size = available_size_;
   NGLogicalSize percentage_resolution_size = percentage_resolution_size_;
-  Optional<NGLogicalSize> parent_percentage_resolution_size =
-      parent_percentage_resolution_size_;
+  NGLogicalSize parent_percentage_resolution_size =
+      parent_percentage_resolution_size_.value_or(percentage_resolution_size);
   if (!is_in_parallel_flow) {
     available_size.Flip();
     percentage_resolution_size.Flip();
-    if (parent_percentage_resolution_size.has_value())
-      parent_percentage_resolution_size->Flip();
+    parent_percentage_resolution_size.Flip();
   }
 
   // If inline size is indefinite, use size of initial containing block.
@@ -197,12 +198,6 @@
           initial_containing_block_size_.height;
     }
   }
-  // parent_percentage_resolution_size is so rarely used that compute indefinite
-  // fallback in NGConstraintSpace when it is used.
-  Optional<LayoutUnit> parent_percentage_resolution_inline_size =
-      parent_percentage_resolution_size.has_value()
-          ? parent_percentage_resolution_size->inline_size
-          : Optional<LayoutUnit>();
 
   DEFINE_STATIC_LOCAL(NGExclusionSpace, empty_exclusion_space, ());
 
@@ -229,7 +224,8 @@
     return base::AdoptRef(new NGConstraintSpace(
         static_cast<WritingMode>(out_writing_mode), false,
         static_cast<TextDirection>(text_direction_), available_size,
-        percentage_resolution_size, parent_percentage_resolution_inline_size,
+        percentage_resolution_size,
+        parent_percentage_resolution_size.inline_size,
         initial_containing_block_size_, fragmentainer_block_size_,
         fragmentainer_space_at_bfc_start_, is_fixed_size_inline_,
         is_fixed_size_block_, is_shrink_to_fit_,
@@ -243,9 +239,10 @@
   return base::AdoptRef(new NGConstraintSpace(
       out_writing_mode, true, static_cast<TextDirection>(text_direction_),
       available_size, percentage_resolution_size,
-      parent_percentage_resolution_inline_size, initial_containing_block_size_,
-      fragmentainer_block_size_, fragmentainer_space_at_bfc_start_,
-      is_fixed_size_block_, is_fixed_size_inline_, is_shrink_to_fit_,
+      parent_percentage_resolution_size.inline_size,
+      initial_containing_block_size_, fragmentainer_block_size_,
+      fragmentainer_space_at_bfc_start_, is_fixed_size_block_,
+      is_fixed_size_inline_, is_shrink_to_fit_,
       is_block_direction_triggers_scrollbar_,
       is_inline_direction_triggers_scrollbar_,
       static_cast<NGFragmentationType>(fragmentation_type_), is_new_fc_,
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 300445ec..0589c737 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
@@ -60,12 +60,12 @@
         child_break_tokens_.push_back(child->BreakToken());
       break;
     case NGPhysicalBoxFragment::kFragmentLineBox:
-      // NGInlineNode produces multiple line boxes in an anonymous box. Only
-      // the last break token is needed to be reported to the parent.
+      // NGInlineNode produces multiple line boxes in an anonymous box. We won't
+      // know up front which line box to insert a fragment break before (due to
+      // widows), so keep them all until we know.
       DCHECK(child->BreakToken());
       DCHECK(child->BreakToken()->InputNode() == node_);
-      last_inline_break_token_ =
-          child->BreakToken()->IsFinished() ? nullptr : child->BreakToken();
+      inline_break_tokens_.push_back(child->BreakToken());
       break;
     case NGPhysicalBoxFragment::kFragmentText:
       DCHECK(!child->BreakToken());
@@ -92,15 +92,15 @@
     has_last_resort_break_ = true;
   }
   if (child.IsInline()) {
-    if (last_inline_break_token_) {
-      // We need to resume at this inline location in the next fragmentainer,
-      // but broken floats, which are resumed and positioned by the parent block
-      // layout algorithm, need to be ignored by the inline layout algorithm.
-      ToNGInlineBreakToken(last_inline_break_token_.get())->SetIgnoreFloats();
-    } else {
-      last_inline_break_token_ = NGInlineBreakToken::Create(
+    if (inline_break_tokens_.IsEmpty()) {
+      // In some cases we may want to break before the first line, as a last
+      // resort. We need a break token for that as well, so that the machinery
+      // will understand that we should resume at the beginning of the inline
+      // formatting context, rather than concluding that we're done with the
+      // whole thing.
+      inline_break_tokens_.push_back(NGInlineBreakToken::Create(
           ToNGInlineNode(child), 0, 0, false,
-          std::make_unique<NGInlineLayoutStateStack>());
+          std::make_unique<NGInlineLayoutStateStack>()));
     }
     return *this;
   }
@@ -114,6 +114,38 @@
   return *this;
 }
 
+NGFragmentBuilder& NGFragmentBuilder::AddBreakBeforeLine(int line_number) {
+  DCHECK_GT(line_number, 0);
+  DCHECK_LE(unsigned(line_number), inline_break_tokens_.size());
+  int lines_to_remove = inline_break_tokens_.size() - line_number;
+  if (lines_to_remove > 0) {
+    // Remove widows that should be pushed to the next fragment. We'll also
+    // remove all other child fragments than line boxes (typically floats) that
+    // come after the first line that's moved, as those also have to be re-laid
+    // out in the next fragment.
+    inline_break_tokens_.resize(line_number);
+    DCHECK_GT(children_.size(), 0UL);
+    for (int i = children_.size() - 1; i >= 0; i--) {
+      DCHECK_NE(i, 0);
+      if (!children_[i]->IsLineBox())
+        continue;
+      if (!--lines_to_remove) {
+        // This is the first line that is going to the next fragment. Remove it,
+        // and everything after it.
+        children_.resize(i);
+        offsets_.resize(i);
+        break;
+      }
+    }
+  }
+
+  // We need to resume at the right inline location in the next fragment, but
+  // broken floats, which are resumed and positioned by the parent block layout
+  // algorithm, need to be ignored by the inline layout algorithm.
+  ToNGInlineBreakToken(inline_break_tokens_.back().get())->SetIgnoreFloats();
+  return *this;
+}
+
 NGFragmentBuilder& NGFragmentBuilder::PropagateBreak(
     scoped_refptr<NGLayoutResult> child_layout_result) {
   if (!did_break_)
@@ -223,9 +255,11 @@
 
   scoped_refptr<NGBreakToken> break_token;
   if (node_) {
-    if (last_inline_break_token_) {
-      DCHECK(!last_inline_break_token_->IsFinished());
-      child_break_tokens_.push_back(std::move(last_inline_break_token_));
+    if (!inline_break_tokens_.IsEmpty()) {
+      if (auto token = inline_break_tokens_.back()) {
+        if (!token->IsFinished())
+          child_break_tokens_.push_back(std::move(token));
+      }
     }
     if (did_break_) {
       break_token = NGBlockBreakToken::Create(
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 baa547a4..4740cbc 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
@@ -56,6 +56,9 @@
   // add a break token for the child, but no fragment.
   NGFragmentBuilder& AddBreakBeforeChild(NGLayoutInputNode child);
 
+  // Prepare for a break token before the specified line.
+  NGFragmentBuilder& AddBreakBeforeLine(int line_number);
+
   // Update if we have fragmented in this flow.
   NGFragmentBuilder& PropagateBreak(scoped_refptr<NGLayoutResult>);
   NGFragmentBuilder& PropagateBreak(scoped_refptr<NGPhysicalFragment>);
@@ -91,6 +94,13 @@
   // in-flow siblings.
   EBreakBetween JoinedBreakBetweenValue(EBreakBetween break_before) const;
 
+  // Return the number of line boxes laid out.
+  int LineCount() const { return inline_break_tokens_.size(); }
+
+  // Call when we're setting an undersirable break. It may be possible to avoid
+  // the break if we instead break at an earlier element.
+  void SetHasLastResortBreak() { has_last_resort_break_ = true; }
+
   // Offsets are not supposed to be set during fragment construction, so we
   // do not provide a setter here.
 
@@ -170,7 +180,7 @@
   EBreakBetween previous_break_after_ = EBreakBetween::kAuto;
 
   Vector<scoped_refptr<NGBreakToken>> child_break_tokens_;
-  scoped_refptr<NGBreakToken> last_inline_break_token_;
+  Vector<scoped_refptr<NGBreakToken>> inline_break_tokens_;
 
   Vector<NGBaseline> baselines_;
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
index 2a137c37..d13e7e9 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -108,168 +108,175 @@
           default_containing_block_.style->GetWritingMode());
   // Translate start/end fragments into ContainingBlockInfo.
   for (auto& block_info : inline_container_fragments) {
+    // Variables needed to describe ContainingBlockInfo
+    const ComputedStyle* inline_cb_style;
+    NGLogicalSize inline_cb_size;
+    NGLogicalOffset inline_content_offset;
+    NGPhysicalOffset inline_content_physical_offset;
+    NGLogicalOffset default_container_offset;
     if (!block_info.value.start_fragment) {
       // This happens when Legacy block is the default container.
       // In this case, container builder does not have any fragments because
       // ng layout algorithm did not run.
-      DCHECK(false);
-      // TODO(atotic) ContainingBlockInfo must be computed from Legacy algorithm
-    }
-    NGLogicalOffset inline_content_offset;
-    NGPhysicalOffset inline_content_physical_offset;
-    NGLogicalSize inline_cb_size;
-    const ComputedStyle* inline_cb_style;
-    inline_cb_style = &block_info.value.start_fragment->Style();
-    scoped_refptr<NGConstraintSpace> dummy_constraint_space =
-        NGConstraintSpaceBuilder(inline_cb_style->GetWritingMode(), icb_size_)
-            .ToConstraintSpace(inline_cb_style->GetWritingMode());
-    // TODO Creating dummy constraint space just to get borders feels wrong.
-    NGBoxStrut inline_cb_borders =
-        ComputeBorders(*dummy_constraint_space, *inline_cb_style);
-    NGPhysicalBoxStrut physical_borders = inline_cb_borders.ConvertToPhysical(
-        inline_cb_style->GetWritingMode(), inline_cb_style->Direction());
-    NGBoxStrut inline_cb_padding =
-        ComputePadding(*dummy_constraint_space, *inline_cb_style);
-
-    // Warning: lots of non-obvious coordinate manipulation ahead.
-    //
-    // High level goal is:
-    // - Find logical topleft of start fragment, and logical bottomright
-    //   of end fragment.
-    // - Use these to compute inline-cb geometry:
-    //   - inline-cb size (content_size)
-    //   - inline-cb offset from containing block (default_container_offset)
-    //
-    // We start with:
-    // start_fragment, which has physical offset from start_linebox_fragment,
-    // end_fragment, also with physical offset.
-    // start_linebox_fragment, which has logical offset from containing box.
-    // end_linebox_fragment, which also has logical offset from containing box.
-    //
-    // Then magic happens.^H^H^H^H^H^H^H
-    //
-    // Then we do the following:
-    // 1. Find start fragment physical topleft wrt containing box.
-    //    - convert start_fragment offset to logical.
-    //    - convert start fragment inline/block start to physical.
-    //    - convert linebox topleft to physical.
-    //    - add start fragment to linebox topleft
-    // 2. Find end fragment bottom right wrt containing box
-    //    - convert end fragment offset to logical.
-    //    - convert end fragment inline/block end to physical
-    //    - convert linebox topleft to physical
-    //    - add end fragment bottomLeft to linebox topleft
-    // 3. Convert both topleft/bottomright to logical, so that we can
-    // 4. Enforce logical topLeft < bottomRight
-    // 5. Compute size, physical offset
-    const NGPhysicalFragment* start_fragment = block_info.value.start_fragment;
-    const NGPhysicalLineBoxFragment* start_linebox_fragment =
-        block_info.value.start_linebox_fragment;
-    WritingMode container_writing_mode =
-        default_containing_block_.style->GetWritingMode();
-    TextDirection container_direction =
-        default_containing_block_.style->Direction();
-    // Step 1
-    NGLogicalOffset start_fragment_logical_offset =
-        block_info.value.start_fragment_union_rect.offset.ConvertToLogical(
-            container_writing_mode, container_direction,
-            start_linebox_fragment->Size(),
-            block_info.value.start_fragment_union_rect.size);
-    // Text fragments do not include inline-cb borders and padding.
-    if (start_fragment->IsText()) {
-      start_fragment_logical_offset -= inline_cb_borders.StartOffset();
-      start_fragment_logical_offset -= inline_cb_padding.StartOffset();
-    }
-    NGPhysicalOffset start_fragment_physical_offset =
-        start_fragment_logical_offset.ConvertToPhysical(
-            container_writing_mode, container_direction,
-            start_linebox_fragment->Size(), NGPhysicalSize());
-    NGPhysicalOffset start_linebox_physical_offset =
-        block_info.value.start_linebox_offset.ConvertToPhysical(
-            container_writing_mode, container_direction,
-            container_builder_physical_size, start_linebox_fragment->Size());
-    start_fragment_physical_offset += start_linebox_physical_offset;
-    // Step 2
-    const NGPhysicalLineBoxFragment* end_linebox_fragment =
-        block_info.value.end_linebox_fragment;
-    const NGPhysicalFragment* end_fragment = block_info.value.end_fragment;
-    NGLogicalOffset end_fragment_logical_offset =
-        block_info.value.end_fragment_union_rect.offset.ConvertToLogical(
-            container_writing_mode, container_direction,
-            end_linebox_fragment->Size(),
-            block_info.value.end_fragment_union_rect.size);
-    // Text fragments do not include inline-cb borders and padding.
-    if (end_fragment->IsText()) {
-      end_fragment_logical_offset += NGLogicalOffset(
-          inline_cb_borders.inline_end, inline_cb_borders.block_end);
-      end_fragment_logical_offset += NGLogicalOffset(
-          inline_cb_padding.inline_end, inline_cb_padding.block_end);
-    }
-    NGLogicalOffset end_fragment_bottom_right =
-        end_fragment_logical_offset +
-        block_info.value.end_fragment_union_rect.size.ConvertToLogical(
-            container_writing_mode);
-    NGPhysicalOffset end_fragment_physical_offset =
-        end_fragment_bottom_right.ConvertToPhysical(
-            container_writing_mode, container_direction,
-            end_linebox_fragment->Size(), NGPhysicalSize());
-    NGPhysicalOffset end_linebox_physical_offset =
-        block_info.value.end_linebox_offset.ConvertToPhysical(
-            container_writing_mode, container_direction,
-            container_builder_physical_size, end_linebox_fragment->Size());
-    end_fragment_physical_offset += end_linebox_physical_offset;
-    // Step 3
-    NGLogicalOffset start_fragment_logical_offset_wrt_box =
-        start_fragment_physical_offset.ConvertToLogical(
-            inline_cb_style->GetWritingMode(), inline_cb_style->Direction(),
-            container_builder_physical_size, NGPhysicalSize());
-    NGLogicalOffset end_fragment_logical_offset_wrt_box =
-        end_fragment_physical_offset.ConvertToLogical(
-            inline_cb_style->GetWritingMode(), inline_cb_style->Direction(),
-            container_builder_physical_size, NGPhysicalSize());
-
-    // Step 4
-    end_fragment_logical_offset_wrt_box.inline_offset =
-        std::max(end_fragment_logical_offset_wrt_box.inline_offset,
-                 start_fragment_logical_offset_wrt_box.inline_offset +
-                     inline_cb_borders.InlineSum());
-    end_fragment_logical_offset_wrt_box.block_offset =
-        std::max(end_fragment_logical_offset_wrt_box.block_offset,
-                 start_fragment_logical_offset_wrt_box.block_offset +
-                     inline_cb_borders.BlockSum());
-
-    // Step 5
-    inline_cb_size.inline_size =
-        end_fragment_logical_offset_wrt_box.inline_offset -
-        start_fragment_logical_offset_wrt_box.inline_offset -
-        inline_cb_borders.InlineSum();
-    inline_cb_size.block_size =
-        end_fragment_logical_offset_wrt_box.block_offset -
-        start_fragment_logical_offset_wrt_box.block_offset -
-        inline_cb_borders.BlockSum();
-
-    DCHECK_GE(inline_cb_size.inline_size, LayoutUnit());
-    DCHECK_GE(inline_cb_size.block_size, LayoutUnit());
-
-    inline_content_offset = NGLogicalOffset{inline_cb_borders.inline_start,
-                                            inline_cb_borders.block_start};
-    inline_content_physical_offset =
-        NGPhysicalOffset(physical_borders.left, physical_borders.top);
-
-    NGLogicalOffset default_container_offset;
-    if (RuntimeEnabledFeatures::LayoutNGPaintFragmentsEnabled()) {
-      // NGPaint offset is wrt parent fragment.
-      default_container_offset = start_fragment_logical_offset_wrt_box -
-                                 default_containing_block_.content_offset;
-      default_container_offset += inline_cb_borders.StartOffset();
+      DCHECK(block_info.key->IsLayoutInline());
+      inline_cb_style = block_info.key->Style();
+      NOTIMPLEMENTED()
+          << "Inline containing block might need geometry information";
+      // TODO(atotic) ContainingBlockInfo geometry
+      // must be computed from Legacy algorithm
     } else {
-      // Legacy offset is wrt inline container.
-      default_container_offset =
-          NGLogicalOffset(inline_cb_borders.inline_start,
-                          inline_cb_borders.block_start) -
-          default_containing_block_.content_offset;
-    }
+      inline_cb_style = &block_info.value.start_fragment->Style();
+      scoped_refptr<NGConstraintSpace> dummy_constraint_space =
+          NGConstraintSpaceBuilder(inline_cb_style->GetWritingMode(), icb_size_)
+              .ToConstraintSpace(inline_cb_style->GetWritingMode());
+      // TODO Creating dummy constraint space just to get borders feels wrong.
+      NGBoxStrut inline_cb_borders =
+          ComputeBorders(*dummy_constraint_space, *inline_cb_style);
+      NGPhysicalBoxStrut physical_borders = inline_cb_borders.ConvertToPhysical(
+          inline_cb_style->GetWritingMode(), inline_cb_style->Direction());
+      NGBoxStrut inline_cb_padding =
+          ComputePadding(*dummy_constraint_space, *inline_cb_style);
 
+      // Warning: lots of non-obvious coordinate manipulation ahead.
+      //
+      // High level goal is:
+      // - Find logical topleft of start fragment, and logical bottomright
+      //   of end fragment.
+      // - Use these to compute inline-cb geometry:
+      //   - inline-cb size (content_size)
+      //   - inline-cb offset from containing block (default_container_offset)
+      //
+      // We start with:
+      // start_fragment, which has physical offset from start_linebox_fragment,
+      // end_fragment, also with physical offset.
+      // start_linebox_fragment, which has logical offset from containing box.
+      // end_linebox_fragment, which also has logical offset from containing
+      // box.
+      //
+      // Then magic happens.^H^H^H^H^H^H^H
+      //
+      // Then we do the following:
+      // 1. Find start fragment physical topleft wrt containing box.
+      //    - convert start_fragment offset to logical.
+      //    - convert start fragment inline/block start to physical.
+      //    - convert linebox topleft to physical.
+      //    - add start fragment to linebox topleft
+      // 2. Find end fragment bottom right wrt containing box
+      //    - convert end fragment offset to logical.
+      //    - convert end fragment inline/block end to physical
+      //    - convert linebox topleft to physical
+      //    - add end fragment bottomLeft to linebox topleft
+      // 3. Convert both topleft/bottomright to logical, so that we can
+      // 4. Enforce logical topLeft < bottomRight
+      // 5. Compute size, physical offset
+      const NGPhysicalFragment* start_fragment =
+          block_info.value.start_fragment;
+      const NGPhysicalLineBoxFragment* start_linebox_fragment =
+          block_info.value.start_linebox_fragment;
+      WritingMode container_writing_mode =
+          default_containing_block_.style->GetWritingMode();
+      TextDirection container_direction =
+          default_containing_block_.style->Direction();
+      // Step 1
+      NGLogicalOffset start_fragment_logical_offset =
+          block_info.value.start_fragment_union_rect.offset.ConvertToLogical(
+              container_writing_mode, container_direction,
+              start_linebox_fragment->Size(),
+              block_info.value.start_fragment_union_rect.size);
+      // Text fragments do not include inline-cb borders and padding.
+      if (start_fragment->IsText()) {
+        start_fragment_logical_offset -= inline_cb_borders.StartOffset();
+        start_fragment_logical_offset -= inline_cb_padding.StartOffset();
+      }
+      NGPhysicalOffset start_fragment_physical_offset =
+          start_fragment_logical_offset.ConvertToPhysical(
+              container_writing_mode, container_direction,
+              start_linebox_fragment->Size(), NGPhysicalSize());
+      NGPhysicalOffset start_linebox_physical_offset =
+          block_info.value.start_linebox_offset.ConvertToPhysical(
+              container_writing_mode, container_direction,
+              container_builder_physical_size, start_linebox_fragment->Size());
+      start_fragment_physical_offset += start_linebox_physical_offset;
+      // Step 2
+      const NGPhysicalLineBoxFragment* end_linebox_fragment =
+          block_info.value.end_linebox_fragment;
+      const NGPhysicalFragment* end_fragment = block_info.value.end_fragment;
+      NGLogicalOffset end_fragment_logical_offset =
+          block_info.value.end_fragment_union_rect.offset.ConvertToLogical(
+              container_writing_mode, container_direction,
+              end_linebox_fragment->Size(),
+              block_info.value.end_fragment_union_rect.size);
+      // Text fragments do not include inline-cb borders and padding.
+      if (end_fragment->IsText()) {
+        end_fragment_logical_offset += NGLogicalOffset(
+            inline_cb_borders.inline_end, inline_cb_borders.block_end);
+        end_fragment_logical_offset += NGLogicalOffset(
+            inline_cb_padding.inline_end, inline_cb_padding.block_end);
+      }
+      NGLogicalOffset end_fragment_bottom_right =
+          end_fragment_logical_offset +
+          block_info.value.end_fragment_union_rect.size.ConvertToLogical(
+              container_writing_mode);
+      NGPhysicalOffset end_fragment_physical_offset =
+          end_fragment_bottom_right.ConvertToPhysical(
+              container_writing_mode, container_direction,
+              end_linebox_fragment->Size(), NGPhysicalSize());
+      NGPhysicalOffset end_linebox_physical_offset =
+          block_info.value.end_linebox_offset.ConvertToPhysical(
+              container_writing_mode, container_direction,
+              container_builder_physical_size, end_linebox_fragment->Size());
+      end_fragment_physical_offset += end_linebox_physical_offset;
+      // Step 3
+      NGLogicalOffset start_fragment_logical_offset_wrt_box =
+          start_fragment_physical_offset.ConvertToLogical(
+              inline_cb_style->GetWritingMode(), inline_cb_style->Direction(),
+              container_builder_physical_size, NGPhysicalSize());
+      NGLogicalOffset end_fragment_logical_offset_wrt_box =
+          end_fragment_physical_offset.ConvertToLogical(
+              inline_cb_style->GetWritingMode(), inline_cb_style->Direction(),
+              container_builder_physical_size, NGPhysicalSize());
+
+      // Step 4
+      end_fragment_logical_offset_wrt_box.inline_offset =
+          std::max(end_fragment_logical_offset_wrt_box.inline_offset,
+                   start_fragment_logical_offset_wrt_box.inline_offset +
+                       inline_cb_borders.InlineSum());
+      end_fragment_logical_offset_wrt_box.block_offset =
+          std::max(end_fragment_logical_offset_wrt_box.block_offset,
+                   start_fragment_logical_offset_wrt_box.block_offset +
+                       inline_cb_borders.BlockSum());
+
+      // Step 5
+      inline_cb_size.inline_size =
+          end_fragment_logical_offset_wrt_box.inline_offset -
+          start_fragment_logical_offset_wrt_box.inline_offset -
+          inline_cb_borders.InlineSum();
+      inline_cb_size.block_size =
+          end_fragment_logical_offset_wrt_box.block_offset -
+          start_fragment_logical_offset_wrt_box.block_offset -
+          inline_cb_borders.BlockSum();
+
+      DCHECK_GE(inline_cb_size.inline_size, LayoutUnit());
+      DCHECK_GE(inline_cb_size.block_size, LayoutUnit());
+
+      inline_content_offset = NGLogicalOffset{inline_cb_borders.inline_start,
+                                              inline_cb_borders.block_start};
+      inline_content_physical_offset =
+          NGPhysicalOffset(physical_borders.left, physical_borders.top);
+
+      if (RuntimeEnabledFeatures::LayoutNGPaintFragmentsEnabled()) {
+        // NGPaint offset is wrt parent fragment.
+        default_container_offset = start_fragment_logical_offset_wrt_box -
+                                   default_containing_block_.content_offset;
+        default_container_offset += inline_cb_borders.StartOffset();
+      } else {
+        // Legacy offset is wrt inline container.
+        default_container_offset =
+            NGLogicalOffset(inline_cb_borders.inline_start,
+                            inline_cb_borders.block_start) -
+            default_containing_block_.content_offset;
+      }
+    }
     containing_blocks_map_.insert(
         block_info.key, ContainingBlockInfo{inline_cb_style, inline_cb_size,
                                             inline_content_offset,
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
index d54dbd0..79b4979f 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
@@ -103,8 +103,8 @@
   // If our frame has an owner layoutObject, we're embedded through eg.
   // object/embed/iframe, but we only negotiate if we're in an SVG document
   // inside a embedded object (object/embed).
-  if (frame->OwnerLayoutItem().IsNull() ||
-      !frame->OwnerLayoutItem().IsEmbeddedObject())
+  if (!frame->OwnerLayoutObject() ||
+      !frame->OwnerLayoutObject()->IsEmbeddedObject())
     return false;
   return frame->GetDocument()->IsSVGDocument();
 }
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index a871a07..8a24b45 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -358,7 +358,7 @@
                                   const LayoutPoint& point) {
   HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive);
   HitTestResult result(request, point);
-  document_under_mouse->GetLayoutViewItem().HitTest(result);
+  document_under_mouse->GetLayoutView()->HitTest(result);
 
   Node* n = result.InnerNode();
   while (n && !n->IsElementNode())
@@ -703,7 +703,7 @@
   if (!drag_data->ContainsCompatibleContent())
     return false;
 
-  if (local_root.ContentLayoutItem().IsNull())
+  if (!local_root.ContentLayoutObject())
     return false;
 
   LayoutPoint point = local_root.View()->RootFrameToContents(
@@ -927,7 +927,7 @@
   DCHECK(DragTypeIsValid(state.drag_type_));
 #endif
   DCHECK(src);
-  if (!src->View() || src->ContentLayoutItem().IsNull())
+  if (!src->View() || !src->ContentLayoutObject())
     return false;
 
   HitTestResult hit_test_result =
@@ -1158,7 +1158,7 @@
   DCHECK(DragTypeIsValid(state.drag_type_));
 #endif
   DCHECK(src);
-  if (!src->View() || src->ContentLayoutItem().IsNull())
+  if (!src->View() || !src->ContentLayoutObject())
     return false;
 
   HitTestResult hit_test_result =
diff --git a/third_party/WebKit/Source/core/page/PrintContext.cpp b/third_party/WebKit/Source/core/page/PrintContext.cpp
index db70d57..e40998aa 100644
--- a/third_party/WebKit/Source/core/page/PrintContext.cpp
+++ b/third_party/WebKit/Source/core/page/PrintContext.cpp
@@ -60,8 +60,8 @@
   if (!IsFrameValid())
     return;
 
-  LayoutViewItem view = frame_->GetDocument()->GetLayoutViewItem();
-  const IntRect& document_rect = view.DocumentRect();
+  auto* view = frame_->GetDocument()->GetLayoutView();
+  const IntRect& document_rect = view->DocumentRect();
   FloatSize page_size = frame_->ResizePageRectsKeepingRatio(
       print_size, FloatSize(document_rect.Width(), document_rect.Height()));
   ComputePageRectsWithPageSizeInternal(page_size);
@@ -78,9 +78,9 @@
   if (!IsFrameValid())
     return;
 
-  LayoutViewItem view = frame_->GetDocument()->GetLayoutViewItem();
+  auto* view = frame_->GetDocument()->GetLayoutView();
 
-  IntRect doc_rect = view.DocumentRect();
+  IntRect doc_rect = view->DocumentRect();
 
   int page_width = page_size_in_pixels.Width();
   // We scaled with floating point arithmetic and need to ensure results like
@@ -88,7 +88,7 @@
   // page for the stray pixel.
   int page_height = page_size_in_pixels.Height() + LayoutUnit::Epsilon();
 
-  bool is_horizontal = view.Style()->IsHorizontalWritingMode();
+  bool is_horizontal = view->StyleRef().IsHorizontalWritingMode();
 
   int doc_logical_height = is_horizontal ? doc_rect.Height() : doc_rect.Width();
   int page_logical_height = is_horizontal ? page_height : page_width;
@@ -102,9 +102,9 @@
     std::swap(block_direction_start, inline_direction_start);
     std::swap(block_direction_end, inline_direction_end);
   }
-  if (!view.Style()->IsLeftToRightDirection())
+  if (!view->StyleRef().IsLeftToRightDirection())
     std::swap(inline_direction_start, inline_direction_end);
-  if (view.Style()->IsFlippedBlocksWritingMode())
+  if (view->StyleRef().IsFlippedBlocksWritingMode())
     std::swap(block_direction_start, block_direction_end);
 
   unsigned page_count =
@@ -313,7 +313,7 @@
 
 bool PrintContext::IsFrameValid() const {
   return frame_->View() && frame_->GetDocument() &&
-         !frame_->GetDocument()->GetLayoutViewItem().IsNull();
+         frame_->GetDocument()->GetLayoutView();
 }
 
 void PrintContext::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/page/ViewportTest.cpp b/third_party/WebKit/Source/core/page/ViewportTest.cpp
index 8337be9d..b747581 100644
--- a/third_party/WebKit/Source/core/page/ViewportTest.cpp
+++ b/third_party/WebKit/Source/core/page/ViewportTest.cpp
@@ -3240,6 +3240,132 @@
   EXPECT_EQ(0U, web_frame_client.messages.size());
 }
 
+class ViewportClient : public FrameTestHelpers::TestWebViewClient {
+ public:
+  ViewportClient() : device_scale_factor_(1.f) {}
+  void ConvertWindowToViewport(WebFloatRect* rect) override {
+    rect->x *= device_scale_factor_;
+    rect->y *= device_scale_factor_;
+    rect->width *= device_scale_factor_;
+    rect->height *= device_scale_factor_;
+  }
+  void set_device_scale_factor(float device_scale_factor) {
+    device_scale_factor_ = device_scale_factor;
+  }
+
+ private:
+  float device_scale_factor_;
+};
+
+TEST_F(ViewportTest, viewportUseZoomForDSF1) {
+  ViewportClient client;
+  client.set_device_scale_factor(3);
+  RegisterMockedHttpURLLoad("viewport/viewport-legacy-merge-quirk-1.html");
+
+  FrameTestHelpers::WebViewHelper web_view_helper;
+  web_view_helper.InitializeAndLoad(
+      base_url_ + "viewport/viewport-legacy-merge-quirk-1.html", nullptr,
+      &client, nullptr, SetQuirkViewportSettings);
+
+  Page* page = web_view_helper.GetWebView()->GetPage();
+  // Initial width and height must be scaled by DSF when --use-zoom-for-dsf
+  // is enabled.
+  PageScaleConstraints constraints = RunViewportTest(page, 960, 1056);
+
+  // When --use-zoom-for-dsf is enabled,
+  // constraints layout width == 640 * DSF = 1920
+  EXPECT_EQ(1920, constraints.layout_size.Width());
+  // When --use-zoom-for-dsf is enabled,
+  // constraints layout height == 704 * DSF = 2112
+  EXPECT_EQ(2112, constraints.layout_size.Height());
+  EXPECT_NEAR(1.0f, constraints.initial_scale, 0.01f);
+  EXPECT_NEAR(1.0f, constraints.minimum_scale, 0.01f);
+  EXPECT_NEAR(1.0f, constraints.maximum_scale, 0.01f);
+  EXPECT_FALSE(page->GetViewportDescription().user_zoom);
+}
+
+TEST_F(ViewportTest, viewportUseZoomForDSF2) {
+  ViewportClient client;
+  client.set_device_scale_factor(3);
+  RegisterMockedHttpURLLoad("viewport/viewport-legacy-merge-quirk-2.html");
+
+  FrameTestHelpers::WebViewHelper web_view_helper;
+  web_view_helper.InitializeAndLoad(
+      base_url_ + "viewport/viewport-legacy-merge-quirk-2.html", nullptr,
+      &client, nullptr, SetQuirkViewportSettings);
+
+  Page* page = web_view_helper.GetWebView()->GetPage();
+
+  // This quirk allows content attributes of meta viewport tags to be merged.
+  page->GetSettings().SetViewportMetaMergeContentQuirk(true);
+  // Initial width and height must be scaled by DSF when --use-zoom-for-dsf
+  // is enabled.
+  PageScaleConstraints constraints = RunViewportTest(page, 960, 1056);
+
+  // When --use-zoom-for-dsf is enabled,
+  // constraints layout width == 500 * DSF = 1500
+  EXPECT_EQ(1500, constraints.layout_size.Width());
+  // When --use-zoom-for-dsf is enabled,
+  // constraints layout height == 550 * DSF = 1650
+  EXPECT_EQ(1650, constraints.layout_size.Height());
+  EXPECT_NEAR(2.0f, constraints.initial_scale, 0.01f);
+  EXPECT_NEAR(2.0f, constraints.minimum_scale, 0.01f);
+  EXPECT_NEAR(2.0f, constraints.maximum_scale, 0.01f);
+  EXPECT_FALSE(page->GetViewportDescription().user_zoom);
+}
+
+TEST_F(ViewportTest, viewportUseZoomForDSF3) {
+  ViewportClient client;
+  client.set_device_scale_factor(3);
+  RegisterMockedHttpURLLoad("viewport/viewport-48.html");
+
+  FrameTestHelpers::WebViewHelper web_view_helper;
+  web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-48.html",
+                                    nullptr, &client, nullptr,
+                                    SetViewportSettings);
+
+  Page* page = web_view_helper.GetWebView()->GetPage();
+  // Initial width and height must be scaled by DSF when --use-zoom-for-dsf
+  // is enabled.
+  PageScaleConstraints constraints = RunViewportTest(page, 960, 1056);
+
+  // When --use-zoom-for-dsf is enabled,
+  // constraints layout width == 3000 * DSF = 9000
+  EXPECT_EQ(9000, constraints.layout_size.Width());
+  EXPECT_EQ(1056, constraints.layout_size.Height());
+  EXPECT_NEAR(1.0f, constraints.initial_scale, 0.01f);
+  EXPECT_NEAR(0.25f, constraints.minimum_scale, 0.01f);
+  EXPECT_NEAR(5.0f, constraints.maximum_scale, 0.01f);
+  EXPECT_TRUE(page->GetViewportDescription().user_zoom);
+}
+
+TEST_F(ViewportTest, viewportUseZoomForDSF4) {
+  ViewportClient client;
+  client.set_device_scale_factor(3);
+  RegisterMockedHttpURLLoad("viewport/viewport-39.html");
+
+  FrameTestHelpers::WebViewHelper web_view_helper;
+  web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-39.html",
+                                    nullptr, &client, nullptr,
+                                    SetViewportSettings);
+
+  Page* page = web_view_helper.GetWebView()->GetPage();
+  // Initial width and height must be scaled by DSF when --use-zoom-for-dsf
+  // is enabled.
+  PageScaleConstraints constraints = RunViewportTest(page, 960, 1056);
+
+  // When --use-zoom-for-dsf is enabled,
+  // constraints layout width == 200 * DSF = 600
+  EXPECT_EQ(600, constraints.layout_size.Width());
+  // When --use-zoom-for-dsf is enabled,
+  // constraints layout height == 700 * DSF = 2100
+  EXPECT_EQ(2100, constraints.layout_size.Height());
+  EXPECT_NEAR(1.6f, constraints.initial_scale, 0.01f);
+  EXPECT_NEAR(1.6f, constraints.minimum_scale, 0.01f);
+  EXPECT_NEAR(5.0f, constraints.maximum_scale, 0.01f);
+  EXPECT_TRUE(page->GetViewportDescription().user_zoom);
+}
+
 class ViewportHistogramsTest : public SimTest {
  public:
   ViewportHistogramsTest() {}
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp
index a76c66c..3804aec 100644
--- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp
@@ -46,7 +46,7 @@
   LayoutRect bounding_box(quads[0].BoundingBox());
 
   return bounding_box.Location() == LayoutPoint::Zero() &&
-         bounding_box.Size() == top_document.GetLayoutViewItem().Size();
+         bounding_box.Size() == top_document.GetLayoutView()->Size();
 }
 
 }  // namespace
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index 6c8aaf75..21d991586 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -548,10 +548,10 @@
        child = child->Tree().NextSibling()) {
     if (!child->IsLocalFrame())
       continue;
-    const LayoutItem owner_layout_item = ToLocalFrame(child)->OwnerLayoutItem();
-    if (owner_layout_item.IsNull())
+    auto* owner_layout_object = ToLocalFrame(child)->OwnerLayoutObject();
+    if (!owner_layout_object)
       continue;
-    const PaintLayer* containing_layer = owner_layout_item.EnclosingLayer();
+    const PaintLayer* containing_layer = owner_layout_object->EnclosingLayer();
     LayerFrameMap::iterator iter = map->find(containing_layer);
     if (iter == map->end())
       map->insert(containing_layer, HeapVector<Member<const LocalFrame>>())
@@ -638,7 +638,7 @@
         continue;
 
       const PaintLayer* child_layer =
-          child_frame->View()->GetLayoutViewItem().Layer();
+          child_frame->View()->GetLayoutView()->Layer();
       if (layers_with_rects.Contains(child_layer)) {
         LayerFrameMap new_layer_child_frame_map;
         MakeLayerChildFrameMap(child_frame, &new_layer_child_frame_map);
@@ -679,10 +679,10 @@
       if (layer->Parent()) {
         layer = layer->Parent();
       } else {
-        LayoutItem parent_doc_layout_item =
-            layer->GetLayoutObject().GetFrame()->OwnerLayoutItem();
-        if (!parent_doc_layout_item.IsNull()) {
-          layer = parent_doc_layout_item.EnclosingLayer();
+        auto* parent_doc_layout_object =
+            layer->GetLayoutObject().GetFrame()->OwnerLayoutObject();
+        if (parent_doc_layout_object) {
+          layer = parent_doc_layout_object->EnclosingLayer();
           touch_handler_in_child_frame = true;
         }
       }
@@ -693,7 +693,7 @@
   MapCoordinatesFlags flags = kUseTransforms;
   if (touch_handler_in_child_frame)
     flags |= kTraverseDocumentBoundaries;
-  PaintLayer* root_layer = main_frame->ContentLayoutItem().Layer();
+  PaintLayer* root_layer = main_frame->ContentLayoutObject()->Layer();
   LayoutGeometryMap geometry_map(flags);
   geometry_map.PushMappingsToAncestor(root_layer, nullptr);
   LayerFrameMap layer_child_frame_map;
@@ -815,10 +815,9 @@
   // FIXME: scheduleAnimation() is just a method of forcing the compositor to
   // realize that it needs to commit here. We should expose a cleaner API for
   // this.
-  LayoutViewItem layout_view =
-      page_->DeprecatedLocalMainFrame()->ContentLayoutItem();
-  if (!layout_view.IsNull() && layout_view.Compositor() &&
-      layout_view.Compositor()->StaleInCompositingMode())
+  auto* layout_view = page_->DeprecatedLocalMainFrame()->ContentLayoutObject();
+  if (layout_view && layout_view->Compositor() &&
+      layout_view->Compositor()->StaleInCompositingMode())
     page_->DeprecatedLocalMainFrame()->View()->ScheduleAnimation();
 
   touch_event_target_rects_are_dirty_ = true;
@@ -964,10 +963,10 @@
   DCHECK(IsMainThread());
 
   // We currently only support composited mode.
-  LayoutViewItem layout_view = frame_view->GetFrame().ContentLayoutItem();
-  if (layout_view.IsNull())
+  auto* layout_view = frame_view->GetFrame().ContentLayoutObject();
+  if (!layout_view)
     return false;
-  return layout_view.UsesCompositing();
+  return layout_view->UsesCompositing();
 }
 
 Region ScrollingCoordinator::ComputeShouldHandleScrollGestureOnMainThreadRegion(
@@ -1060,7 +1059,7 @@
   // implemented by replacing the root cc::layer with the video layer so doing
   // this optimization causes the compositor to think that there are no
   // handlers, therefore skip it.
-  if (!document->GetLayoutViewItem().Compositor()->InOverlayFullscreenVideo()) {
+  if (!document->GetLayoutView()->Compositor()->InOverlayFullscreenVideo()) {
     for (const auto& event_target : *targets) {
       EventTarget* target = event_target.key;
       Node* node = target->ToNode();
@@ -1074,8 +1073,8 @@
         continue;
       if (window || node == document || node == document->documentElement() ||
           node == document->body()) {
-        if (LayoutViewItem layout_view = document->GetLayoutViewItem()) {
-          layout_view.ComputeLayerHitTestRects(rects, supported_fast_actions);
+        if (auto* layout_view = document->GetLayoutView()) {
+          layout_view->ComputeLayerHitTestRects(rects, supported_fast_actions);
         }
         return;
       }
@@ -1193,11 +1192,10 @@
     return false;
 
   // FIXME(305811): Refactor for OOPI.
-  LayoutViewItem layout_view_item =
-      page_->DeprecatedLocalMainFrame()->View()->GetLayoutViewItem();
-  return layout_view_item.IsNull()
-             ? false
-             : scrollable_area == layout_view_item.Layer()->GetScrollableArea();
+  if (auto* layout_view =
+          page_->DeprecatedLocalMainFrame()->View()->GetLayoutView())
+    return scrollable_area == layout_view->Layer()->GetScrollableArea();
+  return false;
 }
 
 bool ScrollingCoordinator::IsForMainFrame(
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorTest.cpp
index 90a085f0..403be63 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorTest.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorTest.cpp
@@ -77,8 +77,8 @@
                                                 ->MainFrameImpl()
                                                 ->GetFrame()
                                                 ->View()
-                                                ->GetLayoutViewItem()
-                                                .Compositor()
+                                                ->GetLayoutView()
+                                                ->Compositor()
                                                 ->RootGraphicsLayer());
   }
 
@@ -750,10 +750,10 @@
   LocalFrameView* inner_frame_view = layout_embedded_content->ChildFrameView();
   ASSERT_TRUE(inner_frame_view);
 
-  LayoutViewItem inner_layout_view_item = inner_frame_view->GetLayoutViewItem();
-  ASSERT_FALSE(inner_layout_view_item.IsNull());
+  auto* inner_layout_view = inner_frame_view->GetLayoutView();
+  ASSERT_TRUE(inner_layout_view);
 
-  PaintLayerCompositor* inner_compositor = inner_layout_view_item.Compositor();
+  PaintLayerCompositor* inner_compositor = inner_layout_view->Compositor();
   ASSERT_TRUE(inner_compositor->InCompositingMode());
 
   GraphicsLayer* scroll_layer =
@@ -803,10 +803,10 @@
   LocalFrameView* inner_frame_view = layout_embedded_content->ChildFrameView();
   ASSERT_TRUE(inner_frame_view);
 
-  LayoutViewItem inner_layout_view_item = inner_frame_view->GetLayoutViewItem();
-  ASSERT_FALSE(inner_layout_view_item.IsNull());
+  auto* inner_layout_view = inner_frame_view->GetLayoutView();
+  ASSERT_TRUE(inner_layout_view);
 
-  PaintLayerCompositor* inner_compositor = inner_layout_view_item.Compositor();
+  PaintLayerCompositor* inner_compositor = inner_layout_view->Compositor();
   ASSERT_TRUE(inner_compositor->InCompositingMode());
 
   GraphicsLayer* scroll_layer =
@@ -982,10 +982,10 @@
   LocalFrameView* inner_frame_view = layout_embedded_content->ChildFrameView();
   ASSERT_TRUE(inner_frame_view);
 
-  LayoutViewItem inner_layout_view_item = inner_frame_view->GetLayoutViewItem();
-  ASSERT_FALSE(inner_layout_view_item.IsNull());
+  auto* inner_layout_view = inner_frame_view->GetLayoutView();
+  ASSERT_TRUE(inner_layout_view);
 
-  PaintLayerCompositor* inner_compositor = inner_layout_view_item.Compositor();
+  PaintLayerCompositor* inner_compositor = inner_layout_view->Compositor();
   ASSERT_TRUE(inner_compositor->InCompositingMode());
 
   GraphicsLayer* scroll_layer =
diff --git a/third_party/WebKit/Source/core/paint/CollapsedBorderPainter.cpp b/third_party/WebKit/Source/core/paint/CollapsedBorderPainter.cpp
index d18e827fc..e86ba97e2 100644
--- a/third_party/WebKit/Source/core/paint/CollapsedBorderPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/CollapsedBorderPainter.cpp
@@ -76,7 +76,7 @@
   if (start_.value) {
     const auto* cell_preceding = table_.CellPreceding(cell_);
     if (cell_.StartsAtSameRow(cell_preceding) &&
-        cell_preceding->RowSpan() >= cell_.RowSpan() &&
+        cell_preceding->ResolvedRowSpan() >= cell_.ResolvedRowSpan() &&
         // |cell_preceding| didn't paint the border if it is invisible.
         cell_preceding->StyleRef().Visibility() == EVisibility::kVisible) {
       start_.value = nullptr;
diff --git a/third_party/WebKit/Source/core/paint/EmbeddedContentPainter.cpp b/third_party/WebKit/Source/core/paint/EmbeddedContentPainter.cpp
index c8d4a9f..8d216571 100644
--- a/third_party/WebKit/Source/core/paint/EmbeddedContentPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/EmbeddedContentPainter.cpp
@@ -16,6 +16,7 @@
 #include "core/paint/ScrollableAreaPainter.h"
 #include "core/paint/SelectionPaintingUtils.h"
 #include "core/paint/TransformRecorder.h"
+#include "platform/graphics/paint/DisplayItemCacheSkipper.h"
 #include "platform/graphics/paint/DrawingRecorder.h"
 #include "platform/wtf/Optional.h"
 
@@ -31,6 +32,15 @@
 
 void EmbeddedContentPainter::Paint(const PaintInfo& paint_info,
                                    const LayoutPoint& paint_offset) {
+  // TODO(crbug.com/797779): For now embedded contents don't know whether
+  // they are painted in a fragmented context and may do something bad in a
+  // fragmented context, e.g. creating subsequences. Skip cache to avoid that.
+  // This will be unnecessary when the contents are fragment aware.
+  Optional<DisplayItemCacheSkipper> cache_skipper;
+  DCHECK(layout_embedded_content_.HasLayer());
+  if (layout_embedded_content_.Layer()->EnclosingPaginationLayer())
+    cache_skipper.emplace(paint_info.context);
+
   AdjustPaintOffsetScope adjustment(layout_embedded_content_, paint_info,
                                     paint_offset);
   const auto& local_paint_info = adjustment.GetPaintInfo();
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp
index 9c9cb03..35b3195a 100644
--- a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp
+++ b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp
@@ -255,7 +255,7 @@
       !RuntimeEnabledFeatures::PrintBrowserEnabled())
     return;
 
-  DCHECK(frame_view->GetFrame().OwnerLayoutItem().IsNull());
+  DCHECK(!frame_view->GetFrame().OwnerLayoutObject());
 
   IntRect paint_rect = dirty_rect;
   paint_rect.Intersect(frame_view->VisibleContentRect());
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index b21d32c..51f8f22 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -1025,10 +1025,10 @@
     composited_layer = layer->EnclosingLayerForPaintInvalidation();
     if (!composited_layer) {
       CHECK(layer->GetLayoutObject().GetFrame());
-      LayoutItem owner = layer->GetLayoutObject().GetFrame()->OwnerLayoutItem();
-      if (owner.IsNull())
+      auto* owner = layer->GetLayoutObject().GetFrame()->OwnerLayoutObject();
+      if (!owner)
         break;
-      layer = owner.EnclosingLayer();
+      layer = owner->EnclosingLayer();
     }
   }
   return composited_layer;
@@ -1861,7 +1861,7 @@
 
   // LayoutView should make sure to update layout before entering hit testing
   DCHECK(!GetLayoutObject().GetFrame()->View()->LayoutPending());
-  DCHECK(!GetLayoutObject().GetDocument().GetLayoutViewItem().NeedsLayout());
+  DCHECK(!GetLayoutObject().GetDocument().GetLayoutView()->NeedsLayout());
 
   const HitTestRequest& request = result.GetHitTestRequest();
   const HitTestLocation& hit_test_location = result.GetHitTestLocation();
@@ -3410,10 +3410,10 @@
 
     PaintLayer* container = layer->CompositingContainer();
     if (!container) {
-      LayoutItem owner = layer->GetLayoutObject().GetFrame()->OwnerLayoutItem();
-      if (owner.IsNull())
+      auto* owner = layer->GetLayoutObject().GetFrame()->OwnerLayoutObject();
+      if (!owner)
         break;
-      container = owner.EnclosingLayer();
+      container = owner->EnclosingLayer();
     }
 
     if (container->needs_repaint_)
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index a11e2174..31f5f8e 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -177,6 +177,9 @@
   if (context.Printing())
     return false;
 
+  if (context.GetPaintController().IsSkippingCache())
+    return false;
+
   if (!paint_layer.SupportsSubsequenceCaching())
     return false;
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 01c224c..efe57e8e 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -348,8 +348,7 @@
   IntRect rect = scrollbar_rect;
   rect.Move(ScrollbarOffset(scrollbar));
 
-  return view->GetFrameView()->ConvertFromLayoutItem(LayoutBoxItem(&Box()),
-                                                     rect);
+  return view->GetFrameView()->ConvertFromLayoutObject(Box(), rect);
 }
 
 IntPoint
@@ -362,8 +361,7 @@
 
   IntPoint point = scrollbar_point;
   point.Move(ScrollbarOffset(scrollbar));
-  return view->GetFrameView()->ConvertFromLayoutItem(LayoutBoxItem(&Box()),
-                                                     point);
+  return view->GetFrameView()->ConvertFromLayoutObject(Box(), point);
 }
 
 IntPoint
@@ -374,8 +372,8 @@
   if (!view)
     return parent_point;
 
-  IntPoint point = view->GetFrameView()->ConvertToLayoutItem(
-      LayoutBoxItem(&Box()), parent_point);
+  IntPoint point =
+      view->GetFrameView()->ConvertToLayoutObject(Box(), parent_point);
 
   point.Move(-ScrollbarOffset(scrollbar));
   return point;
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
index 50ab160..b618ab0 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -3714,6 +3714,27 @@
       GetLayoutObjectByElementId("absolute")->Container()->IsLayoutBlock());
 }
 
+TEST_P(PaintPropertyTreeBuilderTest, FrameUnderMulticol) {
+  SetBodyInnerHTML(R"HTML(
+    <div style='columns: 2; width: 200px; height: 100px; coloum-gap: 0'>
+      <iframe style='width: 50px; height: 150px'></iframe>
+    </div>
+  )HTML");
+  SetChildFrameHTML(R"HTML(
+    <style>
+      body { margin: 0; }
+      div { height: 60px; }
+    </style>
+    <div id='div1' style='background: blue'></div>
+    <div id='div2' style='background: green'></div>
+  )HTML");
+
+  // This should not crash on duplicated subsequences in the iframe.
+  GetDocument().View()->UpdateAllLifecyclePhases();
+
+  // TODO(crbug.com/797779): Add code to verify fragments under the iframe.
+}
+
 TEST_P(PaintPropertyTreeBuilderTest, Reflection) {
   SetBodyInnerHTML(
       "<div id='filter' style='-webkit-box-reflect: below; height:1000px;'>"
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
index bc2b110b..2b15899 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
@@ -3309,11 +3309,9 @@
   LayoutRect graphics_layer_bounds_in_root_view_space(
       graphics_layer_bounds_in_object_space);
   LayoutView* root_view = anchor_layout_object->View();
-  while (!root_view->GetFrame()->OwnerLayoutItem().IsNull()) {
-    root_view = LayoutAPIShim::LayoutObjectFrom(
-                    root_view->GetFrame()->OwnerLayoutItem())
-                    ->View();
-  }
+  while (root_view->GetFrame()->OwnerLayoutObject())
+    root_view = root_view->GetFrame()->OwnerLayoutObject()->View();
+
   anchor_layout_object->MapToVisualRectInAncestorSpace(
       root_view, graphics_layer_bounds_in_root_view_space);
   FloatRect visible_content_rect(graphics_layer_bounds_in_root_view_space);
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp
index 1aff9aa..1b62837 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp
@@ -198,7 +198,7 @@
       ScrollOffset(-5000, 0), kProgrammaticScroll);
   GetDocument().View()->UpdateAllLifecyclePhases();
 
-  PaintLayer* paint_layer = GetDocument().GetLayoutViewItem().Layer();
+  PaintLayer* paint_layer = GetDocument().GetLayoutView()->Layer();
   ASSERT_TRUE(paint_layer->GraphicsLayerBacking());
   ASSERT_TRUE(paint_layer->GetCompositedLayerMapping());
   // A scroll by -5000px is equivalent to a scroll by (10000 - 5000 - 800)px =
@@ -587,7 +587,7 @@
 
   GetDocument().View()->UpdateAllLifecyclePhases();
   GraphicsLayer* root_scrolling_layer =
-      GetDocument().GetLayoutViewItem().Layer()->GraphicsLayerBacking();
+      GetDocument().GetLayoutView()->Layer()->GraphicsLayerBacking();
   EXPECT_EQ(IntRect(0, 0, 800, 4600),
             PreviousInterestRect(root_scrolling_layer));
 
@@ -649,7 +649,7 @@
 
   GetDocument().View()->UpdateAllLifecyclePhases();
   GraphicsLayer* root_scrolling_layer =
-      GetDocument().GetLayoutViewItem().Layer()->GraphicsLayerBacking();
+      GetDocument().GetLayoutView()->Layer()->GraphicsLayerBacking();
   EXPECT_EQ(IntRect(0, 0, 800, 4600),
             PreviousInterestRect(root_scrolling_layer));
 
@@ -865,12 +865,12 @@
       ScrollOffset(0.0, 7500.0), kProgrammaticScroll);
   GetDocument().View()->UpdateAllLifecyclePhases();
 
-  ASSERT_TRUE(ChildDocument().View()->GetLayoutViewItem().HasLayer());
+  ASSERT_TRUE(ChildDocument().View()->GetLayoutView()->HasLayer());
   EXPECT_EQ(IntRect(0, 3500, 500, 4500),
             RecomputeInterestRect(ChildDocument()
                                       .View()
-                                      ->GetLayoutViewItem()
-                                      .EnclosingLayer()
+                                      ->GetLayoutView()
+                                      ->EnclosingLayer()
                                       ->GraphicsLayerBacking()));
 }
 
@@ -899,13 +899,13 @@
       ScrollOffset(0.0, 3000.0), kProgrammaticScroll);
   GetDocument().View()->UpdateAllLifecyclePhases();
 
-  ASSERT_TRUE(ChildDocument().View()->GetLayoutViewItem().HasLayer());
+  ASSERT_TRUE(ChildDocument().View()->GetLayoutView()->HasLayer());
   // The width is 485 pixels due to the size of the scrollbar.
   EXPECT_EQ(IntRect(0, 0, 500, 7500),
             RecomputeInterestRect(ChildDocument()
                                       .View()
-                                      ->GetLayoutViewItem()
-                                      .EnclosingLayer()
+                                      ->GetLayoutView()
+                                      ->EnclosingLayer()
                                       ->GraphicsLayerBacking()));
 }
 
@@ -2399,7 +2399,7 @@
   GetDocument().View()->UpdateAllLifecyclePhases();
   EXPECT_EQ(Color::kWhite, GetDocument().View()->BaseBackgroundColor());
   auto* view_layer =
-      GetDocument().GetLayoutViewItem().Layer()->GraphicsLayerBacking();
+      GetDocument().GetLayoutView()->Layer()->GraphicsLayerBacking();
   EXPECT_EQ(Color::kWhite, view_layer->BackgroundColor());
 
   Color base_background(255, 0, 0);
diff --git a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
index e00cce7..8a1d623 100644
--- a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
@@ -219,9 +219,9 @@
     // the middle of frame detach.
     // TODO(bbudge) Remove this check when trusted Pepper plugins are gone.
     if (local_frame->GetDocument()->IsActive() &&
-        !local_frame->ContentLayoutItem().IsNull()) {
-      local_frame->ContentLayoutItem()
-          .Compositor()
+        local_frame->ContentLayoutObject()) {
+      local_frame->ContentLayoutObject()
+          ->Compositor()
           ->UpdateIfNeededRecursiveInternal(target_state,
                                             compositing_reasons_stats);
     }
@@ -272,10 +272,10 @@
       continue;
     LocalFrame* local_frame = ToLocalFrame(child);
     if (local_frame->ShouldThrottleRendering() ||
-        local_frame->ContentLayoutItem().IsNull())
+        !local_frame->ContentLayoutObject())
       continue;
-    local_frame->ContentLayoutItem()
-        .Compositor()
+    local_frame->ContentLayoutObject()
+        ->Compositor()
         ->AssertNoUnresolvedDirtyBits();
   }
 #endif
@@ -800,8 +800,8 @@
   HTMLFrameOwnerElement* element =
       ToHTMLFrameOwnerElement(layout_object.GetNode());
   if (Document* content_document = element->contentDocument()) {
-    if (LayoutViewItem view = content_document->GetLayoutViewItem())
-      return view.Compositor();
+    if (auto* view = content_document->GetLayoutView())
+      return view->Compositor();
   }
   return nullptr;
 }
diff --git a/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp b/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp
index 0b3dc4a..5ca90e5 100644
--- a/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp
+++ b/third_party/WebKit/Source/core/scheduler/FrameThrottlingTest.cpp
@@ -1127,8 +1127,8 @@
   // Simulate the paint for a graphics layer being externally invalidated
   // (e.g., by video playback).
   frame_document->View()
-      ->GetLayoutViewItem()
-      .InvalidatePaintForViewAndCompositedLayers();
+      ->GetLayoutView()
+      ->InvalidatePaintForViewAndCompositedLayers();
 
   // The layer inside the throttled frame should not get painted.
   auto display_items2 = CompositeFrame();
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index 28c47d91..f2b46fc 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -1693,7 +1693,8 @@
 
   float autosized_font_size =
       TextAutosizer::ComputeAutosizedFontSize(size, multiplier);
-  desc.SetComputedSize(std::min(kMaximumAllowedFontSize, autosized_font_size));
+  float computed_size = autosized_font_size * EffectiveZoom();
+  desc.SetComputedSize(std::min(kMaximumAllowedFontSize, computed_size));
 
   SetFontDescription(desc);
   GetFont().Update(current_font_selector);
diff --git a/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp b/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
index 195c623d..bad12803 100644
--- a/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
@@ -479,7 +479,7 @@
     return 0;
 
   CSSToLengthConversionData conversion_data = CSSToLengthConversionData(
-      style, root_style, context_->GetDocument().GetLayoutViewItem(), 1.0f);
+      style, root_style, context_->GetDocument().GetLayoutView(), 1.0f);
   Length length = primitive_value.ConvertToLength(conversion_data);
   return ValueForLength(length, 1.0f, mode);
 }
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index e14ba37f..c5a5d5be 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -355,7 +355,7 @@
     return 0;
   }
 
-  return doc->GetLayoutViewItem().HitTestCount();
+  return doc->GetLayoutView()->HitTestCount();
 }
 
 unsigned Internals::hitTestCacheHits(Document* doc,
@@ -366,7 +366,7 @@
     return 0;
   }
 
-  return doc->GetLayoutViewItem().HitTestCacheHits();
+  return doc->GetLayoutView()->HitTestCacheHits();
 }
 
 Element* Internals::elementFromPoint(Document* doc,
@@ -381,7 +381,7 @@
     return nullptr;
   }
 
-  if (doc->GetLayoutViewItem().IsNull())
+  if (!doc->GetLayoutView())
     return nullptr;
 
   HitTestRequest::HitTestRequestType hit_type =
@@ -404,10 +404,10 @@
     return;
   }
 
-  if (doc->GetLayoutViewItem().IsNull())
+  if (!doc->GetLayoutView())
     return;
 
-  doc->GetLayoutViewItem().ClearHitTestCache();
+  doc->GetLayoutView()->ClearHitTestCache();
 }
 
 Element* Internals::innerEditorElement(Element* container,
@@ -2018,9 +2018,8 @@
     }
   }
 
-  LayoutViewItem view = document->GetLayoutViewItem();
-  if (!view.IsNull()) {
-    if (PaintLayerCompositor* compositor = view.Compositor()) {
+  if (auto* view = document->GetLayoutView()) {
+    if (PaintLayerCompositor* compositor = view->Compositor()) {
       if (GraphicsLayer* root_layer = compositor->RootGraphicsLayer()) {
         LayerRectList* rects = LayerRectList::Create();
         AccumulateLayerRectList(compositor, root_layer, rects);
@@ -2094,9 +2093,9 @@
 
   LocalFrame* frame = document->GetFrame();
   LocalFrameView* frame_view = document->View();
-  LayoutViewItem layout_view_item = document->GetLayoutViewItem();
+  auto* layout_view = document->GetLayoutView();
 
-  if (layout_view_item.IsNull())
+  if (!layout_view)
     return nullptr;
 
   float zoom_factor = frame->PageZoomFactor();
@@ -2125,7 +2124,7 @@
   HeapVector<Member<Node>> matches;
   HitTestResult result(request, point, top_padding, right_padding,
                        bottom_padding, left_padding);
-  layout_view_item.HitTest(result);
+  layout_view->HitTest(result);
   CopyToVector(result.ListBasedTestResult(), matches);
 
   return StaticNodeList::Adopt(matches);
@@ -2683,9 +2682,9 @@
     return;
   }
 
-  LayoutViewItem layout_view_item = document->GetLayoutViewItem();
-  if (!layout_view_item.IsNull())
-    layout_view_item.InvalidatePaintForViewAndCompositedLayers();
+  auto* layout_view = document->GetLayoutView();
+  if (layout_view)
+    layout_view->InvalidatePaintForViewAndCompositedLayers();
 }
 
 DOMRectList* Internals::draggableRegions(Document* document,
@@ -3057,7 +3056,7 @@
 void Internals::forceCompositingUpdate(Document* document,
                                        ExceptionState& exception_state) {
   DCHECK(document);
-  if (document->GetLayoutViewItem().IsNull()) {
+  if (!document->GetLayoutView()) {
     exception_state.ThrowDOMException(kInvalidAccessError,
                                       "The document provided is invalid.");
     return;
diff --git a/third_party/WebKit/Source/core/testing/sim/SimCompositor.cpp b/third_party/WebKit/Source/core/testing/sim/SimCompositor.cpp
index 72cf6b8d..fa0a89d 100644
--- a/third_party/WebKit/Source/core/testing/sim/SimCompositor.cpp
+++ b/third_party/WebKit/Source/core/testing/sim/SimCompositor.cpp
@@ -38,7 +38,7 @@
 
 static void PaintFrames(LocalFrame& root, SimDisplayItemList& display_list) {
   GraphicsLayer* layer =
-      root.View()->GetLayoutViewItem().Compositor()->RootGraphicsLayer();
+      root.View()->GetLayoutView()->Compositor()->RootGraphicsLayer();
   PaintLayers(*layer, display_list);
 }
 
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorker.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorker.cpp
index 84255df..e0c915e 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorker.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorker.cpp
@@ -21,7 +21,6 @@
 #include "core/workers/WorkerContentSettingsClient.h"
 #include "core/workers/WorkerScriptLoader.h"
 #include "platform/bindings/ScriptState.h"
-#include "platform/loader/fetch/ResourceFetcher.h"
 #include "platform/weborigin/SecurityPolicy.h"
 #include "public/platform/WebContentSettingsClient.h"
 #include "public/web/WebFrameClient.h"
@@ -81,7 +80,7 @@
     : AbstractWorker(context),
       script_url_(script_url),
       options_(options),
-      context_proxy_(CreateMessagingProxy(context)) {
+      context_proxy_(new DedicatedWorkerMessagingProxy(context, this)) {
   DCHECK(IsMainThread());
   DCHECK(script_url_.IsValid());
   DCHECK(context_proxy_);
@@ -166,10 +165,8 @@
   return context_proxy_->HasPendingActivity() || script_loader_;
 }
 
-DedicatedWorkerMessagingProxy* DedicatedWorker::CreateMessagingProxy(
-    ExecutionContext* context) {
-  DCHECK(IsMainThread());
-  Document* document = ToDocument(context);
+WorkerClients* DedicatedWorker::CreateWorkerClients() {
+  Document* document = ToDocument(GetExecutionContext());
   WebLocalFrameImpl* web_frame =
       WebLocalFrameImpl::FromFrame(document->GetFrame());
 
@@ -180,7 +177,8 @@
       *worker_clients);
   ProvideContentSettingsClientToWorker(
       worker_clients, web_frame->Client()->CreateWorkerContentSettingsClient());
-  return new DedicatedWorkerMessagingProxy(context, this, worker_clients);
+
+  return worker_clients;
 }
 
 void DedicatedWorker::OnResponse() {
@@ -221,7 +219,7 @@
   return std::make_unique<GlobalScopeCreationParams>(
       script_url_, GetExecutionContext()->UserAgent(),
       document->GetContentSecurityPolicy()->Headers().get(),
-      kReferrerPolicyDefault, starter_origin, nullptr /* worker_clients */,
+      kReferrerPolicyDefault, starter_origin, CreateWorkerClients(),
       document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
       std::make_unique<WorkerSettings>(document->GetSettings()),
       kV8CacheOptionsDefault,
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorker.h b/third_party/WebKit/Source/core/workers/DedicatedWorker.h
index a1552ec..f4feab5 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorker.h
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorker.h
@@ -26,6 +26,7 @@
 class ExceptionState;
 class ExecutionContext;
 class ScriptState;
+class WorkerClients;
 class WorkerScriptLoader;
 struct GlobalScopeCreationParams;
 
@@ -78,11 +79,7 @@
 
   std::unique_ptr<GlobalScopeCreationParams> CreateGlobalScopeCreationParams();
 
-  // Creates a proxy to allow communicating with the worker's global scope.
-  // DedicatedWorker does not take ownership of the created proxy. The proxy
-  // is expected to manage its own lifetime, and delete itself in response to
-  // terminateWorkerGlobalScope().
-  DedicatedWorkerMessagingProxy* CreateMessagingProxy(ExecutionContext*);
+  WorkerClients* CreateWorkerClients();
 
   // [classic script only]
   // Callbacks for |script_loader_|.
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp
index 65cb665..7d6782e 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.cpp
@@ -15,7 +15,6 @@
 #include "core/workers/DedicatedWorker.h"
 #include "core/workers/DedicatedWorkerObjectProxy.h"
 #include "core/workers/DedicatedWorkerThread.h"
-#include "core/workers/WorkerClients.h"
 #include "core/workers/WorkerInspectorProxy.h"
 #include "core/workers/WorkerOptions.h"
 #include "platform/CrossThreadFunctional.h"
@@ -34,9 +33,8 @@
 
 DedicatedWorkerMessagingProxy::DedicatedWorkerMessagingProxy(
     ExecutionContext* execution_context,
-    DedicatedWorker* worker_object,
-    WorkerClients* worker_clients)
-    : ThreadedMessagingProxyBase(execution_context, worker_clients),
+    DedicatedWorker* worker_object)
+    : ThreadedMessagingProxyBase(execution_context),
       worker_object_(worker_object) {
   worker_object_proxy_ =
       DedicatedWorkerObjectProxy::Create(this, GetParentFrameTaskRunners());
@@ -57,9 +55,6 @@
     return;
   }
 
-  // TODO(nhiroki): Move ReleaseWorkerClients() to DedicatedWorker for cleanup.
-  creation_params->worker_clients = ReleaseWorkerClients();
-
   InitializeWorkerThread(
       std::move(creation_params),
       CreateBackingThreadStartupData(ToIsolate(GetExecutionContext())));
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h
index a83cc300..b720f7c 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerMessagingProxy.h
@@ -26,7 +26,6 @@
 class DedicatedWorker;
 class DedicatedWorkerObjectProxy;
 class SerializedScriptValue;
-class WorkerClients;
 class WorkerOptions;
 
 // A proxy class to talk to the DedicatedWorkerGlobalScope on a worker thread
@@ -35,9 +34,7 @@
 class CORE_EXPORT DedicatedWorkerMessagingProxy
     : public ThreadedMessagingProxyBase {
  public:
-  DedicatedWorkerMessagingProxy(ExecutionContext*,
-                                DedicatedWorker*,
-                                WorkerClients*);
+  DedicatedWorkerMessagingProxy(ExecutionContext*, DedicatedWorker*);
   ~DedicatedWorkerMessagingProxy() override;
 
   // These methods should only be used on the parent context thread.
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
index ab40ced2..a923eac 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
@@ -111,8 +111,7 @@
  public:
   DedicatedWorkerMessagingProxyForTest(ExecutionContext* execution_context)
       : DedicatedWorkerMessagingProxy(execution_context,
-                                      nullptr /* workerObject */,
-                                      nullptr /* workerClients */) {
+                                      nullptr /* worker_object */) {
     worker_object_proxy_ = std::make_unique<DedicatedWorkerObjectProxyForTest>(
         this, GetParentFrameTaskRunners());
   }
diff --git a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
index a6ed380..00ae0ef7 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.cpp
@@ -28,33 +28,14 @@
 }  // namespace
 
 ThreadedMessagingProxyBase::ThreadedMessagingProxyBase(
-    ExecutionContext* execution_context,
-    WorkerClients* worker_clients)
+    ExecutionContext* execution_context)
     : execution_context_(execution_context),
-      worker_clients_(worker_clients),
       worker_inspector_proxy_(WorkerInspectorProxy::Create()),
       parent_frame_task_runners_(ParentFrameTaskRunners::Create(
           *ToDocument(execution_context_.Get())->GetFrame())),
-      asked_to_terminate_(false),
       keep_alive_(this) {
   DCHECK(IsParentContextThread());
   g_live_messaging_proxy_count++;
-
-  Document* document = ToDocument(execution_context_);
-  WebLocalFrameImpl* web_frame =
-      WebLocalFrameImpl::FromFrame(document->GetFrame());
-  // |web_frame| is null in some unit tests.
-  if (web_frame) {
-    std::unique_ptr<WebWorkerFetchContext> web_worker_fetch_context =
-        web_frame->Client()->CreateWorkerFetchContext();
-    DCHECK(web_worker_fetch_context);
-    web_worker_fetch_context->SetApplicationCacheHostID(
-        document->Fetcher()->Context().ApplicationCacheHostID());
-    web_worker_fetch_context->SetIsOnSubframe(
-        document->GetFrame() != document->GetFrame()->Tree().Top());
-    ProvideWorkerFetchContextToWorker(worker_clients,
-                                      std::move(web_worker_fetch_context));
-  }
 }
 
 ThreadedMessagingProxyBase::~ThreadedMessagingProxyBase() {
@@ -68,7 +49,6 @@
 
 void ThreadedMessagingProxyBase::Trace(blink::Visitor* visitor) {
   visitor->Trace(execution_context_);
-  visitor->Trace(worker_clients_);
   visitor->Trace(worker_inspector_proxy_);
 }
 
@@ -80,6 +60,22 @@
   Document* document = ToDocument(GetExecutionContext());
   KURL script_url = global_scope_creation_params->script_url.Copy();
 
+  WebLocalFrameImpl* web_frame =
+      WebLocalFrameImpl::FromFrame(document->GetFrame());
+  // |web_frame| is null in some unit tests.
+  if (web_frame) {
+    std::unique_ptr<WebWorkerFetchContext> web_worker_fetch_context =
+        web_frame->Client()->CreateWorkerFetchContext();
+    DCHECK(web_worker_fetch_context);
+    web_worker_fetch_context->SetApplicationCacheHostID(
+        document->Fetcher()->Context().ApplicationCacheHostID());
+    web_worker_fetch_context->SetIsOnSubframe(
+        document->GetFrame() != document->GetFrame()->Tree().Top());
+    ProvideWorkerFetchContextToWorker(
+        global_scope_creation_params->worker_clients,
+        std::move(web_worker_fetch_context));
+  }
+
   worker_thread_ = CreateWorkerThread();
   worker_thread_->Start(
       std::move(global_scope_creation_params), thread_startup_data,
@@ -188,12 +184,6 @@
   return worker_thread_.get();
 }
 
-WorkerClients* ThreadedMessagingProxyBase::ReleaseWorkerClients() {
-  DCHECK(IsParentContextThread());
-  DCHECK(worker_clients_);
-  return worker_clients_.Release();
-}
-
 bool ThreadedMessagingProxyBase::IsParentContextThread() const {
   // TODO(nhiroki): Nested worker is not supported yet, so the parent context
   // thread should be equal to the main thread (http://crbug.com/31666).
diff --git a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h
index 68526c2..802a56bd 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedMessagingProxyBase.h
@@ -10,7 +10,6 @@
 #include "core/inspector/ConsoleTypes.h"
 #include "core/workers/ParentFrameTaskRunners.h"
 #include "core/workers/WorkerBackingThreadStartupData.h"
-#include "core/workers/WorkerClients.h"
 #include "core/workers/WorkerThread.h"
 #include "platform/heap/SelfKeepAlive.h"
 #include "platform/wtf/Forward.h"
@@ -66,7 +65,7 @@
   virtual void Trace(blink::Visitor*);
 
  protected:
-  ThreadedMessagingProxyBase(ExecutionContext*, WorkerClients*);
+  explicit ThreadedMessagingProxyBase(ExecutionContext*);
 
   void InitializeWorkerThread(
       std::unique_ptr<GlobalScopeCreationParams>,
@@ -83,9 +82,6 @@
 
   bool AskedToTerminate() const { return asked_to_terminate_; }
 
-  // Transfers ownership of the clients to the caller.
-  WorkerClients* ReleaseWorkerClients();
-
   // Returns true if this is called on the parent context thread.
   bool IsParentContextThread() const;
 
@@ -93,7 +89,6 @@
   virtual std::unique_ptr<WorkerThread> CreateWorkerThread() = 0;
 
   Member<ExecutionContext> execution_context_;
-  Member<WorkerClients> worker_clients_;
   Member<WorkerInspectorProxy> worker_inspector_proxy_;
 
   // Accessed cross-thread when worker thread posts tasks to the parent.
@@ -101,7 +96,7 @@
 
   std::unique_ptr<WorkerThread> worker_thread_;
 
-  bool asked_to_terminate_;
+  bool asked_to_terminate_ = false;
 
   // Used to keep this alive until the worker thread gets terminated. This is
   // necessary because the co-owner (i.e., Worker or Worklet object) can be
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp
index 219a57e..8b15d200 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.cpp
@@ -23,11 +23,10 @@
 namespace blink {
 
 ThreadedWorkletMessagingProxy::ThreadedWorkletMessagingProxy(
-    ExecutionContext* execution_context,
-    WorkerClients* worker_clients)
-    : ThreadedMessagingProxyBase(execution_context, worker_clients) {}
+    ExecutionContext* execution_context)
+    : ThreadedMessagingProxyBase(execution_context) {}
 
-void ThreadedWorkletMessagingProxy::Initialize() {
+void ThreadedWorkletMessagingProxy::Initialize(WorkerClients* worker_clients) {
   DCHECK(IsMainThread());
   if (AskedToTerminate())
     return;
@@ -42,7 +41,7 @@
       std::make_unique<GlobalScopeCreationParams>(
           document->Url(), document->UserAgent(), csp->Headers().get(),
           document->GetReferrerPolicy(), document->GetSecurityOrigin(),
-          ReleaseWorkerClients(), document->AddressSpace(),
+          worker_clients, document->AddressSpace(),
           OriginTrialContext::GetTokens(document).get(),
           std::make_unique<WorkerSettings>(document->GetSettings()),
           kV8CacheOptionsDefault);
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h
index 9bd3afde..6dbd2e1c 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletMessagingProxy.h
@@ -30,12 +30,12 @@
   void WorkletObjectDestroyed() final;
   void TerminateWorkletGlobalScope() final;
 
-  void Initialize();
+  void Initialize(WorkerClients*);
 
   void Trace(blink::Visitor*) override;
 
  protected:
-  ThreadedWorkletMessagingProxy(ExecutionContext*, WorkerClients*);
+  explicit ThreadedWorkletMessagingProxy(ExecutionContext*);
 
   ThreadedWorkletObjectProxy& WorkletObjectProxy();
 
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
index 8ecda7f9..4eb520ee 100644
--- a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
+++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
@@ -159,9 +159,9 @@
 class ThreadedWorkletMessagingProxyForTest
     : public ThreadedWorkletMessagingProxy {
  public:
-  ThreadedWorkletMessagingProxyForTest(ExecutionContext* execution_context,
-                                       WorkerClients* worker_clients)
-      : ThreadedWorkletMessagingProxy(execution_context, worker_clients) {
+  explicit ThreadedWorkletMessagingProxyForTest(
+      ExecutionContext* execution_context)
+      : ThreadedWorkletMessagingProxy(execution_context) {
     worklet_object_proxy_ = std::make_unique<ThreadedWorkletObjectProxyForTest>(
         this, GetParentFrameTaskRunners());
   }
@@ -199,8 +199,8 @@
     Document* document = page_->GetFrame().GetDocument();
     document->SetURL(KURL("https://example.com/"));
     document->UpdateSecurityOrigin(SecurityOrigin::Create(document->Url()));
-    messaging_proxy_ = new ThreadedWorkletMessagingProxyForTest(
-        &page_->GetDocument(), WorkerClients::Create());
+    messaging_proxy_ =
+        new ThreadedWorkletMessagingProxyForTest(&page_->GetDocument());
     ThreadedWorkletThreadForTest::EnsureSharedBackingThread();
   }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index 152c31b1..40264dca 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -96,24 +96,6 @@
   return KURL(BaseURL(), url);
 }
 
-void WorkerGlobalScope::EvaluateClassicScript(
-    const KURL& script_url,
-    String source_code,
-    std::unique_ptr<Vector<char>> cached_meta_data) {
-  DCHECK(IsContextThread());
-  CachedMetadataHandler* handler = CreateWorkerScriptCachedMetadataHandler(
-      script_url, cached_meta_data.get());
-  DCHECK(!source_code.IsNull());
-  ReportingProxy().WillEvaluateWorkerScript(
-      source_code.length(),
-      cached_meta_data.get() ? cached_meta_data->size() : 0);
-  bool success = ScriptController()->Evaluate(
-      ScriptSourceCode(source_code, ScriptSourceLocationType::kUnknown, handler,
-                       script_url),
-      nullptr /* error_event */, v8_cache_options_);
-  ReportingProxy().DidEvaluateWorkerScript(success);
-}
-
 void WorkerGlobalScope::Dispose() {
   DCHECK(IsContextThread());
   closing_ = true;
@@ -313,6 +295,24 @@
   return const_cast<WorkerGlobalScope*>(this);
 }
 
+void WorkerGlobalScope::EvaluateClassicScript(
+    const KURL& script_url,
+    String source_code,
+    std::unique_ptr<Vector<char>> cached_meta_data) {
+  DCHECK(IsContextThread());
+  CachedMetadataHandler* handler = CreateWorkerScriptCachedMetadataHandler(
+      script_url, cached_meta_data.get());
+  DCHECK(!source_code.IsNull());
+  ReportingProxy().WillEvaluateWorkerScript(
+      source_code.length(),
+      cached_meta_data.get() ? cached_meta_data->size() : 0);
+  bool success = ScriptController()->Evaluate(
+      ScriptSourceCode(source_code, ScriptSourceLocationType::kUnknown, handler,
+                       script_url),
+      nullptr /* error_event */, v8_cache_options_);
+  ReportingProxy().DidEvaluateWorkerScript(success);
+}
+
 void WorkerGlobalScope::ImportModuleScript(
     const KURL& module_url_record,
     network::mojom::FetchCredentialsMode credentials_mode) {
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
index 58f7d39..09fd8bc1 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -78,10 +78,6 @@
   }
 
   // WorkerOrWorkletGlobalScope
-  void EvaluateClassicScript(
-      const KURL& script_url,
-      String source_code,
-      std::unique_ptr<Vector<char>> cached_meta_data) override;
   bool IsClosing() const final { return closing_; }
   void Dispose() override;
   WorkerThread* GetThread() const final { return thread_; }
@@ -127,6 +123,13 @@
   // EventTarget
   ExecutionContext* GetExecutionContext() const final;
 
+  // Evaluates the given top-level classic script.
+  virtual void EvaluateClassicScript(
+      const KURL& script_url,
+      String source_code,
+      std::unique_ptr<Vector<char>> cached_meta_data);
+
+  // Imports the top-level module script for |module_url_record|.
   void ImportModuleScript(const KURL& module_url_record,
                           network::mojom::FetchCredentialsMode);
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
index 2581ab9..fcce23f 100644
--- a/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerOrWorkletGlobalScope.h
@@ -60,14 +60,6 @@
   // 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
-  virtual void EvaluateClassicScript(
-      const KURL& script_url,
-      String source_code,
-      std::unique_ptr<Vector<char>> cached_meta_data) = 0;
-
   // Returns true when the WorkerOrWorkletGlobalScope is closing (e.g. via
   // WorkerGlobalScope#close() method). If this returns true, the worker is
   // going to be shutdown after the current task execution. Globals that
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index 57b4bdd..9a1ffc38 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -456,11 +456,11 @@
     String source_code,
     std::unique_ptr<Vector<char>> cached_meta_data,
     const v8_inspector::V8StackTraceId& stack_id) {
-  DCHECK(GlobalScope()->IsWorkerGlobalScope());
   WorkerThreadDebugger* debugger = WorkerThreadDebugger::From(GetIsolate());
   debugger->ExternalAsyncTaskStarted(stack_id);
-  GlobalScope()->EvaluateClassicScript(script_url, std::move(source_code),
-                                       std::move(cached_meta_data));
+  ToWorkerGlobalScope(GlobalScope())
+      ->EvaluateClassicScript(script_url, std::move(source_code),
+                              std::move(cached_meta_data));
   debugger->ExternalAsyncTaskFinished(stack_id);
 }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
index 41e04fa..617a09dd 100644
--- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.cpp
@@ -52,15 +52,6 @@
 
 WorkletGlobalScope::~WorkletGlobalScope() = default;
 
-void WorkletGlobalScope::EvaluateClassicScript(
-    const KURL& script_url,
-    String source_code,
-    std::unique_ptr<Vector<char>> cached_meta_data) {
-  // Worklet should evaluate a script as a module script (as opposed to a
-  // classic script).
-  NOTREACHED();
-}
-
 ExecutionContext* WorkletGlobalScope::GetExecutionContext() const {
   return const_cast<WorkletGlobalScope*>(this);
 }
diff --git a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
index f777704..813b55d 100644
--- a/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkletGlobalScope.h
@@ -36,11 +36,6 @@
 
   bool IsWorkletGlobalScope() const final { return true; }
 
-  void EvaluateClassicScript(
-      const KURL& script_url,
-      String source_code,
-      std::unique_ptr<Vector<char>> cached_meta_data) final;
-
   // Always returns false here as PaintWorkletGlobalScope and
   // AnimationWorkletGlobalScope don't have a #close() method on the global.
   // Note that AudioWorkletGlobal overrides this behavior.
diff --git a/third_party/WebKit/Source/devtools/.eslintignore b/third_party/WebKit/Source/devtools/.eslintignore
index 60f66fe..86b0332 100644
--- a/third_party/WebKit/Source/devtools/.eslintignore
+++ b/third_party/WebKit/Source/devtools/.eslintignore
@@ -1,13 +1,14 @@
+// Do not use glob pattern, this file is used by PRESUBMIT.py
+// to ignore these same files/folders for clang-format
 front_end/.eslintrc.js
-front_end/acorn/*
 front_end/audits2_worker/lighthouse/
 front_end/audits2/lighthouse/
-front_end/cm/*
-front_end/cm_headless/*
-front_end/cm_modes/*
-front_end/cm_web_modes/*
+front_end/cm/
+front_end/cm_headless/
+front_end/cm_modes/
+front_end/cm_web_modes/
 front_end/diff/diff_match_patch.js
-front_end/formatter_worker/acorn/*
-front_end/terminal/xterm.js/**
+front_end/formatter_worker/acorn/
+front_end/terminal/xterm.js/
 front_end/protocol_externs.js
-scripts/*
+scripts/
diff --git a/third_party/WebKit/Source/devtools/.eslintrc.js b/third_party/WebKit/Source/devtools/.eslintrc.js
index 1856537..9369e1ee 100644
--- a/third_party/WebKit/Source/devtools/.eslintrc.js
+++ b/third_party/WebKit/Source/devtools/.eslintrc.js
@@ -76,7 +76,11 @@
         // spacing details
         "space-infix-ops": 2,
         "space-in-parens": [2, "never"],
-        "space-before-function-paren": [2, "never"],
+        "space-before-function-paren": [2, {
+            "anonymous": "never",
+            "named": "never",
+            "asyncArrow": "always"
+        }],
         "no-whitespace-before-property": 2,
         "keyword-spacing": [2, {
             "overrides": {
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index 433c923..c744ad7 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -47,8 +47,11 @@
   "front_end/audits2/lighthouse/renderer/dom.js",
   "front_end/audits2/lighthouse/renderer/details-renderer.js",
   "front_end/audits2/lighthouse/renderer/category-renderer.js",
+  "front_end/audits2/lighthouse/renderer/crc-details-renderer.js",
   "front_end/audits2/lighthouse/renderer/report-renderer.js",
   "front_end/audits2/lighthouse/renderer/util.js",
+  "front_end/audits2/lighthouse/report-styles.css",
+  "front_end/audits2/lighthouse/templates.html",
   "front_end/audits2/module.json",
   "front_end/audits2_test_runner/Audits2TestRunner.js",
   "front_end/audits2_test_runner/module.json",
@@ -98,11 +101,13 @@
   "front_end/cm_modes/clojure.js",
   "front_end/cm_modes/coffeescript.js",
   "front_end/cm_modes/DefaultCodeMirrorMimeMode.js",
+  "front_end/cm_modes/jsx.js",
   "front_end/cm_modes/livescript.js",
   "front_end/cm_modes/module.json",
   "front_end/cm_modes/php.js",
   "front_end/cm_modes/python.js",
   "front_end/cm_modes/shell.js",
+  "front_end/cm_modes/stylus.js",
   "front_end/cm_web_modes/css.js",
   "front_end/cm_web_modes/htmlembedded.js",
   "front_end/cm_web_modes/htmlmixed.js",
@@ -217,6 +222,7 @@
   "front_end/elements/module.json",
   "front_end/elements/platformFontsWidget.css",
   "front_end/elements/PlatformFontsWidget.js",
+  "front_end/elements/propertiesWidget.css",
   "front_end/elements/PropertiesWidget.js",
   "front_end/elements/StylePropertyHighlighter.js",
   "front_end/elements/stylesSectionTree.css",
@@ -250,10 +256,10 @@
   "front_end/event_listeners/EventListenersView.js",
   "front_end/event_listeners/module.json",
   "front_end/extensions/ExtensionAPI.js",
-
   "front_end/extensions/ExtensionPanel.js",
   "front_end/extensions/ExtensionRegistryStub.js",
   "front_end/extensions/ExtensionServer.js",
+  "front_end/extensions/ExtensionTraceProvider.js",
   "front_end/extensions/ExtensionView.js",
   "front_end/extensions/module.json",
   "front_end/extensions_test_runner/ExtensionsNetworkTestRunner.js",
@@ -376,6 +382,7 @@
   "front_end/network/NetworkPanel.js",
   "front_end/network/NetworkTimeCalculator.js",
   "front_end/network/networkTimingTable.css",
+  "front_end/network/networkWaterfallColumn.css",
   "front_end/network/NetworkWaterfallColumn.js",
   "front_end/network/requestCookiesView.css",
   "front_end/network/RequestCookiesView.js",
@@ -549,6 +556,7 @@
   "front_end/sdk/ScreenCaptureModel.js",
   "front_end/sdk/Script.js",
   "front_end/sdk/SecurityOriginManager.js",
+  "front_end/sdk/ServerTiming.js",
   "front_end/sdk/ServiceWorkerCacheModel.js",
   "front_end/sdk/ServiceWorkerManager.js",
   "front_end/sdk/SourceMap.js",
@@ -600,6 +608,8 @@
   "front_end/sources/CallStackSidebarPane.js",
   "front_end/sources/CSSPlugin.js",
   "front_end/sources/dialog.css",
+  "front_end/sources/debuggerPausedMessage.css",
+  "front_end/sources/DebuggerPausedMessage.js",
   "front_end/sources/EditingLocationHistoryManager.js",
   "front_end/sources/eventListenerBreakpoints.css",
   "front_end/sources/EventListenerBreakpointsSidebarPane.js",
@@ -679,6 +689,7 @@
   "front_end/timeline_model/TracingLayerTree.js",
   "front_end/timeline/CountersGraph.js",
   "front_end/timeline/EventsTimelineTreeView.js",
+  "front_end/timeline/ExtensionTracingSession.js",
   "front_end/timeline/historyToolbarButton.css",
   "front_end/timeline/invalidationsTree.css",
   "front_end/timeline/module.json",
diff --git a/third_party/WebKit/Source/devtools/PRESUBMIT.py b/third_party/WebKit/Source/devtools/PRESUBMIT.py
index 9b4ddfc7..9ae3f15 100644
--- a/third_party/WebKit/Source/devtools/PRESUBMIT.py
+++ b/third_party/WebKit/Source/devtools/PRESUBMIT.py
@@ -59,12 +59,20 @@
     finally:
         sys.path = original_sys_path
 
-    check_formatting_process = popen(['git', 'cl', 'format', '--js', '--dry-run', input_api.PresubmitLocalPath()])
+    ignore_files = []
+    eslint_ignore_path = input_api.os_path.join(input_api.PresubmitLocalPath(), '.eslintignore')
+    with open(eslint_ignore_path, 'r') as ignore_manifest:
+        for line in ignore_manifest:
+            ignore_files.append(line.strip())
+    formattable_files = [affected_file for affected_file in affected_files
+                         if all(ignore_file not in affected_file for ignore_file in ignore_files)]
+
+    check_formatting_process = popen(['git', 'cl', 'format', '--js', '--dry-run'] + formattable_files)
     check_formatting_process.communicate()
     if check_formatting_process.returncode == 0:
         return []
 
-    format_args = ['git', 'cl', 'format', '--js', input_api.PresubmitLocalPath()]
+    format_args = ['git', 'cl', 'format', '--js'] + formattable_files
     format_process = popen(format_args)
     format_out, _ = format_process.communicate()
     if format_process.returncode != 0:
diff --git a/third_party/WebKit/Source/devtools/package.json b/third_party/WebKit/Source/devtools/package.json
index b9ffb03f..157c75ab 100644
--- a/third_party/WebKit/Source/devtools/package.json
+++ b/third_party/WebKit/Source/devtools/package.json
@@ -8,16 +8,13 @@
     "test": "node scripts/npm_test.js",
     "debug-test": "node scripts/npm_test.js --debug-devtools",
     "lint": "eslint front_end",
-    "format": "git cl format --js .",
     "closure": "python scripts/compile_frontend.py",
     "setup-dtrun": "cd scripts/devtools_run && npm link",
     "format-py": "yapf --exclude scripts/build/rjsmin.py -i --recursive scripts PRESUBMIT.py",
     "extract": "node scripts/extract_module/extract_module.js",
     "check-gn": "node scripts/check_gn.js",
     "check-json": "node scripts/json_validator/validate_module_json.js",
-    "check-descriptors": "node scripts/check_application_descriptors.js",
-    "migrate": "node scripts/migrate_test/migrate_test.js",
-    "test-summary": "node scripts/migrate_test/test_summary.js"
+    "check-descriptors": "node scripts/check_application_descriptors.js"
   },
   "repository": {
     "type": "git",
@@ -37,7 +34,6 @@
   },
   "homepage": "https://devtools.chrome.com",
   "devDependencies": {
-    "ajv": "^5.1.5",
-    "eslint": "3.10.0"
+    "ajv": "^5.1.5"
   }
 }
diff --git a/third_party/WebKit/Source/devtools/scripts/check_gn.js b/third_party/WebKit/Source/devtools/scripts/check_gn.js
index e942126..11c64b44 100644
--- a/third_party/WebKit/Source/devtools/scripts/check_gn.js
+++ b/third_party/WebKit/Source/devtools/scripts/check_gn.js
@@ -6,7 +6,8 @@
 const fs = require('fs');
 const path = require('path');
 
-const inspectorManifest = require('../front_end/inspector.json');
+const FRONTEND_PATH = path.resolve(__dirname, '..', 'front_end');
+const inspectorManifest = require(path.resolve(FRONTEND_PATH, 'inspector.json'));
 const utils = require('./utils');
 
 const gnPath = path.resolve(__dirname, '..', 'BUILD.gn');
@@ -16,6 +17,7 @@
 function main() {
   let errors = [];
   errors = errors.concat(checkNonAutostartNonRemoteModules());
+  errors = errors.concat(checkAllDevToolsFiles());
   if (errors.length) {
     console.log('DevTools BUILD.gn checker detected errors!');
     console.log(`There's an issue with: ${gnPath}`);
@@ -54,6 +56,43 @@
   return errors;
 }
 
+function checkAllDevToolsFiles() {
+  const errors = [];
+  const excludedFiles = ['InspectorBackendCommands.js', 'SupportedCSSProperties.js'];
+  const gnVariable = 'all_devtools_files';
+  const lines = selectGNLines(`${gnVariable} = [`, ']');
+  if (!lines.length) {
+    return [
+      'Could not identify all_devtools_files list in gn file',
+      'Please look at: ' + __filename,
+    ];
+  }
+  const gnFiles = new Set(lines);
+  var moduleFiles = [];
+  fs.readdirSync(FRONTEND_PATH).forEach(function(moduleName) {
+    const moduleJSONPath = path.join(FRONTEND_PATH, moduleName, 'module.json');
+    if (utils.isFile(moduleJSONPath)) {
+      const moduleJSON = require(moduleJSONPath);
+      const scripts = moduleJSON.scripts || [];
+      const resources = moduleJSON.resources || [];
+      const files = scripts.concat(resources)
+                        .map(relativePathFromBuildGN)
+                        .filter(file => excludedFiles.every(excludedFile => !file.includes(excludedFile)));
+      moduleFiles = moduleFiles.concat(files);
+
+      function relativePathFromBuildGN(filename) {
+        const relativePath = path.normalize(`front_end/${moduleName}/${filename}`);
+        return `"${relativePath}",`;
+      }
+    }
+  });
+  for (const file of moduleFiles) {
+    if (!gnFiles.has(file))
+      errors.push(`Missing file in BUILD.gn for ${gnVariable}: ` + file);
+  }
+  return errors;
+}
+
 function selectGNLines(startLine, endLine) {
   let lines = gnLines.map(line => line.trim());
   let startIndex = lines.indexOf(startLine);
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/format.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/format.js
deleted file mode 100644
index 0ef5f28..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/format.js
+++ /dev/null
@@ -1,173 +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.
-
-var childProcess = require('child_process');
-const path = require('path');
-const fs = require('fs');
-
-const recast = require('recast');
-var Linter = require('eslint').Linter;
-
-const utils = require('../utils');
-
-const TEMP_JS_FILE = path.resolve(__dirname, 'temp.js');
-const TEST_FUNCTION_SENTINEL = 'TEST_FUNCTION_SENTINEL();';
-
-function main() {
-  const args = process.argv;
-  if (args.length > 2) {
-    formatFile(args[2], true);
-    return;
-  }
-  walkSync('../../../../LayoutTests/http/tests/inspector');
-  walkSync('../../../../LayoutTests/http/tests/inspector-enabled');
-  walkSync('../../../../LayoutTests/http/tests/inspector-unit');
-  walkSync('../../../../LayoutTests/inspector-enabled');
-  walkSync('../../../../LayoutTests/inspector');
-}
-
-function walkSync(currentDirPath) {
-  fs.readdirSync(currentDirPath).forEach(function(name) {
-    if (name === 'resources') {
-      return;
-    }
-    let filePath = path.join(currentDirPath, name);
-    let stat = fs.statSync(filePath);
-    if (stat.isFile() && (filePath.endsWith('.html'))) {
-      try {
-        formatFile(filePath);
-      } catch (err) {
-        console.log(filePath, 'has err:', err);
-      }
-    } else if (stat.isDirectory()) {
-      walkSync(filePath);
-    }
-  });
-}
-
-function formatFile(filePath, isDryRun) {
-  let htmlContents = fs.readFileSync(filePath, 'utf-8');
-  const scriptContents = htmlContents.match(/<script.*?>([\S\s]*?)<\/script>/g);
-
-  let functionNode;
-  let testScript;
-  for (const script of scriptContents) {
-    const regex = /<script.*?>([\S\s]*?)<\/script>/
-    const innerScript = script.match(regex)[1];
-    if (!innerScript)
-      continue;
-    const ast = recast.parse(innerScript);
-    const sentinelNode = createExpressionNode(TEST_FUNCTION_SENTINEL);
-
-    let index =
-        ast.program.body.findIndex(n => n.type === 'VariableDeclaration' && n.declarations[0].id.name === 'test');
-    if (index > -1) {
-      functionNode = ast.program.body[index];
-      testScript = innerScript;
-    }
-
-    index = ast.program.body.findIndex(n => n.type === 'FunctionDeclaration' && n.id.name === 'test');
-    if (index > -1) {
-      functionNode = ast.program.body[index];
-      testScript = innerScript;
-    }
-  }
-
-  if (!functionNode) {
-    console.log('ERROR with: ', filePath);
-    return;
-  }
-
-  let locStart = functionNode.loc.start;
-  let locEnd = functionNode.loc.end;
-
-  (functionNode.comments || []).forEach(comment => {
-    if ((comment.loc.start.line === locStart.line && comment.loc.start.column < locStart.column) ||
-        comment.loc.start.line < locStart.line) {
-      locStart = comment.loc.start;
-    }
-    if ((comment.loc.end.line === locEnd.line && comment.loc.end.column > locEnd.column) ||
-        comment.loc.end.line > locEnd.line) {
-      locEnd = comment.loc.end;
-    }
-  });
-
-  let newTestScript = testScript.split('\n')
-                          .map((line, index) => {
-                            const lineNumber = index + 1;
-
-                            if (lineNumber === locStart.line) {
-                              return line.split('')
-                                  .map((char, columnNumber) => {
-                                    if (columnNumber === locStart.column) {
-                                      return '@@START_TEST_FUNCTION@@' + char;
-                                    }
-                                    return char;
-                                  })
-                                  .join('');
-                            }
-
-                            if (lineNumber === locEnd.line) {
-                              return line.split('')
-                                  .map((char, columnNumber) => {
-                                    if (columnNumber === locEnd.column - 1) {
-                                      return char + '@@END_TEST_FUNCTION@@';
-                                    }
-                                    return char;
-                                  })
-                                  .join('');
-                            }
-
-                            return line;
-                          })
-                          .join('\n');
-
-  newTestScript =
-      escapedReplace(newTestScript, /@@START_TEST_FUNCTION@@[\S\s]*@@END_TEST_FUNCTION@@/, TEST_FUNCTION_SENTINEL);
-  htmlContents = escapedReplace(htmlContents, testScript, newTestScript);
-
-  let linter = new Linter();
-  let result = linter.verifyAndFix(recast.print(functionNode).code, {
-    envs: ['browser'],
-    useEslintrc: false,
-    parserOptions: {
-      ecmaVersion: 8,
-    },
-    rules: {
-      semi: 2,
-    }
-  });
-  if (result.messages.length) {
-    console.log('Issue with eslint', result.messages, 'for file: ', filePath);
-    process.exit(1);
-  }
-  fs.writeFileSync(TEMP_JS_FILE, result.output);
-  const formattedTestcode = shellOutput(`clang-format ${TEMP_JS_FILE} --style=FILE`);
-  fs.unlinkSync(TEMP_JS_FILE);
-  const newContents = escapedReplace(htmlContents, TEST_FUNCTION_SENTINEL, formattedTestcode);
-
-  if (isDryRun) {
-    console.log(newContents);
-    return;
-  }
-  fs.writeFileSync(filePath, newContents);
-}
-
-main();
-
-function shellOutput(command) {
-  return childProcess.execSync(command).toString();
-}
-
-function createExpressionNode(code) {
-  return recast.parse(code).program.body[0];
-}
-
-function escapedReplace(source, target, replacement) {
-  replacement = replacement
-                    // Need to escape $ symbol
-                    .split('$')
-                    .join('$$');
-  return source.replace(target, replacement);
-}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_helpers.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_helpers.js
deleted file mode 100644
index 6175a39..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_helpers.js
+++ /dev/null
@@ -1,515 +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.
-
-'use strict';
-
-const fs = require('fs');
-const path = require('path');
-
-const recast = require('recast');
-const types = recast.types;
-const b = recast.types.builders;
-
-const utils = require('../utils');
-const migrateUtils = require('./migrate_utils');
-/**
- * propertyToNamespace {[testProperty:string]: {namespace: string, done: boolean}}
- * Moved file
- * {ETR.something: ETR}
- * Existing helper module
- * {ConsoleTestRunner.something: CTR}
- */
-const BUILD_GN_PATH = path.resolve(__dirname, '..', '..', 'BUILD.gn');
-const DRY_RUN = process.env.DRY_RUN || false;
-const FRONT_END_PATH = path.resolve(__dirname, '..', '..', 'front_end');
-
-function main() {
-  const helperPaths = scanHelpers();
-  const helpers = mapTestFilesToHelperModules(helperPaths);
-  transformHelperCode(helpers);
-  if (DRY_RUN) {
-    return;
-  }
-  updateModuleDescriptors(helpers);
-  const newModules = new Set();
-  const helperFiles = [];
-  for (const h of helpers) {
-    newModules.add(h.helperModule);
-    helperFiles.push(h.newPath);
-  }
-  const existingModulesJson = require(path.resolve(FRONT_END_PATH, 'integration_test_runner.json'));
-  for (const module of existingModulesJson.modules) {
-    newModules.delete(module.name)
-  }
-  updateApplicationDescriptor('integration_test_runner.json', newModules);
-  updateBuildGN(newModules, helperFiles);
-  writeNewHelpers(helpers);
-}
-
-function updateBuildGN(newModuleSet, helperFiles) {
-  let content = fs.readFileSync(BUILD_GN_PATH).toString();
-  helperFiles =
-      helperFiles.map(p => p.split('/').slice(-3).join('/')).filter(p => content.indexOf(p) === -1).map(p => `"${p}",`);
-
-  let newContent = addContentToLinesInSortedOrder({
-    content,
-    startLine: 'all_devtools_files = [',
-    endLine: ']',
-    linesToInsert:
-        [...newModuleSet].map(module => `"front_end/${module}/module.json",`).filter(p => content.indexOf(p) === -1),
-  });
-
-  newContent = addContentToLinesInSortedOrder({
-    content: newContent,
-    startLine: 'all_devtools_files = [',
-    endLine: ']',
-    linesToInsert: helperFiles,
-  });
-
-  fs.writeFileSync(BUILD_GN_PATH, newContent);
-
-  function top(array) {
-    return array[array.length - 1];
-  }
-
-  function addContentToLinesInSortedOrder({content, startLine, endLine, linesToInsert}) {
-    if (linesToInsert.length === 0)
-      return content;
-    let lines = content.split('\n');
-    let seenStartLine = false;
-    let contentStack = linesToInsert.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).reverse();
-    for (var i = 0; i < lines.length; i++) {
-      let line = lines[i].trim();
-      let nextLine = lines[i + 1].trim();
-      if (line === startLine)
-        seenStartLine = true;
-
-      if (line === endLine && seenStartLine)
-        break;
-
-      if (!seenStartLine)
-        continue;
-
-      const nextContent = top(contentStack) ? top(contentStack).toLowerCase() : '';
-      if ((line === startLine || nextContent >= line.toLowerCase()) &&
-          (nextLine === endLine || nextContent <= nextLine.toLowerCase()))
-        lines.splice(i + 1, 0, contentStack.pop());
-    }
-    if (contentStack.length)
-      lines.splice(i, 0, ...contentStack);
-    return lines.join('\n');
-  }
-}
-
-function updateApplicationDescriptor(descriptorFileName, newModuleSet) {
-  let descriptorPath = path.join(FRONT_END_PATH, descriptorFileName);
-  let newModules = [...newModuleSet];
-  if (newModules.length === 0)
-    return;
-  let includeNewModules = (acc, line) => {
-    if (line === '  "modules" : [') {
-      acc.push(line);
-      return acc.concat(newModules.map((m, i) => {
-        // Need spacing to preserve indentation
-        let string;
-        string = `    { "name": "${m}" },`;
-        return string;
-      }));
-    }
-    return acc.concat([line]);
-  };
-  let lines = fs.readFileSync(descriptorPath).toString().split('\n').reduce(includeNewModules, []);
-  fs.writeFileSync(descriptorPath, lines.join('\n'));
-}
-
-function updateModuleDescriptors(helpers) {
-  const dependenciesByModule = {
-    application_test_runner: ['resources', 'console_test_runner', 'sources', 'sources_test_runner'],
-    audits_test_runner: ['audits'],
-    bindings_test_runner: ['workspace', 'diff', 'bindings', 'persistence'],
-    coverage_test_runner: ['coverage', 'sources_test_runner'],
-    device_mode_test_runner: ['emulation'],
-    elements_test_runner: ['animation'],
-    accessibility_test_runner: ['accessibility', 'elements_test_runner'],
-    extensions_test_runner: ['extensions'],
-    layers_test_runner: ['layers', 'components'],
-    network_test_runner: ['product_registry_impl', 'console_test_runner'],
-    performance_test_runner: ['timeline_model', 'timeline'],
-    profiler_test_runner: ['profiler', 'data_grid', 'heap_snapshot_worker'],
-    security_test_runner: ['security'],
-    sources_test_runner: ['source_frame', 'text_utils'],
-    sass_test_runner: ['sass'],
-  };
-
-  for (const helper of helpers) {
-    const parentPath = path.dirname(helper.newPath);
-    if (!utils.isDir(parentPath))
-      fs.mkdirSync(parentPath);
-    const modulePath = path.resolve(parentPath, 'module.json');
-    const additionalDependencies = dependenciesByModule[helper.helperModule] || [];
-    let contents = {
-      dependencies: ['test_runner', 'integration_test_runner'],
-      scripts: [],
-    };
-    if (utils.isFile(modulePath)) {
-      contents = JSON.parse(fs.readFileSync(modulePath, 'utf-8'));
-    }
-    contents.dependencies = unique(contents.dependencies.concat(additionalDependencies));
-    const filename = path.basename(helper.newPath);
-    if (contents.scripts.indexOf(filename) === -1)
-      contents.scripts.push(filename);
-    contents.skip_compilation = contents.skip_compilation || [];
-    contents.skip_compilation.push(filename);
-    fs.writeFileSync(modulePath, stringifyJSON(contents));
-  }
-
-  function unique(array) {
-    const set = new Set();
-    for (const el of array)
-      set.add(el);
-    return Array.from(set);
-  }
-
-  function stringifyJSON(obj) {
-    return unicodeEscape(JSON.stringify(obj, null, 2) + '\n');
-  }
-
-  // http://stackoverflow.com/questions/7499473/need-to-escape-non-ascii-characters-in-javascript
-  function unicodeEscape(string) {
-    function padWithLeadingZeros(string) {
-      return new Array(5 - string.length).join('0') + string;
-    }
-
-    function unicodeCharEscape(charCode) {
-      return '\\u' + padWithLeadingZeros(charCode.toString(16));
-    }
-
-    return string.split('')
-        .map(function(char) {
-          var charCode = char.charCodeAt(0);
-          return charCode > 127 ? unicodeCharEscape(charCode) : char;
-        })
-        .join('');
-  }
-}
-
-function transformHelperCode(helpers) {
-  const boilerplate = `// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-`;
-
-  const propertyToNamespace = scrapeTestProperties(helpers);
-
-  for (const helper of helpers) {
-    const ast = recast.parse(helper.originalContents);
-    unwrapInitializeFunction(ast);
-
-    recast.visit(ast, {
-      /**
-     * Remove all deprecated API calls
-     */
-      visitIdentifier: function(path) {
-        if (path.parentPath && path.parentPath.value && path.parentPath.value.object &&
-            path.parentPath.value.object.name === 'InspectorTest' && path.value.name !== 'InspectorTest') {
-          const identifier = path.value.name;
-          if (identifier === 'preloadPanel' || identifier === 'preloadModule') {
-            console.log('helper: ', helper.originalPath, recast.print(path.parentPath.parentPath.value).code)
-            //  Removes these types of calls: InspectorTest.preloadPanel("elements");
-            path.parentPath.parentPath.prune();
-          }
-        }
-        return false;
-      },
-      /**
-     * Skip already ported API calls
-     */
-      visitAssignmentExpression: function(path) {
-        if (!path.value.left.object) {
-          return false;
-        }
-        const namespace = path.value.left.object.name;
-        const propertyName = path.value.left.property.name;
-        if (namespace === 'InspectorTest' && propertyToNamespace.get(propertyName).done) {
-          // console.log('pruning', propertyName);
-          path.prune();
-        }
-        this.traverse(path);
-      },
-    });
-
-    /**
-   * Migrate all the call sites from InspectorTest to .*TestRunner
-   */
-    recast.visit(ast, {
-      visitIdentifier: function(path) {
-        if (path.parentPath && path.parentPath.value && path.parentPath.value.object &&
-            path.parentPath.value.object.name === 'InspectorTest' && path.value.name !== 'InspectorTest') {
-          if (!propertyToNamespace.get(path.value.name)) {
-            throw new Error('Could not find identifier for: ' + path.value.name);
-          }
-          const newParentIdentifier = propertyToNamespace.get(path.value.name).namespace;
-          path.parentPath.value.object.name = newParentIdentifier;
-        }
-        return false;
-      }
-    });
-
-    /**
-   * Migrate all the .bind call sites
-   * Example: SourcesTestRunner.waitUntilPaused.bind(InspectorTest, didPause)
-   */
-    recast.visit(ast, {
-      visitCallExpression: function(path) {
-        const node = path.value;
-        if (node.callee.property && node.callee.property.name === 'bind') {
-          const code = recast.prettyPrint(node);
-          if (node.arguments[0].name === 'InspectorTest') {
-            node.arguments[0].name = node.callee.object.object.name;
-          }
-        }
-        this.traverse(path);
-      }
-    });
-
-
-    const existingContents = utils.isFile(helper.newPath) ? fs.readFileSync(helper.newPath) : '';
-    if (existingContents)
-      helper.contents = existingContents + '\n' + print(ast);
-    else
-      helper.contents = boilerplate + print(ast);
-  }
-
-  function unwrapInitializeFunction(ast) {
-    // Handle function expression
-    let index = ast.program.body.findIndex(
-        n => n.type === 'VariableDeclaration' && n.declarations[0].id.name.indexOf('initialize_') !== -1);
-    if (index > -1) {
-      const otherNodes = ast.program.body.filter((_, i) => i !== index);
-      const testFunctionNode = ast.program.body[index];
-      ast.program.body = testFunctionNode.declarations[0].init.body.body;
-      inspectedPageNodes(otherNodes);
-      return;
-    }
-
-    // Handle function declaration
-    index =
-        ast.program.body.findIndex(n => n.type === 'FunctionDeclaration' && n.id.name.indexOf('initialize_') !== -1);
-    if (index > -1) {
-      const otherNodes = ast.program.body.filter((_, i) => i !== index);
-      const testFunctionNode = ast.program.body[index];
-      ast.program.body.splice(index, 1);
-      ast.program.body = testFunctionNode.body.body;
-      inspectedPageNodes(otherNodes);
-    }
-
-    function inspectedPageNodes(otherNodes) {
-      if (!otherNodes.length)
-        return;
-      const code = otherNodes.map(node => print(node)).join('\n').slice(0, -1);
-      ast.program.body.push(createAwaitExpressionNode(`await TestRunner.evaluateInPagePromise(\`
-${code.split('\n').map(x => x.length ? '    ' + x : x).join('\n')}
-  \`)`));
-    }
-  }
-}
-
-function print(ast) {
-  /**
-   * Not using clang-format because certain tests look bad when formatted by it.
-   * Recast pretty print is smarter about preserving existing spacing.
-   */
-  let code = recast.prettyPrint(ast, {tabWidth: 2, wrapColumn: 120, quote: 'single'}).code;
-  code = code.replace(/(\/\/\#\s*sourceURL=[\w-]+)\.html/, '$1.js');
-  code = code.replace(/\s*\$\$SECRET_IDENTIFIER_FOR_LINE_BREAK\$\$\(\);/g, '\n');
-  return code + '\n';
-}
-
-function scrapeTestProperties(helpers) {
-  const propertyToNamespace = new Map();
-  scrapeOriginalHelpers(propertyToNamespace, helpers);
-  scrapeMovedHelpers(propertyToNamespace);
-
-  // Manual overrides
-  propertyToNamespace.set('consoleModel', {
-    namespace: 'ConsoleModel',
-    done: true,
-  });
-  propertyToNamespace.set('networkLog', {
-    namespace: 'NetworkLog',
-    done: true,
-  });
-  return propertyToNamespace;
-}
-
-function scrapeMovedHelpers(propertyToNamespace) {
-  const testRunnerPaths = fs.readdirSync(FRONT_END_PATH)
-                              .filter(folder => folder.indexOf('test_runner') !== -1)
-                              .map(folder => path.resolve(FRONT_END_PATH, folder))
-                              .filter(file => utils.isDir(file));
-
-  testRunnerPaths.forEach((helperPath) => {
-    const files = fs.readdirSync(helperPath)
-                      .filter(file => file.indexOf('TestRunner') !== -1)
-                      .map(file => path.resolve(helperPath, file));
-    files.forEach(file => scrapeTestHelperIdentifiers(file));
-  });
-
-  function scrapeTestHelperIdentifiers(filePath) {
-    var content = fs.readFileSync(filePath).toString();
-    var lines = content.split('\n');
-    for (var line of lines) {
-      var line = line.trim();
-      if (line.indexOf('TestRunner.') === -1)
-        continue;
-      var match = line.match(/^\s*(\b\w*TestRunner.[a-z_A-Z0-9]+)\s*(\=[^,}]|[;])/) ||
-          line.match(/^(TestRunner.[a-z_A-Z0-9]+)\s*\=$/);
-      if (!match)
-        continue;
-      var name = match[1];
-      var components = name.split('.');
-      if (components.length !== 2)
-        continue;
-      propertyToNamespace.set(components[1], {
-        namespace: components[0],
-        done: true,
-      });
-    }
-  }
-}
-
-function scrapeOriginalHelpers(propertyToNamespace, helpers) {
-  const testRunnerPaths = fs.readdirSync(FRONT_END_PATH)
-                              .filter(folder => folder.indexOf('test_runner') !== -1)
-                              .map(folder => path.resolve(FRONT_END_PATH, folder));
-
-  for (const helper of helpers) {
-    scrapeTestHelperIdentifiers(helper.originalContents, helper.namespace);
-  }
-
-  function scrapeTestHelperIdentifiers(content, namespace) {
-    var lines = content.split('\n');
-    for (var line of lines) {
-      var line = line.trim();
-      if (line.indexOf('InspectorTest.') === -1)
-        continue;
-      var match = line.match(/^\s*(\b\w*InspectorTest.[a-z_A-Z0-9]+)\s*(\=[^,}]|[;])/) ||
-          line.match(/^(InspectorTest.[a-z_A-Z0-9]+)\s*\=$/);
-      if (!match)
-        continue;
-      var name = match[1];
-      var components = name.split('.');
-      if (components.length !== 2)
-        continue;
-      propertyToNamespace.set(components[1], {
-        namespace: namespace,
-        done: false,
-      });
-    }
-  }
-}
-
-// Causes too much diff in test expectations
-// function appendComment(helpers) {
-//   for (const {originalPath, originalContents, helperModule, filename} of helpers) {
-//     const comment = `// This file is being deprecated and is moving to front_end/${helperModule}/${filename}
-// // Please see crbug.com/667560 for more details\n\n`;
-//     fs.writeFileSync(originalPath, comment + originalContents);
-//   }
-// }
-
-function writeNewHelpers(helpers) {
-  for (const {contents, helperModule, filename} of helpers) {
-    const modulePath = path.resolve(FRONT_END_PATH, helperModule);
-    if (!utils.isDir(modulePath))
-      fs.mkdirSync(modulePath);
-    const destPath = path.resolve(modulePath, filename);
-    fs.writeFileSync(destPath, contents);
-  }
-}
-
-function mapTestFilesToHelperModules(helperPaths) {
-  const helpers = new Set();
-  for (const p of helperPaths) {
-    const inputFilename = path.basename(p);
-    let namespacePrefix = path.basename(p)
-                              .split('-test')[0]
-                              .split('-')
-                              .map(a => a.substring(0, 1).toUpperCase() + a.substring(1))
-                              .join('');
-    let filenamePrefix = namespacePrefix;
-
-    // Already migrated or n/a
-    if (namespacePrefix === 'Inspector' || namespacePrefix === 'Console' || namespacePrefix === 'Protocol' ||
-        namespacePrefix === 'ExampleFilesetFor') {
-      continue;
-    }
-
-    // Needs to be manually migrated
-    if (namespacePrefix === 'CspInline' || namespacePrefix === 'Stacktrace')
-      continue;
-
-    const res = migrateUtils.mapTestFilename(inputFilename);
-    namespacePrefix = res.namespacePrefix;
-    filenamePrefix = res.filenamePrefix;
-
-    const contents = fs.readFileSync(p, 'utf-8');
-    const namespace = namespacePrefix + 'TestRunner';
-    const helperModule = namespacePrefix === 'SASS' ?
-        'sass_test_runner' :
-        namespacePrefix === '' ? 'integration_test_runner' :
-                                 namespace.replace(/([A-Z])/g, '_$1').replace(/^_/, '').toLowerCase();
-    const filename = filenamePrefix + 'TestRunner.js';
-    helpers.add({
-      originalPath: p,
-      newPath: path.resolve(FRONT_END_PATH, helperModule, filename),
-      namespace,
-      helperModule,
-      filename,
-      originalContents: contents,
-      contents,
-    });
-  }
-  return helpers;
-}
-
-main();
-
-function scanHelpers() {
-  const paths = [];
-
-  const http_root = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', 'http', 'tests', 'inspector');
-  const non_http_root = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', 'inspector');
-  scan(http_root);
-  scan(non_http_root);
-
-  function scan(p) {
-    const files = fs.readdirSync(p).map(file => path.resolve(p, file));
-    for (const file of files) {
-      if (utils.isDir(file))
-        scan(file);
-      else if (file.indexOf('editing-test-suite.js') !== -1)
-        paths.push(file);
-    }
-  }
-
-  return paths;
-}
-
-/**
- * Hack to quickly create an AST node
- */
-function createAwaitExpressionNode(code) {
-  return recast
-      .parse(`TestRunner.initAsync(async function(){
-  ${code}
-  });`)
-      .program.body[0];
-}
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_test.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_test.js
deleted file mode 100644
index 65f49f3..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_test.js
+++ /dev/null
@@ -1,546 +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.
-
-'use strict';
-
-var childProcess = require('child_process');
-const fs = require('fs');
-const path = require('path');
-
-const cheerio = require('cheerio');
-const mkdirp = require('mkdirp');
-const recast = require('recast');
-const types = recast.types;
-const b = recast.types.builders;
-
-const migrateUtils = require('./migrate_utils');
-const utils = require('../utils');
-
-const RUN_TEST_REGEX = /\s*runTest\(\);?\n*/
-const DRY_RUN = process.env.DRY_RUN || false;
-const FRONT_END_PATH = path.resolve(__dirname, '..', '..', 'front_end');
-const LINE_BREAK = '$$SECRET_IDENTIFIER_FOR_LINE_BREAK$$();';
-const LAYOUT_TESTS_PATH = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests');
-const FLAG_EXPECTATIONS_PATH = path.resolve(LAYOUT_TESTS_PATH, 'FlagExpectations');
-const TEMP_JS_FILE = path.resolve(__dirname, 'temp.js');
-
-function main() {
-  const files = process.argv.slice(2);
-  const inputPaths = files.map(p => path.isAbsolute(p) ? p : path.resolve(process.cwd(), p));
-  const identifierMap = generateTestHelperMap();
-
-  for (const inputPath of inputPaths) {
-    migrateTest(inputPath, identifierMap);
-  }
-  console.log(`Finished migrating ${inputPaths.length} tests`);
-}
-
-main();
-
-function getPrologue(inputExpectationsPath, bodyText) {
-  const expectations = fs.readFileSync(inputExpectationsPath, 'utf-8').split('\n');
-  let prologueBeginning = bodyText.split('\n')[0];
-  for (const line of expectations) {
-    if (line.startsWith(prologueBeginning)) {
-      return line;
-    }
-  }
-
-  prologueBeginning = bodyText.split(' ')[0];
-  for (const line of expectations) {
-    if (line.startsWith(prologueBeginning)) {
-      return line;
-    }
-  }
-  return '';
-}
-
-function appendBugLink(prologue, text) {
-  var match;
-  if (match = text.match(/crbug.com\/\d+/)) {
-    if (!prologue.includes(match[0]))
-      return prologue + ' ' + match[0];
-  }
-  if (match = text.match(/https:\/\/bugs.webkit.org\/show_bug.cgi\?id=\d+/)) {
-    if (!prologue.includes(match[0]))
-      return prologue + ' ' + match[0];
-  }
-  return prologue;
-}
-
-function escapeRegExp(str) {
-  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
-}
-
-function migrateTest(inputPath, identifierMap) {
-  console.log('Starting to migrate: ', inputPath);
-
-  const htmlTestFile = fs.readFileSync(inputPath, 'utf-8');
-  const $ = cheerio.load(htmlTestFile);
-
-  const inputFilename = path.basename(inputPath);
-  const inputExpectationsPath = inputPath.replace('.js', '-expected.txt').replace('.html', '-expected.txt');
-  const bodyText = $('body').text().trim();
-
-  const prologue = appendBugLink(getPrologue(inputExpectationsPath, bodyText), htmlTestFile);
-
-  const stylesheetPaths = $('link').toArray().filter(l => l.attribs.rel === 'stylesheet').map(l => l.attribs.href);
-  const onloadFunctionName = $('body')[0].attribs.onload ? $('body')[0].attribs.onload.slice(0, -2) : '';
-  const javascriptFixtures = [];
-  const inputCode = $('script:not([src])')
-                        .toArray()
-                        .map(n => n.children[0].data)
-                        .map(code => processScriptCode(code, javascriptFixtures, onloadFunctionName))
-                        .filter(x => !!x)
-                        .join('\n');
-  const helperScripts = [];
-  const resourceScripts = [];
-  $('script[src]').toArray().map((n) => n.attribs.src).forEach(src => {
-    if (src.indexOf('resources/') !== -1 && src.indexOf('-test.js') === -1) {
-      resourceScripts.push(src);
-      return;
-    }
-    const components = src.split('/');
-    var filename = components[components.length - 1].split('.')[0];
-    helperScripts.push(filename);
-  });
-
-  const destResourcePaths = resourceScripts.map(s => path.resolve(path.dirname(inputPath), s));
-  const relativeResourcePaths = destResourcePaths.map(p => path.relative(path.dirname(inputPath), p));
-
-  let outputCode;
-  try {
-    const testHelpers = mapTestHelpers(helperScripts, htmlTestFile.includes('ConsoleTestRunner'));
-    let domFixture = $('body')
-                         .html()
-                         .trim()
-                         // Unescapes apostrophe
-                         .replace(/&apos;/g, `'`)
-                         // Tries to remove it if it has it's own line
-                         .replace(prologue + '\n', '')
-                         // Tries to remove it if it's inline
-                         .replace(prologue, '')
-                         // Optimistically remove the first sentence of the prologue and everything in that block
-                         .replace(new RegExp(`<p>\\s*${escapeRegExp(prologue).split('.')[0]}[\\s\\S]*?<\\/p>`), '')
-                         .replace(new RegExp(`<div>\\s*${escapeRegExp(prologue).split('.')[0]}[\\s\\S]*?<\\/div>`), '')
-                         .replace(/<p>\s*<\/p>/, '')
-                         .replace(/<div>\s*<\/div>/, '')
-                         .replace(/<script.*?>([\S\s]*?)<\/script>/g, '')
-                         .trim();
-    const docType = htmlTestFile.match(/<!DOCTYPE.*>/) ? htmlTestFile.match(/<!DOCTYPE.*>/)[0] : '';
-    const inlineStylesheets =
-        $('style').toArray().map(n => n.children[0].data).map(text => `<style>${text}</style>`).join('\n');
-    if (inlineStylesheets)
-      domFixture = inlineStylesheets + (domFixture.length ? '\n' : '') + domFixture;
-    if (docType)
-      domFixture = docType + (domFixture.length ? '\n' : '') + domFixture;
-    outputCode = transformTestScript(
-        inputCode, prologue, identifierMap, testHelpers, javascriptFixtures, getPanels(inputPath, inputCode),
-        domFixture, onloadFunctionName, relativeResourcePaths, stylesheetPaths, inputFilename);
-  } catch (err) {
-    console.log('Unable to migrate: ', inputPath);
-    console.log('ERROR: ', err);
-    process.exit(1);
-  }
-  fs.writeFileSync(TEMP_JS_FILE, outputCode);
-  outputCode = shellOutput(`clang-format ${TEMP_JS_FILE} --style=FILE`);
-  fs.unlinkSync(TEMP_JS_FILE);
-  outputCode = unicodeEscape(outputCode);
-  console.log(outputCode);
-  if (!DRY_RUN) {
-    const jsInputPath = inputPath.replace('.html', '.js');
-    fs.writeFileSync(jsInputPath, outputCode);
-    console.log('Migrated: ', jsInputPath);
-    fs.unlinkSync(inputPath);
-    updateTestExpectations(path.relative(LAYOUT_TESTS_PATH, inputPath), path.relative(LAYOUT_TESTS_PATH, jsInputPath));
-  }
-}
-
-function transformTestScript(
-    inputCode, prologue, identifierMap, explicitTestHelpers, javascriptFixtures, panels, domFixture, onloadFunctionName,
-    relativeResourcePaths, stylesheetPaths, inputFilename) {
-  const ast = recast.parse(inputCode);
-
-  /**
-   * Wrap everything that's not the magical 'test' function
-   * with evaluateInPagePromise
-   */
-  const nonTestNodes = [];
-  for (const [index, node] of ast.program.body.entries()) {
-    if (node.type === 'FunctionDeclaration' && node.id.name === 'test') {
-      continue;
-    }
-    if (node.type === 'VariableDeclaration' && node.declarations[0].id.name === 'test') {
-      continue;
-    }
-    nonTestNodes.push(node);
-  }
-  const nonTestAst = recast.parse('');
-  nonTestAst.program.body = nonTestNodes;
-
-  replaceBodyWithFunctionExpression(ast, 'test');
-  replaceBodyWithFunctionDeclaration(ast, 'test');
-
-
-  /**
-   * Need to track all of the namespaces used because test helper refactoring
-   * requires additional fine-grained dependencies for some tests
-   */
-  const namespacesUsed = new Set();
-
-  /**
-   * Migrate all the call sites from InspectorTest to .*TestRunner
-   */
-  recast.visit(ast, {
-    visitIdentifier: function(path) {
-      if (path.parentPath && path.parentPath.value && path.parentPath.value.object &&
-          path.parentPath.value.object.name === 'InspectorTest' && path.value.name !== 'InspectorTest') {
-        const newParentIdentifier = identifierMap.get(path.value.name);
-        if (!newParentIdentifier) {
-          console.log('ERROR: Could not find identifier for: ' + path.value.name);
-          return false;
-        }
-        path.parentPath.value.object.name = newParentIdentifier;
-        namespacesUsed.add(newParentIdentifier.split('.')[0]);
-      }
-      return false;
-    }
-  });
-
-  /**
-   * Migrate all the .bind call sites
-   * Example: SourcesTestRunner.waitUntilPaused.bind(InspectorTest, didPause)
-   */
-  recast.visit(ast, {
-    visitCallExpression: function(path) {
-      const node = path.value;
-      if (node.callee.property && node.callee.property.name === 'bind') {
-        if (node.arguments[0].name === 'InspectorTest') {
-          node.arguments[0].name = node.callee.object.object.name;
-        }
-      }
-      this.traverse(path);
-    }
-  });
-
-
-  const allTestHelpers = new Set();
-
-  for (const helper of explicitTestHelpers) {
-    allTestHelpers.add(helper);
-  }
-
-  for (const namespace of namespacesUsed) {
-    if (namespace === 'TestRunner')
-      continue;
-    const moduleName = namespace.replace(/([A-Z])/g, '_$1').replace(/^_/, '').toLowerCase();
-    allTestHelpers.add(moduleName);
-  }
-
-  /**
-   * Create test header based on extracted data
-   */
-  const headerLines = [];
-  headerLines.push(createExpressionNode(`TestRunner.addResult(\`${prologue}\\n\`);`));
-  headerLines.push(createNewLineNode());
-  for (const helper of allTestHelpers) {
-    headerLines.push(createAwaitExpressionNode(`await TestRunner.loadModule('${helper}');`));
-  }
-  for (const panel of panels)
-    headerLines.push(createAwaitExpressionNode(`await TestRunner.showPanel('${panel}');`));
-
-  if (domFixture) {
-    headerLines.push(createAwaitExpressionNode(`await TestRunner.loadHTML(\`
-${domFixture.split('\n').map(line => '    ' + line).join('\n')}
-  \`);`));
-  }
-
-  stylesheetPaths.forEach(p => {
-    headerLines.push(createAwaitExpressionNode(`await TestRunner.addStylesheetTag('${p}');`));
-  });
-
-  relativeResourcePaths.forEach(p => {
-    headerLines.push(createAwaitExpressionNode(`await TestRunner.addScriptTag('${p}');`));
-  });
-
-  for (const fixture of javascriptFixtures) {
-    headerLines.push(fixture);
-  }
-
-  const formattedNonTestCode = formatNonTestCode(nonTestAst, onloadFunctionName);
-
-  if (formattedNonTestCode.trim()) {
-    headerLines.push((createAwaitExpressionNode(`await TestRunner.evaluateInPagePromise(\`
-${formattedNonTestCode}
-\`);`)));
-  }
-
-  headerLines.push(createNewLineNode());
-
-  ast.program.body = headerLines.concat(ast.program.body);
-
-  /**
-   * Wrap entire body in an async IIFE
-   */
-  const iife = b.functionExpression(null, [], b.blockStatement(ast.program.body));
-  iife.async = true;
-  ast.program.body = [b.expressionStatement(b.callExpression(iife, []))];
-
-  const outputFilename = inputFilename.replace('.html', '.js');
-  return print(ast)
-      .split(inputFilename)
-      .join(outputFilename)
-      .replace(/TestRunner.consoleModel/g, 'ConsoleModel.consoleModel')
-      .replace(/TestRunner.networkLog/g, 'NetworkLog.networkLog');
-}
-
-/**
- * If the <script></script> block doesn't contain a test function
- * assume that it needs to be serialized
- */
-function processScriptCode(code, javascriptFixtures, onloadFunctionName) {
-  const ast = recast.parse(code);
-  const testFunctionExpression =
-      ast.program.body.find(n => n.type === 'VariableDeclaration' && n.declarations[0].id.name === 'test');
-  const testFunctionDeclaration = ast.program.body.find(n => n.type === 'FunctionDeclaration' && n.id.name === 'test');
-  if (testFunctionExpression || testFunctionDeclaration) {
-    return code;
-  }
-  const formattedCode = formatNonTestCode(ast, onloadFunctionName);
-  javascriptFixtures.push(createAwaitExpressionNode(`await TestRunner.evaluateInPagePromise(\`${formattedCode}
-  \`);`));
-  return;
-}
-
-function formatNonTestCode(ast, onloadFunctionName) {
-  inlineFunctionExpression(ast, onloadFunctionName);
-  inlineFunctionDeclaration(ast, onloadFunctionName);
-  return recast.print(ast)
-      .code.trimRight()
-      .split('\n')
-      .map(line => '    ' + line)
-      .join('\n')
-      .replace(/\\n/g, '\\\\n')
-      .replace(RUN_TEST_REGEX, '');
-}
-
-/**
- * Unwrap test if it's a function expression
- * var test = function () {...}
- */
-function replaceBodyWithFunctionExpression(ast, functionName) {
-  const index =
-      ast.program.body.findIndex(n => n.type === 'VariableDeclaration' && n.declarations[0].id.name === functionName);
-  if (index > -1) {
-    const functionNode = ast.program.body[index];
-    ast.program.body = functionNode.declarations[0].init.body.body;
-  }
-}
-
-function inlineFunctionExpression(ast, functionName) {
-  const index =
-      ast.program.body.findIndex(n => n.type === 'VariableDeclaration' && n.declarations[0].id.name === functionName);
-  if (index > -1) {
-    const functionNode = ast.program.body[index];
-    ast.program.body.splice(index, 1, ...functionNode.declarations[0].init.body.body);
-  }
-}
-
-function replaceBodyWithFunctionDeclaration(ast, functionName) {
-  const index = ast.program.body.findIndex(n => n.type === 'FunctionDeclaration' && n.id.name === functionName);
-  if (index > -1) {
-    const functionNode = ast.program.body[index];
-    ast.program.body.splice(index, 1);
-    ast.program.body = functionNode.body.body;
-  }
-}
-
-function inlineFunctionDeclaration(ast, functionName) {
-  const index = ast.program.body.findIndex(n => n.type === 'FunctionDeclaration' && n.id.name === functionName);
-  if (index > -1) {
-    const functionNode = ast.program.body[index];
-    ast.program.body.splice(index, 1, ...functionNode.body.body);
-  }
-}
-
-function print(ast) {
-  const copyrightNotice = `// 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.
-
-`;
-
-  let code = recast.print(ast, {tabWidth: 2, wrapColumn: 120}).code;
-  code = code.replace(/(\/\/\#\s*sourceURL=[\w-]+)\.html/, '$1.js');
-  code = code.replace(/\s*\$\$SECRET_IDENTIFIER_FOR_LINE_BREAK\$\$\(\);/g, '\n');
-  const copyrightedCode = copyrightNotice + code.trim() + '\n';
-  return copyrightedCode;
-}
-
-function getPanels(inputPath, inputCode) {
-  const panels = new Set();
-  if (inputCode.includes('SourcesTestRunner.waitForScriptSource'))
-    panels.add('sources');
-  const panelByFolder = {
-    'animation': 'elements',
-    'appcache': 'resources',
-    'application-panel': 'resources',
-    'audits': 'audits',
-    'console': 'console',
-    'cache-storage': 'resources',
-    'elements': 'elements',
-    'editor': 'sources',
-    'layers': 'layers',
-    'network': 'network',
-    'profiler': 'heap_profiler',
-    'resource-tree': 'resources',
-    'search': 'sources',
-    'security': 'security',
-    'service-workers': 'resources',
-    'sources': 'sources',
-    'timeline': 'timeline',
-    'tracing': 'timeline',
-  };
-
-  const components = inputPath.slice(inputPath.indexOf('LayoutTests/')).split('/');
-  const folder = inputPath.indexOf('LayoutTests/inspector') === -1 ? components[4] : components[2];
-  if (folder.endsWith('.html'))
-    return [];
-  const panel = panelByFolder[folder];
-  if (panel)
-    panels.add(panel);
-  return Array.from(panels);
-}
-
-function mapTestHelpers(testHelpers, includeConsole) {
-  const specialCases = {
-    'SDKTestRunner': 'sdk_test_runner',
-  };
-  const mappedHelpers = new Set();
-  for (const helper of testHelpers) {
-    const namespace = migrateUtils.mapTestFilename(helper).namespacePrefix + 'TestRunner';
-    const mappedHelper =
-        specialCases[namespace] || namespace.replace(/([A-Z])/g, '_$1').replace(/^_/, '').toLowerCase();
-    if (!mappedHelper) {
-      throw Error('Could not map helper ' + helper);
-    }
-    if (mappedHelper === 'inspector_test_runner')
-      continue;
-    // Some tests reference tracing-test.js which doesn't exist
-    if (mappedHelper === 'tracing_test_runner')
-      continue;
-    mappedHelpers.add(mappedHelper);
-  }
-  if (includeConsole)
-    mappedHelpers.add('console_test_runner');
-  return Array.from(mappedHelpers);
-}
-
-function generateTestHelperMap() {
-  const map = new Map();
-  for (const folder of fs.readdirSync(FRONT_END_PATH)) {
-    if (folder.indexOf('test_runner') === -1) {
-      continue;
-    }
-    const testRunnerModulePath = path.resolve(FRONT_END_PATH, folder);
-    if (!utils.isDir(testRunnerModulePath)) {
-      continue;
-    }
-    for (const filename of fs.readdirSync(testRunnerModulePath)) {
-      if (filename === 'module.json') {
-        continue;
-      }
-      scrapeTestHelperIdentifiers(path.resolve(testRunnerModulePath, filename));
-    }
-  }
-
-  // Manual overrides
-  map.set('consoleModel', 'ConsoleModel');
-  map.set('networkLog', 'NetworkLog');
-
-  return map;
-
-  function scrapeTestHelperIdentifiers(filePath) {
-    var content = fs.readFileSync(filePath).toString();
-    var lines = content.split('\n');
-    for (var line of lines) {
-      var line = line.trim();
-      if (line.indexOf('TestRunner.') === -1)
-        continue;
-      var match = line.match(/^\s*(\b\w*TestRunner.[a-z_A-Z0-9]+)\s*(\=[^,}]|[;])/) ||
-          line.match(/^(\b\w*TestRunner.[a-z_A-Z0-9]+)\s*\=$/);
-      if (!match)
-        continue;
-      var name = match[1];
-      var components = name.split('.');
-      if (components.length !== 2)
-        continue;
-      map.set(components[1], components[0]);
-    }
-  }
-}
-
-/**
- * Hack to quickly create an AST node
- */
-function createExpressionNode(code) {
-  return recast.parse(code).program.body[0];
-}
-
-/**
- * Hack to quickly create an AST node
- */
-function createAwaitExpressionNode(code) {
-  code = code.split('\n').map(line => line.trimRight()).join('\n');
-  return recast.parse(`(async function(){${code}});`).program.body[0].expression.body.body[0];
-}
-
-function createNewLineNode() {
-  return createExpressionNode(LINE_BREAK);
-}
-
-function updateTestExpectations(oldRelativeTestPath, newRelativeTestPath) {
-  // Update additional test expectations
-  for (const filename
-           of ['TestExpectations', 'ASANExpectations', 'LeakExpectations', 'MSANExpectations', 'NeverFixTests',
-               'SlowTests', 'SmokeTests', 'StaleTestExpectations']) {
-    const filePath = path.resolve(LAYOUT_TESTS_PATH, filename);
-    updateExpectationsFile(filePath);
-  }
-
-  // Update FlagExpectations
-  for (const filename of fs.readdirSync(FLAG_EXPECTATIONS_PATH)) {
-    const filePath = path.resolve(FLAG_EXPECTATIONS_PATH, filename);
-    updateExpectationsFile(filePath);
-  }
-
-  function updateExpectationsFile(filePath) {
-    const expectations = fs.readFileSync(filePath, 'utf-8');
-    const updatedExpectations = expectations.split('\n').map(line => {
-      return line.replace(oldRelativeTestPath, newRelativeTestPath);
-    });
-    fs.writeFileSync(filePath, updatedExpectations.join('\n'));
-  }
-}
-
-function shellOutput(command) {
-  return childProcess.execSync(command).toString();
-}
-
-function unicodeEscape(string) {
-  function padWithLeadingZeros(string) {
-    return new Array(5 - string.length).join('0') + string;
-  }
-
-  function unicodeCharEscape(charCode) {
-    return '\\u' + padWithLeadingZeros(charCode.toString(16));
-  }
-
-  return string.split('')
-      .map(function(char) {
-        var charCode = char.charCodeAt(0);
-        return charCode > 127 ? unicodeCharEscape(charCode) : char;
-      })
-      .join('');
-}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_utils.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_utils.js
deleted file mode 100644
index 636d55a..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/migrate_utils.js
+++ /dev/null
@@ -1,114 +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.
-
-'use strict';
-
-const path = require('path');
-
-function getOutPath(inputPath, isEnabledTest) {
-  const nonHttpLayoutTestPrefix = isEnabledTest ? 'LayoutTests/inspector-enabled' : 'LayoutTests/inspector';
-  const httpLayoutTestPrefix =
-      isEnabledTest ? 'LayoutTests/http/tests/inspector-enabled' : 'LayoutTests/http/tests/inspector';
-  const postfix = inputPath.indexOf(nonHttpLayoutTestPrefix) === -1 ?
-      inputPath.slice(inputPath.indexOf(httpLayoutTestPrefix) + httpLayoutTestPrefix.length + 1) :
-      inputPath.slice(inputPath.indexOf(nonHttpLayoutTestPrefix) + nonHttpLayoutTestPrefix.length + 1);
-  const out = path.resolve(
-      __dirname, '..', '..', '..', '..', 'LayoutTests', 'http', 'tests', 'devtools', isEnabledTest ? 'startup' : '',
-      postfix);
-  return out;
-}
-
-
-function mapTestFilename(filename) {
-  let namespacePrefix = path.basename(filename, '.js')
-                            .split('-test')[0]
-                            .split('-')
-                            .map(a => a.substring(0, 1).toUpperCase() + a.substring(1))
-                            .join('');
-  let filenamePrefix = namespacePrefix;
-  if (namespacePrefix === 'PageMock')
-    namespacePrefix = 'SDK';
-  if (namespacePrefix === 'SyntaxHighlight')
-    namespacePrefix = '';
-  if (namespacePrefix === 'Datagrid') {
-    namespacePrefix = 'DataGrid';
-    filenamePrefix = 'DataGrid';
-  }
-  if (namespacePrefix === 'TimelineData')
-    namespacePrefix = 'Performance';
-  if (namespacePrefix === 'StylesUpdateLinks')
-    namespacePrefix = 'Elements';
-  if (namespacePrefix === 'BreakpointManager')
-    namespacePrefix = 'Sources';
-  if (namespacePrefix === 'ElementsPanelShadowSelectionOnRefresh')
-    namespacePrefix = 'Elements';
-
-  if (namespacePrefix === 'ExtensionsNetwork')
-    namespacePrefix = 'Extensions';
-  if (namespacePrefix === 'CspInline')
-    namespacePrefix = 'CSPInline';
-  if (namespacePrefix === 'Debugger')
-    namespacePrefix = 'Sources';
-  if (namespacePrefix === 'Resources') {
-    namespacePrefix = 'Application';
-  }
-  if (namespacePrefix === 'Appcache')
-    namespacePrefix = 'Application';
-  if (namespacePrefix === 'ResourceTree')
-    namespacePrefix = 'Application';
-  if (namespacePrefix === 'ServiceWorkers')
-    namespacePrefix = 'Application';
-  if (namespacePrefix === 'CacheStorage')
-    namespacePrefix = 'Application';
-  if (namespacePrefix === 'Indexeddb') {
-    namespacePrefix = 'Application';
-    filenamePrefix = 'IndexedDB';
-  }
-  if (namespacePrefix === 'Timeline')
-    namespacePrefix = 'Performance';
-  if (namespacePrefix === 'ProductRegistry')
-    namespacePrefix = 'Network';
-  if (namespacePrefix === 'Editor')
-    namespacePrefix = 'Sources';
-  if (namespacePrefix === 'Search')
-    namespacePrefix = 'Sources';
-  if (namespacePrefix === 'LiveEdit')
-    namespacePrefix = 'Sources';
-  if (namespacePrefix === 'Autocomplete')
-    namespacePrefix = 'Sources';
-  if (namespacePrefix === 'Changes')
-    namespacePrefix = 'Sources';
-  if (namespacePrefix === 'Persistence')
-    namespacePrefix = 'Bindings';
-  if (namespacePrefix === 'IsolatedFilesystem')
-    namespacePrefix = 'Bindings';
-  if (namespacePrefix === 'Automapping')
-    namespacePrefix = 'Bindings';
-  if (namespacePrefix === 'AccessibilityPane')
-    namespacePrefix = 'Accessibility';
-  if (namespacePrefix === 'EditDom') {
-    namespacePrefix = 'Elements';
-    filenamePrefix = 'EditDOM';
-  }
-  if (namespacePrefix === 'SetOuterHtml') {
-    namespacePrefix = 'Elements';
-    filenamePrefix = 'SetOuterHTML';
-  }
-  if (namespacePrefix === 'Sass') {
-    namespacePrefix = 'SASS';
-    filenamePrefix = 'SASS';
-  }
-  if (namespacePrefix === 'Editing') {
-    namespacePrefix = 'SASS';
-    filenamePrefix = 'SASSEditing'
-  }
-  if (namespacePrefix === 'ExtensionsAudits')
-    namespacePrefix = 'Extensions';
-  return {namespacePrefix, filenamePrefix};
-}
-
-module.exports = {
-  getOutPath,
-  mapTestFilename,
-};
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/move.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/move.js
deleted file mode 100644
index 23e3742..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/move.js
+++ /dev/null
@@ -1,126 +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.
-
-'use strict';
-
-const childProcess = require('child_process');
-const fs = require('fs');
-const path = require('path');
-
-const mkdirp = require('mkdirp');
-
-const migrateUtils = require('./migrate_utils');
-const utils = require('../utils');
-
-const LAYOUT_TESTS_PATH = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests');
-const FLAG_EXPECTATIONS_PATH = path.resolve(LAYOUT_TESTS_PATH, 'FlagExpectations');
-
-function main() {
-  const originalTests = scanForTests([
-    '../../../../LayoutTests/http/tests/inspector-enabled/',
-  ]);
-
-  console.log(originalTests);
-  const oldToNewResourcesPath = new Map();
-  const oldToNewTestPath = new Map(originalTests.map(t => [t, '']));
-
-  for (const inputRelativePath of originalTests) {
-    if (!inputRelativePath) {
-      continue;
-    }
-    const inputPath = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', inputRelativePath);
-    const inputResourcesPath = path.resolve(path.dirname(inputPath), 'resources');
-    const outPath = migrateUtils.getOutPath(inputPath, true);
-    const outResourcesPath = path.resolve(path.dirname(outPath), 'resources');
-
-    if (utils.isDir(inputResourcesPath))
-      oldToNewResourcesPath.set(inputResourcesPath, outResourcesPath);
-    mkdirp.sync(path.dirname(outPath));
-
-    const original = fs.readFileSync(inputPath, 'utf-8');
-    const updatedReferences = original.replace(/127.0.0.1:8000\/inspector/g, '127.0.0.1:8000/devtools')
-                                  .replace(/script src="\.\//g, 'script src="')
-                                  .replace(/script src="..\/(?=.+-test)/g, 'script src="../../')
-                                  .replace(
-                                      /script src="(?=\w.+-test)/g,
-                                      `script src="${path.relative(path.dirname(outPath), path.dirname(inputPath))}/`)
-                                  .replace(/..\/..\/inspector\/..\//g, '../../../inspector/');
-    fs.writeFileSync(outPath, updatedReferences);
-    fs.unlinkSync(inputPath);
-
-    const outRelativePath = outPath.substring(outPath.indexOf('http/'));
-    oldToNewTestPath.set(inputRelativePath, outRelativePath);
-
-    // Move expectation file
-    const inputExpectationsPath =
-        inputPath.replace(/\.x?html/, '-expected.txt').replace('-expected-expected', '-expected');
-    const outExpectationsPath = outPath.replace(/\.x?html/, '-expected.txt').replace('-expected-expected', '-expected');
-    if (utils.isFile(inputExpectationsPath)) {
-      fs.writeFileSync(outExpectationsPath, fs.readFileSync(inputExpectationsPath, 'utf-8'));
-      fs.unlinkSync(inputExpectationsPath);
-    }
-  }
-
-  const newTestPaths = Array.from(oldToNewTestPath.values()).filter(x => x);
-
-  const TestExpectationFailureTypes =
-      ['Crash', 'Failure', 'Rebaseline', 'Skip', 'Timeout', 'WontFix', 'Missing', 'NeedsManualRebaseline'];
-
-  // Update additional test expectations
-  for (const filename
-           of ['TestExpectations', 'ASANExpectations', 'LeakExpectations', 'MSANExpectations', 'NeverFixTests',
-               'SlowTests', 'SmokeTests', 'StaleTestExpectations']) {
-    const filePath = path.resolve(LAYOUT_TESTS_PATH, filename);
-    updateExpectationsFile(filePath);
-  }
-
-  // Update FlagExpectations
-  for (const filename of fs.readdirSync(FLAG_EXPECTATIONS_PATH)) {
-    const filePath = path.resolve(FLAG_EXPECTATIONS_PATH, filename);
-    updateExpectationsFile(filePath);
-  }
-
-  for (const [oldResourcesPath, newResourcesPath] of oldToNewResourcesPath) {
-    utils.copyRecursive(oldResourcesPath, path.dirname(newResourcesPath));
-    utils.removeRecursive(oldResourcesPath);
-  }
-
-  function updateExpectationsFile(filePath) {
-    const expectations = fs.readFileSync(filePath, 'utf-8');
-    const updatedExpectations = expectations.split('\n').map(line => {
-      for (const [oldTestPath, newTestPath] of oldToNewTestPath) {
-        if (!newTestPath)
-          continue;
-        if (line.indexOf(oldTestPath) !== -1) {
-          const newLine = line.replace(oldTestPath, newTestPath);
-          return newLine;
-        }
-      }
-      return line;
-    });
-    fs.writeFileSync(filePath, updatedExpectations.join('\n'));
-  }
-}
-
-main();
-
-function scanForTests(dirPaths) {
-  const absolutePaths = dirPaths.map(dirPath => path.resolve(__dirname, dirPath));
-  let globbedPaths = [];
-  for (const absolutePath of absolutePaths)
-    glob(absolutePath);
-  return globbedPaths.map(p => p.slice(p.indexOf('LayoutTests') + 'LayoutTests'.length + 1));
-
-  function glob(globPath) {
-    for (const filename of fs.readdirSync(globPath)) {
-      const p = path.resolve(globPath, filename);
-      if (utils.isDir(p) && filename !== 'resources') {
-        glob(p);
-      }
-      if (utils.isFile(p) && (p.endsWith('.html') || p.endsWith('.xhtml'))) {
-        globbedPaths.push(p);
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/namespace.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/namespace.js
deleted file mode 100644
index d45fe25..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/namespace.js
+++ /dev/null
@@ -1,112 +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.
-
-const path = require('path');
-const fs = require('fs');
-
-const utils = require('../utils');
-
-const FRONT_END_PATH = path.resolve(__dirname, '..', '..', 'front_end');
-
-function main() {
-  const identifierMap = generateTestHelperMap();
-  renameIdentifiers(identifierMap);
-}
-
-String.prototype.replaceAll = function(search, replacement) {
-  let target = this;
-  return target.replace(new RegExp('\\b' + search + '\\b', 'g'), replacement);
-};
-
-main();
-
-function generateTestHelperMap() {
-  const map = new Map();
-  for (const folder of fs.readdirSync(FRONT_END_PATH)) {
-    if (folder.indexOf('test_runner') === -1) {
-      continue;
-    }
-    const testRunnerModulePath = path.resolve(FRONT_END_PATH, folder);
-    if (!utils.isDir(testRunnerModulePath)) {
-      continue;
-    }
-    for (const filename of fs.readdirSync(testRunnerModulePath)) {
-      if (filename === 'module.json') {
-        continue;
-      }
-      scrapeTestHelperIdentifiers(path.resolve(testRunnerModulePath, filename));
-    }
-  }
-
-  // Manual overrides
-  map.set('InspectorTest.consoleModel', 'TestRunner.consoleModel');
-  map.set('InspectorTest.networkLog', 'TestRunner.networkLog');
-
-  return map;
-
-  function scrapeTestHelperIdentifiers(filePath) {
-    var content = fs.readFileSync(filePath).toString();
-    var lines = content.split('\n');
-    for (var line of lines) {
-      var line = line.trim();
-      if (line.indexOf('TestRunner.') === -1)
-        continue;
-      var match = line.match(/^\s*(\b\w*TestRunner.[a-z_A-Z0-9]+)\s*(\=[^,}]|[;])/) ||
-          line.match(/^(\b\w*TestRunner.[a-z_A-Z0-9]+)\s*\=$/);
-      if (!match)
-        continue;
-      var name = match[1];
-      var components = name.split('.');
-      if (components.length !== 2) {
-        console.log('BAD', name);
-        continue;
-      }
-      map.set(['InspectorTest', components[1]].join('.'), name);
-    }
-  }
-}
-
-function renameIdentifiers(identifierMap) {
-  walkSync('../../../../LayoutTests/http/tests/inspector', write);
-  walkSync('../../../../LayoutTests/http/tests/inspector-enabled', write);
-  walkSync('../../../../LayoutTests/http/tests/inspector-unit', write);
-  walkSync('../../../../LayoutTests/inspector-enabled', write);
-  walkSync('../../../../LayoutTests/inspector', write);
-
-  function walkSync(currentDirPath, process) {
-    fs.readdirSync(currentDirPath).forEach(function(name) {
-      let filePath = path.join(currentDirPath, name);
-      let stat = fs.statSync(filePath);
-      if (stat.isFile() &&
-          (filePath.endsWith('.html') || filePath.endsWith('.xhtml') || filePath.endsWith('.xsl') ||
-           filePath.endsWith('-expected.txt'))) {
-        // This file causes issues with renaming namespace
-        if (filePath.endsWith('heap-snapshot.html'))
-          return;
-        process(filePath);
-      } else if (stat.isDirectory()) {
-        walkSync(filePath, process);
-      }
-    });
-  }
-
-  function write(filePath) {
-    let content = fs.readFileSync(filePath).toString();
-    let newContent = content;
-    for (let key of identifierMap.keys()) {
-      let originalIdentifier = key;
-      let newIdentifier = identifierMap.get(key);
-      newContent = newContent.replaceAll(originalIdentifier, newIdentifier);
-    }
-
-    const ignoreBindContent = newContent.replace(/.bind\(InspectorTest/g, '.bind(IGNOREDIT');
-    if (ignoreBindContent.indexOf('InspectorTest') !== -1) {
-      console.log('WARNING', filePath, 'has old inspector test references remaining');
-      console.log(ignoreBindContent);
-    }
-
-    if (content !== newContent)
-      fs.writeFileSync(filePath, newContent);
-  }
-}
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/notes.txt b/third_party/WebKit/Source/devtools/scripts/migrate_test/notes.txt
deleted file mode 100644
index 5c5bc70..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/notes.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-inspector/console/command-line-api-getEventListeners.html
-- handle <script> extraction
-- add output method
-- regex in javascript function causing issue
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/package.json b/third_party/WebKit/Source/devtools/scripts/migrate_test/package.json
deleted file mode 100644
index a5279aff..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/package.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "name": "chrome-devtools-migrate-test",
-  "version": "0.1.0",
-  "author": "The Chromium Authors",
-  "license": "SEE LICENSE IN https://chromium.googlesource.com/chromium/src/+/master/LICENSE",
-  "dependencies": {
-    "cheerio": "^1.0.0-rc.2",
-    "mkdirp": "^0.5.1",
-    "recast": "^0.12.6"
-  }
-}
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/test_summary.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/test_summary.js
deleted file mode 100644
index ccec4fc0..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/test_summary.js
+++ /dev/null
@@ -1,64 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-
-const utils = require('../utils');
-
-const TESTS_PATH = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', 'http', 'tests', 'devtools');
-
-function main() {
-  const groups = {};
-  groups['<root>'] = {html: 0, js: 0};
-  const total = {html: 0, js: 0};
-  const filenames = fs.readdirSync(TESTS_PATH);
-  for (const filename of filenames) {
-    const filePath = path.resolve(TESTS_PATH, filename);
-    if (utils.isDir(filePath)) {
-      groups[filename] = summarizeRecursive(filePath);
-    } else {
-      const extension = path.extname(filePath);
-      if (extension === '.js') {
-        groups['<root>'].js++;
-      }
-      if (extension === '.html') {
-        groups['<root>'].html++;
-      }
-    }
-  }
-
-  for (var key in groups) {
-    total.html += groups[key].html;
-    total.js += groups[key].js;
-  }
-
-  for (var key in groups) {
-    console.log(key, ' 😞', groups[key].html, ' 🎉', groups[key].js)
-  }
-
-  console.log('\nTotal: ', ' 😞', total.html, ' 🎉', total.js)
-}
-
-function summarizeRecursive(dirPath) {
-  const aggregatedStat = {html: 0, js: 0};
-  if (dirPath.endsWith('resources'))
-    return aggregatedStat;
-  const filenames = fs.readdirSync(dirPath);
-  for (const filename of filenames) {
-    const filePath = path.resolve(dirPath, filename);
-    if (utils.isDir(filePath)) {
-      const stat = summarizeRecursive(filePath);
-      aggregatedStat.html += stat.html;
-      aggregatedStat.js += stat.js;
-    } else {
-      const extension = path.extname(filePath);
-      if (extension === '.js') {
-        aggregatedStat.js++;
-      } else if (extension !== '.txt') {
-        console.log('Legacy test:', filePath);
-        aggregatedStat.html++;
-      }
-    }
-  }
-  return aggregatedStat;
-}
-
-main();
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/scripts/migrate_test/transform.js b/third_party/WebKit/Source/devtools/scripts/migrate_test/transform.js
deleted file mode 100644
index 1005db68..0000000
--- a/third_party/WebKit/Source/devtools/scripts/migrate_test/transform.js
+++ /dev/null
@@ -1,90 +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.
-
-'use strict';
-
-const fs = require('fs');
-const path = require('path');
-
-const childProcess = require('child_process');
-
-const utils = require('../utils');
-
-const MIGRATE_SCRIPT_PATH = path.resolve(__dirname, 'migrate_test.js');
-const TESTS_PATH = path.resolve(__dirname, 'tests.txt');
-const TEST_EXPECTATIONS_PATH = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', 'TestExpectations');
-const FLAG_EXPECTATIONS_PATH = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', 'FlagExpectations');
-
-function main() {
-  const tests = fs.readFileSync(TESTS_PATH, 'utf-8').split('\n').map(line => line.split(' '));
-  const oldToNewTests = new Map(tests);
-  const testCount = oldToNewTests.size;
-  const migratedTests = new Set();
-
-  for (const [_, testPath] of tests) {
-    if (!testPath)
-      continue;
-    const fullTestPath = path.resolve(__dirname, '..', '..', '..', '..', 'LayoutTests', testPath);
-    try {
-      childProcess.execSync(`node ${MIGRATE_SCRIPT_PATH} ${fullTestPath}`);
-    } catch (err) {
-      console.log(err.stdout.toString());
-      continue;
-    }
-
-    for (const [oldTest, newTest] of oldToNewTests) {
-      if (testPath === newTest)
-        oldToNewTests.delete(oldTest);
-    }
-    migratedTests.add(testPath);
-  }
-
-  console.log(`Successfully migrated: ${migratedTests.size} of ${testCount}`);
-  console.log('May need to rebaseline these tests');
-
-  const updatedTests = Array.from(oldToNewTests.entries()).map(line => line.join(' ')).join('\n');
-  console.log(updatedTests);
-
-  // Update TestExpectations
-  const testExpectations = fs.readFileSync(TEST_EXPECTATIONS_PATH, 'utf-8');
-  const updatedTestExpecationLines = [];
-  let seenStartSentinel = false;
-  let seenEndSentinel = false;
-  for (const line of testExpectations.split('\n')) {
-    if (line === '# ====== DevTools test migration failures from here ======') {
-      seenStartSentinel = true;
-      updatedTestExpecationLines.push(line);
-      continue;
-    }
-    if (line === '### Manually fix after migration') {
-      seenEndSentinel = true;
-      updatedTestExpecationLines.push(line);
-      continue;
-    }
-    if (seenEndSentinel) {
-      updatedTestExpecationLines.push(line);
-      continue;
-    }
-    if (!seenStartSentinel) {
-      updatedTestExpecationLines.push(line);
-      continue;
-    }
-    let skipLine = false;
-    for (const test of migratedTests) {
-      if (line.indexOf(test) !== -1) {
-        skipLine = true;
-        break;
-      }
-    }
-    if (!skipLine)
-      updatedTestExpecationLines.push(line);
-  }
-
-  fs.writeFileSync(TEST_EXPECTATIONS_PATH, updatedTestExpecationLines.join('\n'));
-
-  // Update tests.txt
-  fs.writeFileSync(TESTS_PATH, updatedTests);
-}
-
-main();
diff --git a/third_party/WebKit/Source/devtools/scripts/namespaces.js b/third_party/WebKit/Source/devtools/scripts/namespaces.js
deleted file mode 100644
index b1a60a4c..0000000
--- a/third_party/WebKit/Source/devtools/scripts/namespaces.js
+++ /dev/null
@@ -1,134 +0,0 @@
-const fs = require('fs');
-
-const TARGET_MODULE = 'UI';
-
-function depends(module, from) {
-  if (module === from)
-    return true;
-  var desc = descriptors[module];
-  if (!desc)
-    return false;
-  for (var dep of desc.dependencies || []) {
-    if (dep === from)
-      return true;
-    if (depends(dep, from))
-      return true;
-  }
-  return false;
-}
-
-var map = new Map();
-var sortedKeys;
-var moduleNames = new Set();
-
-String.prototype.replaceAll = function(a, b) {
-  var result = this;
-  return result.split(a).join(b);
-};
-
-function read(filePath) {
-  var content = fs.readFileSync(filePath).toString();
-
-  var oldModuleName = filePath.replace(/front_end\/([^/]+)\/.*/, '$1');
-  if (oldModuleName.endsWith('_lazy'))
-    oldModuleName = oldModuleName.substring(0, oldModuleName.length - '_lazy'.length);
-
-  var moduleName = oldModuleName;
-
-  if (moduleName === 'sdk' || moduleName == 'ui')
-    moduleName = moduleName.toUpperCase();
-  moduleName = moduleName.split('_').map(a => a.substring(0, 1).toUpperCase() + a.substring(1)).join('');
-  if (moduleName.includes('/'))
-    return;
-  moduleNames.add(moduleName);
-
-  var lines = content.split('\n');
-  for (var line of lines) {
-    // Replace with your own logic
-    if (!line.startsWith('var '))
-      continue;
-    var globalVariableMatch = line.match(/^var ([a-z_A-Z0-9]+)\s*(\=)/);
-    var match = globalVariableMatch;
-
-    if (!match)
-      continue;
-    var name = match[1];
-    var weight = line.endsWith(name + ';') ? 2 : 1;
-
-    var newName;
-
-    newName = TARGET_MODULE + '.' + name;
-    var existing = map.get(name);
-    if (existing && existing.weight > weight)
-      continue;
-    if (existing && existing.weight === weight && newName !== existing.name)
-      console.log('Conflict: ' + newName + ' vs ' + existing.name + ' ' + weight);
-    map.set(name, {name: newName, weight});
-  }
-}
-
-function write(filePath) {
-  var content = fs.readFileSync(filePath).toString();
-  var newContent = content;
-  for (var key of sortedKeys) {
-    var originalIdentifier = key;
-    var newIdentifier = map.get(key).name;
-    newContent = newContent.split('\n').map(line => processLine(line, originalIdentifier, newIdentifier)).join('\n');
-  }
-
-  if (content !== newContent)
-    fs.writeFileSync(filePath, newContent);
-}
-
-function processLine(line, originalIdentifier, newIdentifier) {
-  return line.replace(new RegExp(`^var ${originalIdentifier}`, 'g'), `${newIdentifier}`)
-      .replace(new RegExp(`^function ${originalIdentifier}`, 'g'), `${newIdentifier} = function`)
-      .replace(new RegExp(`^${originalIdentifier}\\.`, 'g'), `${newIdentifier}.`)
-      .replace(new RegExp(`([^."'])(\\b${originalIdentifier}\\b)(?!(\.js|[ ]|[']))`, 'g'), usageReplacer);
-
-  function usageReplacer(match, p1) {
-    return [p1, newIdentifier].join('');
-  }
-}
-
-function walkSync(currentDirPath, process, json) {
-  var path = require('path');
-  fs.readdirSync(currentDirPath).forEach(function(name) {
-    var filePath = path.join(currentDirPath, name);
-    var stat = fs.statSync(filePath);
-    if (stat.isFile() && (filePath.endsWith('.js') || filePath.endsWith('.html') || filePath.endsWith('.xhtml') ||
-                          filePath.endsWith('-expected.txt') || (json && filePath.endsWith('.json')))) {
-      if (filePath.includes('ExtensionAPI.js'))
-        return;
-      if (filePath.includes('externs.js'))
-        return;
-      if (filePath.includes('eslint') || filePath.includes('lighthouse-background.js') || filePath.includes('/cm/') ||
-          filePath.includes('/xterm.js/') || filePath.includes('/acorn/'))
-        return;
-      if (filePath.includes('/cm_modes/') && !filePath.includes('DefaultCodeMirror') &&
-          !filePath.includes('module.json'))
-        return;
-      process(filePath);
-    } else if (stat.isDirectory()) {
-      walkSync(filePath, process, json);
-    }
-  });
-}
-
-walkSync('front_end', read);
-
-sortedKeys = Array.from(map.keys());
-sortedKeys.sort((a, b) => a.localeCompare(b));
-sortedKeys = ['Size', 'Insets', 'Constraints'];
-for (var key of sortedKeys)
-  console.log(key + ' => ' + map.get(key).name);
-
-walkSync('front_end', write, true);
-
-walkSync('../../LayoutTests/http/tests/inspector', write, false);
-walkSync('../../LayoutTests/http/tests/inspector-enabled', write, false);
-walkSync('../../LayoutTests/http/tests/inspector-protocol', write, false);
-walkSync('../../LayoutTests/http/tests/inspector-unit', write, false);
-walkSync('../../LayoutTests/inspector', write, false);
-walkSync('../../LayoutTests/inspector-enabled', write, false);
-walkSync('../../LayoutTests/inspector-protocol', write, false);
diff --git a/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp b/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp
index e659eb33..74d6080 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXTableCell.cpp
@@ -193,7 +193,7 @@
 
   LayoutTableCell* layout_cell = ToLayoutTableCell(layout_object_);
   row_range.first = layout_cell->RowIndex();
-  row_range.second = layout_cell->RowSpan();
+  row_range.second = layout_cell->ResolvedRowSpan();
 
   // Since our table might have multiple sections, we have to offset our row
   // appropriately.
diff --git a/third_party/WebKit/Source/modules/animationworklet/AnimationWorklet.cpp b/third_party/WebKit/Source/modules/animationworklet/AnimationWorklet.cpp
index 3c87d278d..9b24c14 100644
--- a/third_party/WebKit/Source/modules/animationworklet/AnimationWorklet.cpp
+++ b/third_party/WebKit/Source/modules/animationworklet/AnimationWorklet.cpp
@@ -37,8 +37,8 @@
   ProvideAnimationWorkletProxyClientTo(worker_clients, proxy_client);
 
   AnimationWorkletMessagingProxy* proxy =
-      new AnimationWorkletMessagingProxy(GetExecutionContext(), worker_clients);
-  proxy->Initialize();
+      new AnimationWorkletMessagingProxy(GetExecutionContext());
+  proxy->Initialize(worker_clients);
   return proxy;
 }
 
diff --git a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.cpp b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.cpp
index c82cf55..0f66dbb 100644
--- a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.cpp
+++ b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.cpp
@@ -5,15 +5,13 @@
 #include "modules/animationworklet/AnimationWorkletMessagingProxy.h"
 
 #include "core/workers/ThreadedWorkletObjectProxy.h"
-#include "core/workers/WorkerClients.h"
 #include "modules/animationworklet/AnimationWorkletThread.h"
 
 namespace blink {
 
 AnimationWorkletMessagingProxy::AnimationWorkletMessagingProxy(
-    ExecutionContext* execution_context,
-    WorkerClients* worker_clients)
-    : ThreadedWorkletMessagingProxy(execution_context, worker_clients) {}
+    ExecutionContext* execution_context)
+    : ThreadedWorkletMessagingProxy(execution_context) {}
 
 void AnimationWorkletMessagingProxy::Trace(blink::Visitor* visitor) {
   ThreadedWorkletMessagingProxy::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.h b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.h
index 22ff4e21..1d7de7f 100644
--- a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.h
+++ b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletMessagingProxy.h
@@ -12,7 +12,6 @@
 namespace blink {
 
 class ExecutionContext;
-class WorkerClients;
 class WorkerThread;
 
 // Acts as a proxy for the animation worklet global scopes that live on the
@@ -23,7 +22,7 @@
 class AnimationWorkletMessagingProxy final
     : public ThreadedWorkletMessagingProxy {
  public:
-  AnimationWorkletMessagingProxy(ExecutionContext*, WorkerClients*);
+  explicit AnimationWorkletMessagingProxy(ExecutionContext*);
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/WebKit/Source/modules/exported/WebAXObject.cpp b/third_party/WebKit/Source/modules/exported/WebAXObject.cpp
index 3aa5f60..00c1ce1c 100644
--- a/third_party/WebKit/Source/modules/exported/WebAXObject.cpp
+++ b/third_party/WebKit/Source/modules/exported/WebAXObject.cpp
@@ -1505,9 +1505,7 @@
   const Document* document = web_document.ConstUnwrap<Document>();
   AXObjectCacheImpl* cache =
       ToAXObjectCacheImpl(document->GetOrCreateAXObjectCache());
-  return cache ? WebAXObject(cache->GetOrCreate(
-                     ToLayoutView(LayoutAPIShim::LayoutObjectFrom(
-                         document->GetLayoutViewItem()))))
+  return cache ? WebAXObject(cache->GetOrCreate(document->GetLayoutView()))
                : WebAXObject();
 }
 
diff --git a/third_party/WebKit/Source/modules/filesystem/BUILD.gn b/third_party/WebKit/Source/modules/filesystem/BUILD.gn
index 8308d63..614e04a 100644
--- a/third_party/WebKit/Source/modules/filesystem/BUILD.gn
+++ b/third_party/WebKit/Source/modules/filesystem/BUILD.gn
@@ -37,6 +37,7 @@
     "EntryBase.cpp",
     "EntryBase.h",
     "EntryCallback.h",
+    "EntryHeapVector.h",
     "EntrySync.cpp",
     "EntrySync.h",
     "ErrorCallback.h",
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h
index 2dca524c..12a1d88a 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystem.h
@@ -37,7 +37,6 @@
 #include "core/dom/ExecutionContext.h"
 #include "modules/ModulesExport.h"
 #include "modules/filesystem/DOMFileSystemBase.h"
-#include "modules/filesystem/EntriesCallback.h"
 #include "platform/heap/Handle.h"
 #include "public/platform/TaskType.h"
 
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp
index aeb98cd..1ef6bea3 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp
@@ -38,7 +38,6 @@
 #include "modules/filesystem/DOMFilePath.h"
 #include "modules/filesystem/DirectoryEntry.h"
 #include "modules/filesystem/DirectoryReaderBase.h"
-#include "modules/filesystem/EntriesCallback.h"
 #include "modules/filesystem/Entry.h"
 #include "modules/filesystem/EntryBase.h"
 #include "modules/filesystem/EntryCallback.h"
@@ -444,11 +443,12 @@
                                   std::move(callbacks));
 }
 
-int DOMFileSystemBase::ReadDirectory(DirectoryReaderBase* reader,
-                                     const String& path,
-                                     EntriesCallback* success_callback,
-                                     ErrorCallbackBase* error_callback,
-                                     SynchronousType synchronous_type) {
+int DOMFileSystemBase::ReadDirectory(
+    DirectoryReaderBase* reader,
+    const String& path,
+    DirectoryReaderOnDidReadCallback* success_callback,
+    ErrorCallbackBase* error_callback,
+    SynchronousType synchronous_type) {
   if (!FileSystem()) {
     ReportError(error_callback, FileError::kAbortErr);
     return 0;
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h
index d732b38..d61d0655 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h
@@ -47,14 +47,14 @@
 namespace blink {
 
 class DirectoryReaderBase;
-class EntriesCallback;
+class DirectoryReaderOnDidReadCallback;
 class EntryBase;
 class EntryCallback;
 class ErrorCallbackBase;
+class ExecutionContext;
 class File;
 class FileMetadata;
 class MetadataCallback;
-class ExecutionContext;
 class SecurityOrigin;
 class VoidCallback;
 
@@ -153,7 +153,7 @@
                     SynchronousType = kAsynchronous);
   int ReadDirectory(DirectoryReaderBase*,
                     const String& path,
-                    EntriesCallback*,
+                    DirectoryReaderOnDidReadCallback*,
                     ErrorCallbackBase*,
                     SynchronousType = kAsynchronous);
   bool WaitForAdditionalResult(int callbacks_id);
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemSync.cpp b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemSync.cpp
index b46d114..59dfe86 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemSync.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemSync.cpp
@@ -38,7 +38,6 @@
 #include "core/fileapi/FileError.h"
 #include "modules/filesystem/DOMFilePath.h"
 #include "modules/filesystem/DirectoryEntrySync.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileEntrySync.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
 #include "modules/filesystem/FileWriterBaseCallback.h"
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.cpp
index 773674e..0f0d48d 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.cpp
@@ -31,7 +31,6 @@
 #include "core/frame/UseCounter.h"
 #include "modules/filesystem/DOMFileSystem.h"
 #include "modules/filesystem/EntryCallback.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileSystemCallback.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
 #include "modules/filesystem/LocalFileSystem.h"
@@ -46,7 +45,7 @@
     int type,
     long long size,
     FileSystemCallback* success_callback,
-    ErrorCallback* error_callback) {
+    V8ErrorCallback* error_callback) {
   if (!window.IsCurrentlyDisplayedInFrame())
     return;
 
@@ -86,7 +85,7 @@
     LocalDOMWindow& window,
     const String& url,
     EntryCallback* success_callback,
-    ErrorCallback* error_callback) {
+    V8ErrorCallback* error_callback) {
   if (!window.IsCurrentlyDisplayedInFrame())
     return;
 
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.h b/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.h
index ee300e9..5934769 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.h
+++ b/third_party/WebKit/Source/modules/filesystem/DOMWindowFileSystem.h
@@ -33,9 +33,9 @@
 namespace blink {
 
 class EntryCallback;
-class ErrorCallback;
 class FileSystemCallback;
 class LocalDOMWindow;
+class V8ErrorCallback;
 
 class DOMWindowFileSystem {
   STATIC_ONLY(DOMWindowFileSystem);
@@ -45,11 +45,11 @@
                                       int type,
                                       long long size,
                                       FileSystemCallback*,
-                                      ErrorCallback*);
+                                      V8ErrorCallback*);
   static void webkitResolveLocalFileSystemURL(LocalDOMWindow&,
                                               const String&,
                                               EntryCallback*,
-                                              ErrorCallback*);
+                                              V8ErrorCallback*);
 
   // They are placed here and in all capital letters so they can be checked
   // against the constants in the IDL at compile time.
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.cpp b/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.cpp
index c2c18e07..de9a788 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.cpp
@@ -34,7 +34,6 @@
 #include "core/html/VoidCallback.h"
 #include "modules/filesystem/DirectoryReader.h"
 #include "modules/filesystem/EntryCallback.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
 #include "modules/filesystem/FileSystemFlags.h"
 
@@ -51,7 +50,7 @@
 void DirectoryEntry::getFile(const String& path,
                              const FileSystemFlags& options,
                              EntryCallback* success_callback,
-                             ErrorCallback* error_callback) {
+                             V8ErrorCallback* error_callback) {
   file_system_->GetFile(this, path, options, success_callback,
                         ScriptErrorCallback::Wrap(error_callback));
 }
@@ -59,13 +58,13 @@
 void DirectoryEntry::getDirectory(const String& path,
                                   const FileSystemFlags& options,
                                   EntryCallback* success_callback,
-                                  ErrorCallback* error_callback) {
+                                  V8ErrorCallback* error_callback) {
   file_system_->GetDirectory(this, path, options, success_callback,
                              ScriptErrorCallback::Wrap(error_callback));
 }
 
 void DirectoryEntry::removeRecursively(VoidCallback* success_callback,
-                                       ErrorCallback* error_callback) const {
+                                       V8ErrorCallback* error_callback) const {
   file_system_->RemoveRecursively(this, success_callback,
                                   ScriptErrorCallback::Wrap(error_callback));
 }
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.h b/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.h
index 14fed9d8..a6279043 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.h
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryEntry.h
@@ -41,8 +41,8 @@
 class DOMFileSystemBase;
 class DirectoryReader;
 class EntryCallback;
-class ErrorCallback;
 class FileSystemFlags;
+class V8ErrorCallback;
 class VoidCallback;
 
 class MODULES_EXPORT DirectoryEntry final : public Entry {
@@ -59,13 +59,13 @@
   void getFile(const String& path,
                const FileSystemFlags&,
                EntryCallback* = nullptr,
-               ErrorCallback* = nullptr);
+               V8ErrorCallback* = nullptr);
   void getDirectory(const String& path,
                     const FileSystemFlags&,
                     EntryCallback* = nullptr,
-                    ErrorCallback* = nullptr);
+                    V8ErrorCallback* = nullptr);
   void removeRecursively(VoidCallback* success_callback = nullptr,
-                         ErrorCallback* = nullptr) const;
+                         V8ErrorCallback* = nullptr) const;
 
   void Trace(blink::Visitor*) override;
 
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
index 885518a7..0e62d29d 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
@@ -30,34 +30,35 @@
 
 #include "modules/filesystem/DirectoryReader.h"
 
+#include "bindings/modules/v8/V8EntriesCallback.h"
+#include "bindings/modules/v8/V8ErrorCallback.h"
 #include "core/fileapi/FileError.h"
-#include "modules/filesystem/EntriesCallback.h"
 #include "modules/filesystem/Entry.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
 
 namespace blink {
 
 namespace {
 
-void RunEntriesCallback(EntriesCallback* callback,
+void RunEntriesCallback(V8EntriesCallback* callback,
                         HeapVector<Member<Entry>>* entries) {
   callback->handleEvent(*entries);
 }
 
 }  // namespace
 
-class DirectoryReader::EntriesCallbackHelper final : public EntriesCallback {
+class DirectoryReader::EntriesCallbackHelper final
+    : public DirectoryReaderOnDidReadCallback {
  public:
   explicit EntriesCallbackHelper(DirectoryReader* reader) : reader_(reader) {}
 
-  void handleEvent(const EntryHeapVector& entries) override {
+  void OnDidReadDirectoryEntries(const EntryHeapVector& entries) override {
     reader_->AddEntries(entries);
   }
 
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(reader_);
-    EntriesCallback::Trace(visitor);
+    DirectoryReaderOnDidReadCallback::Trace(visitor);
   }
 
  private:
@@ -87,8 +88,8 @@
 
 DirectoryReader::~DirectoryReader() {}
 
-void DirectoryReader::readEntries(EntriesCallback* entries_callback,
-                                  ErrorCallback* error_callback) {
+void DirectoryReader::readEntries(V8EntriesCallback* entries_callback,
+                                  V8ErrorCallback* error_callback) {
   if (!is_reading_) {
     is_reading_ = true;
     Filesystem()->ReadDirectory(this, full_path_,
@@ -130,7 +131,7 @@
   entries_.AppendVector(entries);
   error_callback_ = nullptr;
   if (entries_callback_) {
-    EntriesCallback* entries_callback = entries_callback_.Release();
+    V8EntriesCallback* entries_callback = entries_callback_.Release();
     EntryHeapVector entries;
     entries.swap(entries_);
     entries_callback->handleEvent(entries);
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h
index 688ea38..8c51467 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h
@@ -33,13 +33,13 @@
 
 #include "modules/filesystem/DOMFileSystem.h"
 #include "modules/filesystem/DirectoryReaderBase.h"
-#include "modules/filesystem/EntriesCallback.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
-class ErrorCallback;
+class V8EntriesCallback;
+class V8ErrorCallback;
 
 class DirectoryReader : public DirectoryReaderBase {
   DEFINE_WRAPPERTYPEINFO();
@@ -52,7 +52,7 @@
 
   ~DirectoryReader() override;
 
-  void readEntries(EntriesCallback*, ErrorCallback* = nullptr);
+  void readEntries(V8EntriesCallback*, V8ErrorCallback* = nullptr);
 
   DOMFileSystem* Filesystem() const {
     return static_cast<DOMFileSystem*>(file_system_.Get());
@@ -73,8 +73,8 @@
   bool is_reading_;
   EntryHeapVector entries_;
   FileError::ErrorCode error_ = FileError::ErrorCode::kOK;
-  Member<EntriesCallback> entries_callback_;
-  Member<ErrorCallback> error_callback_;
+  Member<V8EntriesCallback> entries_callback_;
+  Member<V8ErrorCallback> error_callback_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h
index a32a7d6..cf66c90 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h
@@ -31,13 +31,15 @@
 #ifndef DirectoryReaderBase_h
 #define DirectoryReaderBase_h
 
-#include "modules/filesystem/DOMFileSystemBase.h"
+#include "modules/filesystem/EntryHeapVector.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/text/WTFString.h"
 
 namespace blink {
 
+class DOMFileSystemBase;
+
 class DirectoryReaderBase : public ScriptWrappable {
  public:
   DOMFileSystemBase* Filesystem() const { return file_system_.Get(); }
@@ -66,6 +68,17 @@
   bool has_more_entries_;
 };
 
+class DirectoryReaderOnDidReadCallback
+    : public GarbageCollectedFinalized<DirectoryReaderOnDidReadCallback> {
+ public:
+  virtual ~DirectoryReaderOnDidReadCallback() = default;
+  virtual void Trace(blink::Visitor* visitor) {}
+  virtual void OnDidReadDirectoryEntries(const EntryHeapVector&) = 0;
+
+ protected:
+  DirectoryReaderOnDidReadCallback() = default;
+};
+
 }  // namespace blink
 
 #endif  // DirectoryReaderBase_h
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp
index 3ad9e548..aef032a 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp
@@ -33,21 +33,19 @@
 #include "bindings/core/v8/ExceptionState.h"
 #include "modules/filesystem/DirectoryEntry.h"
 #include "modules/filesystem/DirectoryEntrySync.h"
-#include "modules/filesystem/EntriesCallback.h"
 #include "modules/filesystem/EntrySync.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileEntrySync.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
 
 namespace blink {
 
 class DirectoryReaderSync::EntriesCallbackHelper final
-    : public EntriesCallback {
+    : public DirectoryReaderOnDidReadCallback {
  public:
   explicit EntriesCallbackHelper(DirectoryReaderSync* reader)
       : reader_(reader) {}
 
-  void handleEvent(const EntryHeapVector& entries) override {
+  void OnDidReadDirectoryEntries(const EntryHeapVector& entries) override {
     EntrySyncHeapVector sync_entries;
     sync_entries.ReserveInitialCapacity(entries.size());
     for (size_t i = 0; i < entries.size(); ++i)
@@ -57,7 +55,7 @@
 
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(reader_);
-    EntriesCallback::Trace(visitor);
+    DirectoryReaderOnDidReadCallback::Trace(visitor);
   }
 
  private:
diff --git a/third_party/WebKit/Source/modules/filesystem/EntriesCallback.h b/third_party/WebKit/Source/modules/filesystem/EntriesCallback.h
index 3c5f6d6..950186bf 100644
--- a/third_party/WebKit/Source/modules/filesystem/EntriesCallback.h
+++ b/third_party/WebKit/Source/modules/filesystem/EntriesCallback.h
@@ -31,13 +31,11 @@
 #ifndef EntriesCallback_h
 #define EntriesCallback_h
 
+#include "modules/filesystem/EntryHeapVector.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
 
-class Entry;
-typedef HeapVector<Member<Entry>> EntryHeapVector;
-
 class EntriesCallback : public GarbageCollectedFinalized<EntriesCallback> {
  public:
   virtual ~EntriesCallback() {}
diff --git a/third_party/WebKit/Source/modules/filesystem/Entry.cpp b/third_party/WebKit/Source/modules/filesystem/Entry.cpp
index 41cd22c..8158631a 100644
--- a/third_party/WebKit/Source/modules/filesystem/Entry.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/Entry.cpp
@@ -35,7 +35,6 @@
 #include "core/html/VoidCallback.h"
 #include "modules/filesystem/DirectoryEntry.h"
 #include "modules/filesystem/EntryCallback.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
 #include "modules/filesystem/MetadataCallback.h"
 #include "platform/bindings/ScriptState.h"
@@ -58,7 +57,7 @@
 
 void Entry::getMetadata(ScriptState* script_state,
                         MetadataCallback* success_callback,
-                        ErrorCallback* error_callback) {
+                        V8ErrorCallback* error_callback) {
   if (file_system_->GetType() == kFileSystemTypeIsolated) {
     UseCounter::Count(ExecutionContext::From(script_state),
                       WebFeature::kEntry_GetMetadata_Method_IsolatedFileSystem);
@@ -71,7 +70,7 @@
                    DirectoryEntry* parent,
                    const String& name,
                    EntryCallback* success_callback,
-                   ErrorCallback* error_callback) const {
+                   V8ErrorCallback* error_callback) const {
   if (file_system_->GetType() == kFileSystemTypeIsolated) {
     UseCounter::Count(ExecutionContext::From(script_state),
                       WebFeature::kEntry_MoveTo_Method_IsolatedFileSystem);
@@ -84,7 +83,7 @@
                    DirectoryEntry* parent,
                    const String& name,
                    EntryCallback* success_callback,
-                   ErrorCallback* error_callback) const {
+                   V8ErrorCallback* error_callback) const {
   if (file_system_->GetType() == kFileSystemTypeIsolated) {
     UseCounter::Count(ExecutionContext::From(script_state),
                       WebFeature::kEntry_CopyTo_Method_IsolatedFileSystem);
@@ -95,7 +94,7 @@
 
 void Entry::remove(ScriptState* script_state,
                    VoidCallback* success_callback,
-                   ErrorCallback* error_callback) const {
+                   V8ErrorCallback* error_callback) const {
   if (file_system_->GetType() == kFileSystemTypeIsolated) {
     UseCounter::Count(ExecutionContext::From(script_state),
                       WebFeature::kEntry_Remove_Method_IsolatedFileSystem);
@@ -106,7 +105,7 @@
 
 void Entry::getParent(ScriptState* script_state,
                       EntryCallback* success_callback,
-                      ErrorCallback* error_callback) const {
+                      V8ErrorCallback* error_callback) const {
   if (file_system_->GetType() == kFileSystemTypeIsolated) {
     UseCounter::Count(ExecutionContext::From(script_state),
                       WebFeature::kEntry_GetParent_Method_IsolatedFileSystem);
diff --git a/third_party/WebKit/Source/modules/filesystem/Entry.h b/third_party/WebKit/Source/modules/filesystem/Entry.h
index b5b08ae5..47259d6 100644
--- a/third_party/WebKit/Source/modules/filesystem/Entry.h
+++ b/third_party/WebKit/Source/modules/filesystem/Entry.h
@@ -40,8 +40,8 @@
 
 class DirectoryEntry;
 class EntryCallback;
-class ErrorCallback;
 class MetadataCallback;
+class V8ErrorCallback;
 class VoidCallback;
 
 class MODULES_EXPORT Entry : public EntryBase {
@@ -55,23 +55,23 @@
 
   void getMetadata(ScriptState*,
                    MetadataCallback* success_callback = nullptr,
-                   ErrorCallback* = nullptr);
+                   V8ErrorCallback* = nullptr);
   void moveTo(ScriptState*,
               DirectoryEntry* parent,
               const String& name = String(),
               EntryCallback* success_callback = nullptr,
-              ErrorCallback* = nullptr) const;
+              V8ErrorCallback* = nullptr) const;
   void copyTo(ScriptState*,
               DirectoryEntry* parent,
               const String& name = String(),
               EntryCallback* success_callback = nullptr,
-              ErrorCallback* = nullptr) const;
+              V8ErrorCallback* = nullptr) const;
   void remove(ScriptState*,
               VoidCallback* success_callback = nullptr,
-              ErrorCallback* = nullptr) const;
+              V8ErrorCallback* = nullptr) const;
   void getParent(ScriptState*,
                  EntryCallback* success_callback = nullptr,
-                 ErrorCallback* = nullptr) const;
+                 V8ErrorCallback* = nullptr) const;
   String toURL(ScriptState*) const;
 
   void Trace(blink::Visitor*) override;
diff --git a/third_party/WebKit/Source/modules/filesystem/EntryHeapVector.h b/third_party/WebKit/Source/modules/filesystem/EntryHeapVector.h
new file mode 100644
index 0000000..e755f24
--- /dev/null
+++ b/third_party/WebKit/Source/modules/filesystem/EntryHeapVector.h
@@ -0,0 +1,18 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EntryHeapVector_h
+#define EntryHeapVector_h
+
+#include "platform/heap/Handle.h"
+
+namespace blink {
+
+class Entry;
+
+using EntryHeapVector = HeapVector<Member<Entry>>;
+
+}  // namespace blink
+
+#endif  // EntryHeapVector_h
diff --git a/third_party/WebKit/Source/modules/filesystem/FileEntry.cpp b/third_party/WebKit/Source/modules/filesystem/FileEntry.cpp
index 9d2ff6f..10d5b3f8 100644
--- a/third_party/WebKit/Source/modules/filesystem/FileEntry.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/FileEntry.cpp
@@ -32,7 +32,6 @@
 
 #include "core/fileapi/File.h"
 #include "modules/filesystem/DOMFileSystem.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileCallback.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
 #include "modules/filesystem/FileWriterCallback.h"
@@ -43,13 +42,13 @@
     : Entry(file_system, full_path) {}
 
 void FileEntry::createWriter(FileWriterCallback* success_callback,
-                             ErrorCallback* error_callback) {
+                             V8ErrorCallback* error_callback) {
   filesystem()->CreateWriter(this, success_callback,
                              ScriptErrorCallback::Wrap(error_callback));
 }
 
 void FileEntry::file(FileCallback* success_callback,
-                     ErrorCallback* error_callback) {
+                     V8ErrorCallback* error_callback) {
   filesystem()->CreateFile(this, success_callback,
                            ScriptErrorCallback::Wrap(error_callback));
 }
diff --git a/third_party/WebKit/Source/modules/filesystem/FileEntry.h b/third_party/WebKit/Source/modules/filesystem/FileEntry.h
index a1c3d44..8b965ab1 100644
--- a/third_party/WebKit/Source/modules/filesystem/FileEntry.h
+++ b/third_party/WebKit/Source/modules/filesystem/FileEntry.h
@@ -50,8 +50,8 @@
     return new FileEntry(file_system, full_path);
   }
 
-  void createWriter(FileWriterCallback*, ErrorCallback* = nullptr);
-  void file(FileCallback*, ErrorCallback* = nullptr);
+  void createWriter(FileWriterCallback*, V8ErrorCallback* = nullptr);
+  void file(FileCallback*, V8ErrorCallback* = nullptr);
 
   bool isFile() const override { return true; }
 
diff --git a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
index 2246cd40..043d8cb6 100644
--- a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
@@ -33,6 +33,7 @@
 #include <memory>
 
 #include "base/memory/ptr_util.h"
+#include "bindings/modules/v8/V8ErrorCallback.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/fileapi/File.h"
 #include "core/fileapi/FileError.h"
@@ -44,7 +45,6 @@
 #include "modules/filesystem/DirectoryReader.h"
 #include "modules/filesystem/Entry.h"
 #include "modules/filesystem/EntryCallback.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileCallback.h"
 #include "modules/filesystem/FileEntry.h"
 #include "modules/filesystem/FileSystemCallback.h"
@@ -135,7 +135,7 @@
 // ScriptErrorCallback --------------------------------------------------------
 
 // static
-ScriptErrorCallback* ScriptErrorCallback::Wrap(ErrorCallback* callback) {
+ScriptErrorCallback* ScriptErrorCallback::Wrap(V8ErrorCallback* callback) {
   // DOMFileSystem operations take an optional (nullable) callback. If a
   // script callback was not passed, don't bother creating a dummy wrapper
   // and checking during invoke().
@@ -153,7 +153,7 @@
   callback_->handleEvent(FileError::CreateDOMException(error));
 };
 
-ScriptErrorCallback::ScriptErrorCallback(ErrorCallback* callback)
+ScriptErrorCallback::ScriptErrorCallback(V8ErrorCallback* callback)
     : callback_(callback) {}
 
 // EntryCallbacks -------------------------------------------------------------
@@ -197,7 +197,7 @@
 // EntriesCallbacks -----------------------------------------------------------
 
 std::unique_ptr<AsyncFileSystemCallbacks> EntriesCallbacks::Create(
-    EntriesCallback* success_callback,
+    DirectoryReaderOnDidReadCallback* success_callback,
     ErrorCallbackBase* error_callback,
     ExecutionContext* context,
     DirectoryReaderBase* directory_reader,
@@ -206,11 +206,12 @@
       success_callback, error_callback, context, directory_reader, base_path));
 }
 
-EntriesCallbacks::EntriesCallbacks(EntriesCallback* success_callback,
-                                   ErrorCallbackBase* error_callback,
-                                   ExecutionContext* context,
-                                   DirectoryReaderBase* directory_reader,
-                                   const String& base_path)
+EntriesCallbacks::EntriesCallbacks(
+    DirectoryReaderOnDidReadCallback* success_callback,
+    ErrorCallbackBase* error_callback,
+    ExecutionContext* context,
+    DirectoryReaderBase* directory_reader,
+    const String& base_path)
     : FileSystemCallbacksBase(error_callback,
                               directory_reader->Filesystem(),
                               context),
@@ -238,7 +239,7 @@
   entries.swap(entries_);
   // FIXME: delay the callback iff shouldScheduleCallback() is true.
   if (success_callback_)
-    success_callback_->handleEvent(entries);
+    success_callback_->OnDidReadDirectoryEntries(entries);
 }
 
 // FileSystemCallbacks --------------------------------------------------------
diff --git a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h
index d2897740..eaaec38 100644
--- a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h
+++ b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h
@@ -32,10 +32,11 @@
 #define FileSystemCallbacks_h
 
 #include <memory>
+
 #include "core/fileapi/FileError.h"
-#include "modules/filesystem/EntriesCallback.h"
 #include "platform/AsyncFileSystemCallbacks.h"
 #include "platform/FileSystemType.h"
+#include "platform/heap/Handle.h"
 #include "platform/wtf/Vector.h"
 #include "platform/wtf/text/WTFString.h"
 
@@ -43,9 +44,9 @@
 
 class DOMFileSystemBase;
 class DirectoryReaderBase;
-class EntriesCallback;
+class DirectoryReaderOnDidReadCallback;
+class Entry;
 class EntryCallback;
-class ErrorCallback;
 class ExecutionContext;
 class FileCallback;
 class FileMetadata;
@@ -53,6 +54,7 @@
 class FileWriterBase;
 class FileWriterBaseCallback;
 class MetadataCallback;
+class V8ErrorCallback;
 class VoidCallback;
 
 // Passed to DOMFileSystem implementations that may report errors. Subclasses
@@ -101,15 +103,15 @@
 // Wraps a script-provided callback for use in DOMFileSystem operations.
 class ScriptErrorCallback final : public ErrorCallbackBase {
  public:
-  static ScriptErrorCallback* Wrap(ErrorCallback*);
+  static ScriptErrorCallback* Wrap(V8ErrorCallback*);
   ~ScriptErrorCallback() override {}
   void Trace(blink::Visitor*) override;
 
   void Invoke(FileError::ErrorCode) override;
 
  private:
-  explicit ScriptErrorCallback(ErrorCallback*);
-  Member<ErrorCallback> callback_;
+  explicit ScriptErrorCallback(V8ErrorCallback*);
+  Member<V8ErrorCallback> callback_;
 };
 
 class EntryCallbacks final : public FileSystemCallbacksBase {
@@ -138,7 +140,7 @@
 class EntriesCallbacks final : public FileSystemCallbacksBase {
  public:
   static std::unique_ptr<AsyncFileSystemCallbacks> Create(
-      EntriesCallback*,
+      DirectoryReaderOnDidReadCallback*,
       ErrorCallbackBase*,
       ExecutionContext*,
       DirectoryReaderBase*,
@@ -147,12 +149,12 @@
   void DidReadDirectoryEntries(bool has_more) override;
 
  private:
-  EntriesCallbacks(EntriesCallback*,
+  EntriesCallbacks(DirectoryReaderOnDidReadCallback*,
                    ErrorCallbackBase*,
                    ExecutionContext*,
                    DirectoryReaderBase*,
                    const String& base_path);
-  Persistent<EntriesCallback> success_callback_;
+  Persistent<DirectoryReaderOnDidReadCallback> success_callback_;
   Persistent<DirectoryReaderBase> directory_reader_;
   String base_path_;
   PersistentHeapVector<Member<Entry>> entries_;
diff --git a/third_party/WebKit/Source/modules/filesystem/HTMLInputElementFileSystem.h b/third_party/WebKit/Source/modules/filesystem/HTMLInputElementFileSystem.h
index cf2d244e..3631c4d 100644
--- a/third_party/WebKit/Source/modules/filesystem/HTMLInputElementFileSystem.h
+++ b/third_party/WebKit/Source/modules/filesystem/HTMLInputElementFileSystem.h
@@ -31,7 +31,7 @@
 #ifndef HTMLInputElementFileSystem_h
 #define HTMLInputElementFileSystem_h
 
-#include "modules/filesystem/EntriesCallback.h"
+#include "modules/filesystem/EntryHeapVector.h"
 #include "platform/wtf/Allocator.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h b/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h
index 6007c43..ce36acc0 100644
--- a/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h
+++ b/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h
@@ -36,7 +36,6 @@
 #include "core/fileapi/FileError.h"
 #include "core/html/VoidCallback.h"
 #include "modules/filesystem/DirectoryEntry.h"
-#include "modules/filesystem/EntriesCallback.h"
 #include "modules/filesystem/EntryCallback.h"
 #include "modules/filesystem/EntrySync.h"
 #include "modules/filesystem/FileEntry.h"
diff --git a/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.cpp b/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.cpp
index c6f21d2..dde072c 100644
--- a/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.cpp
@@ -28,6 +28,7 @@
 #include "modules/filesystem/WorkerGlobalScopeFileSystem.h"
 
 #include <memory>
+
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/fileapi/FileError.h"
@@ -35,7 +36,6 @@
 #include "core/workers/WorkerGlobalScope.h"
 #include "modules/filesystem/DOMFileSystemBase.h"
 #include "modules/filesystem/DirectoryEntrySync.h"
-#include "modules/filesystem/ErrorCallback.h"
 #include "modules/filesystem/FileEntrySync.h"
 #include "modules/filesystem/FileSystemCallback.h"
 #include "modules/filesystem/FileSystemCallbacks.h"
@@ -51,7 +51,7 @@
     int type,
     long long size,
     FileSystemCallback* success_callback,
-    ErrorCallback* error_callback) {
+    V8ErrorCallback* error_callback) {
   ExecutionContext* secure_context = worker.GetExecutionContext();
   if (!secure_context->GetSecurityOrigin()->CanAccessFileSystem()) {
     DOMFileSystem::ReportError(&worker,
@@ -114,7 +114,7 @@
     WorkerGlobalScope& worker,
     const String& url,
     EntryCallback* success_callback,
-    ErrorCallback* error_callback) {
+    V8ErrorCallback* error_callback) {
   KURL completed_url = worker.CompleteURL(url);
   ExecutionContext* secure_context = worker.GetExecutionContext();
   if (!secure_context->GetSecurityOrigin()->CanAccessFileSystem() ||
diff --git a/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.h b/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.h
index eb48cf8..7463295 100644
--- a/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.h
+++ b/third_party/WebKit/Source/modules/filesystem/WorkerGlobalScopeFileSystem.h
@@ -34,9 +34,9 @@
 
 class EntryCallback;
 class EntrySync;
-class ErrorCallback;
 class ExceptionState;
 class FileSystemCallback;
+class V8ErrorCallback;
 class WorkerGlobalScope;
 
 class WorkerGlobalScopeFileSystem {
@@ -52,7 +52,7 @@
                                       int type,
                                       long long size,
                                       FileSystemCallback* success_callback,
-                                      ErrorCallback*);
+                                      V8ErrorCallback*);
   static DOMFileSystemSync* webkitRequestFileSystemSync(WorkerGlobalScope&,
                                                         int type,
                                                         long long size,
@@ -60,7 +60,7 @@
   static void webkitResolveLocalFileSystemURL(WorkerGlobalScope&,
                                               const String& url,
                                               EntryCallback* success_callback,
-                                              ErrorCallback*);
+                                              V8ErrorCallback*);
   static EntrySync* webkitResolveLocalFileSystemSyncURL(WorkerGlobalScope&,
                                                         const String& url,
                                                         ExceptionState&);
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni
index b3cf1ae..a972568 100644
--- a/third_party/WebKit/Source/modules/modules_idl_files.gni
+++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -209,14 +209,11 @@
           "peerconnection/RTCIceCandidate.idl",
           "peerconnection/RTCLegacyStatsReport.idl",
           "peerconnection/RTCPeerConnection.idl",
-          "peerconnection/RTCPeerConnectionErrorCallback.idl",
           "peerconnection/RTCPeerConnectionIceEvent.idl",
           "peerconnection/RTCRtpContributingSource.idl",
           "peerconnection/RTCRtpReceiver.idl",
           "peerconnection/RTCRtpSender.idl",
           "peerconnection/RTCSessionDescription.idl",
-          "peerconnection/RTCSessionDescriptionCallback.idl",
-          "peerconnection/RTCStatsCallback.idl",
           "peerconnection/RTCStatsReport.idl",
           "peerconnection/RTCStatsResponse.idl",
           "peerconnection/RTCTrackEvent.idl",
@@ -242,10 +239,7 @@
           "quota/DOMError.idl",
           "quota/DeprecatedStorageInfo.idl",
           "quota/DeprecatedStorageQuota.idl",
-          "quota/StorageErrorCallback.idl",
           "quota/StorageManager.idl",
-          "quota/StorageQuotaCallback.idl",
-          "quota/StorageUsageCallback.idl",
           "remoteplayback/RemotePlayback.idl",
           "screen_orientation/ScreenOrientation.idl",
           "sensor/AbsoluteOrientationSensor.idl",
@@ -433,7 +427,11 @@
         "abspath")
 
 modules_callback_function_idl_files =
-    get_path_info([ "xr/XRFrameRequestCallback.idl" ], "abspath")
+    get_path_info([
+                    "xr/XRFrameRequestCallback.idl",
+                    "quota/DeprecatedStorageCallbacks.idl",
+                  ],
+                  "abspath")
 
 modules_dictionary_idl_files =
     get_path_info([
diff --git a/third_party/WebKit/Source/modules/peerconnection/BUILD.gn b/third_party/WebKit/Source/modules/peerconnection/BUILD.gn
index 7ce538d..20092612 100644
--- a/third_party/WebKit/Source/modules/peerconnection/BUILD.gn
+++ b/third_party/WebKit/Source/modules/peerconnection/BUILD.gn
@@ -22,7 +22,6 @@
     "RTCLegacyStatsReport.h",
     "RTCPeerConnection.cpp",
     "RTCPeerConnection.h",
-    "RTCPeerConnectionErrorCallback.h",
     "RTCPeerConnectionIceEvent.cpp",
     "RTCPeerConnectionIceEvent.h",
     "RTCRtpContributingSource.cpp",
@@ -33,12 +32,10 @@
     "RTCRtpSender.h",
     "RTCSessionDescription.cpp",
     "RTCSessionDescription.h",
-    "RTCSessionDescriptionCallback.h",
     "RTCSessionDescriptionRequestImpl.cpp",
     "RTCSessionDescriptionRequestImpl.h",
     "RTCSessionDescriptionRequestPromiseImpl.cpp",
     "RTCSessionDescriptionRequestPromiseImpl.h",
-    "RTCStatsCallback.h",
     "RTCStatsReport.cpp",
     "RTCStatsReport.h",
     "RTCStatsRequestImpl.cpp",
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
index a34a9593..734e2c4a 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -41,9 +41,13 @@
 #include "bindings/core/v8/Nullable.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/ScriptValue.h"
+#include "bindings/core/v8/v8_void_function.h"
 #include "bindings/modules/v8/V8MediaStreamTrack.h"
 #include "bindings/modules/v8/V8RTCCertificate.h"
 #include "bindings/modules/v8/rtc_ice_candidate_init_or_rtc_ice_candidate.h"
+#include "bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
+#include "bindings/modules/v8/v8_rtc_session_description_callback.h"
+#include "bindings/modules/v8/v8_rtc_stats_callback.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/DOMTimeStamp.h"
 #include "core/dom/Document.h"
@@ -54,7 +58,6 @@
 #include "core/frame/LocalFrame.h"
 #include "core/frame/LocalFrameClient.h"
 #include "core/frame/UseCounter.h"
-#include "core/html/VoidCallback.h"
 #include "modules/crypto/CryptoResultImpl.h"
 #include "modules/mediastream/MediaConstraintsImpl.h"
 #include "modules/mediastream/MediaStream.h"
@@ -67,16 +70,13 @@
 #include "modules/peerconnection/RTCDataChannelInit.h"
 #include "modules/peerconnection/RTCIceServer.h"
 #include "modules/peerconnection/RTCOfferOptions.h"
-#include "modules/peerconnection/RTCPeerConnectionErrorCallback.h"
 #include "modules/peerconnection/RTCPeerConnectionIceEvent.h"
 #include "modules/peerconnection/RTCRtpReceiver.h"
 #include "modules/peerconnection/RTCRtpSender.h"
 #include "modules/peerconnection/RTCSessionDescription.h"
-#include "modules/peerconnection/RTCSessionDescriptionCallback.h"
 #include "modules/peerconnection/RTCSessionDescriptionInit.h"
 #include "modules/peerconnection/RTCSessionDescriptionRequestImpl.h"
 #include "modules/peerconnection/RTCSessionDescriptionRequestPromiseImpl.h"
-#include "modules/peerconnection/RTCStatsCallback.h"
 #include "modules/peerconnection/RTCStatsReport.h"
 #include "modules/peerconnection/RTCStatsRequestImpl.h"
 #include "modules/peerconnection/RTCTrackEvent.h"
@@ -132,17 +132,18 @@
   return false;
 }
 
-void AsyncCallErrorCallback(RTCPeerConnectionErrorCallback* error_callback,
+void AsyncCallErrorCallback(V8RTCPeerConnectionErrorCallback* error_callback,
                             DOMException* exception) {
   DCHECK(error_callback);
   Microtask::EnqueueMicrotask(
-      WTF::Bind(&RTCPeerConnectionErrorCallback::handleEvent,
-                WrapPersistent(error_callback), WrapPersistent(exception)));
+      WTF::Bind(&V8RTCPeerConnectionErrorCallback::InvokeAndReportException,
+                WrapPersistentCallbackFunction(error_callback), nullptr,
+                WrapPersistent(exception)));
 }
 
 bool CallErrorCallbackIfSignalingStateClosed(
     RTCPeerConnection::SignalingState state,
-    RTCPeerConnectionErrorCallback* error_callback) {
+    V8RTCPeerConnectionErrorCallback* error_callback) {
   if (state == RTCPeerConnection::kSignalingStateClosed) {
     if (error_callback)
       AsyncCallErrorCallback(
@@ -590,8 +591,8 @@
 
 ScriptPromise RTCPeerConnection::createOffer(
     ScriptState* script_state,
-    RTCSessionDescriptionCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback,
+    V8RTCSessionDescriptionCallback* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback,
     const Dictionary& rtc_offer_options,
     ExceptionState& exception_state) {
   DCHECK(success_callback);
@@ -666,8 +667,8 @@
 
 ScriptPromise RTCPeerConnection::createAnswer(
     ScriptState* script_state,
-    RTCSessionDescriptionCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback,
+    V8RTCSessionDescriptionCallback* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback,
     const Dictionary& media_constraints) {
   DCHECK(success_callback);
   DCHECK(error_callback);
@@ -725,8 +726,8 @@
 ScriptPromise RTCPeerConnection::setLocalDescription(
     ScriptState* script_state,
     const RTCSessionDescriptionInit& session_description_init,
-    VoidCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback) {
+    V8VoidFunction* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback) {
   ExecutionContext* context = ExecutionContext::From(script_state);
   if (success_callback && error_callback) {
     UseCounter::Count(
@@ -785,8 +786,8 @@
 ScriptPromise RTCPeerConnection::setRemoteDescription(
     ScriptState* script_state,
     const RTCSessionDescriptionInit& session_description_init,
-    VoidCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback) {
+    V8VoidFunction* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback) {
   ExecutionContext* context = ExecutionContext::From(script_state);
   if (success_callback && error_callback) {
     UseCounter::Count(
@@ -1017,8 +1018,8 @@
 ScriptPromise RTCPeerConnection::addIceCandidate(
     ScriptState* script_state,
     const RTCIceCandidateInitOrRTCIceCandidate& candidate,
-    VoidCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback) {
+    V8VoidFunction* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback) {
   DCHECK(success_callback);
   DCHECK(error_callback);
 
@@ -1212,7 +1213,7 @@
 }
 
 ScriptPromise RTCPeerConnection::getStats(ScriptState* script_state,
-                                          RTCStatsCallback* success_callback,
+                                          V8RTCStatsCallback* success_callback,
                                           MediaStreamTrack* selector) {
   ExecutionContext* context = ExecutionContext::From(script_state);
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
index 7b89fbb..92412b0 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
@@ -32,6 +32,7 @@
 #define RTCPeerConnection_h
 
 #include <memory>
+
 #include "bindings/core/v8/ActiveScriptWrappable.h"
 #include "bindings/core/v8/ScriptPromise.h"
 #include "core/dom/PausableObject.h"
@@ -47,6 +48,7 @@
 #include "public/platform/WebRTCPeerConnectionHandlerClient.h"
 
 namespace blink {
+
 class ExceptionState;
 class MediaStreamTrack;
 class RTCAnswerOptions;
@@ -56,16 +58,16 @@
 class RTCDataChannelInit;
 class RTCIceCandidateInitOrRTCIceCandidate;
 class RTCOfferOptions;
-class RTCPeerConnectionErrorCallback;
 class RTCPeerConnectionTest;
 class RTCRtpReceiver;
 class RTCRtpSender;
 class RTCSessionDescription;
-class RTCSessionDescriptionCallback;
 class RTCSessionDescriptionInit;
-class RTCStatsCallback;
 class ScriptState;
-class VoidCallback;
+class V8RTCPeerConnectionErrorCallback;
+class V8RTCSessionDescriptionCallback;
+class V8RTCStatsCallback;
+class V8VoidFunction;
 struct WebRTCConfiguration;
 
 class MODULES_EXPORT RTCPeerConnection final
@@ -87,31 +89,31 @@
 
   ScriptPromise createOffer(ScriptState*, const RTCOfferOptions&);
   ScriptPromise createOffer(ScriptState*,
-                            RTCSessionDescriptionCallback*,
-                            RTCPeerConnectionErrorCallback*,
+                            V8RTCSessionDescriptionCallback*,
+                            V8RTCPeerConnectionErrorCallback*,
                             const Dictionary&,
                             ExceptionState&);
 
   ScriptPromise createAnswer(ScriptState*, const RTCAnswerOptions&);
   ScriptPromise createAnswer(ScriptState*,
-                             RTCSessionDescriptionCallback*,
-                             RTCPeerConnectionErrorCallback*,
+                             V8RTCSessionDescriptionCallback*,
+                             V8RTCPeerConnectionErrorCallback*,
                              const Dictionary&);
 
   ScriptPromise setLocalDescription(ScriptState*,
                                     const RTCSessionDescriptionInit&);
   ScriptPromise setLocalDescription(ScriptState*,
                                     const RTCSessionDescriptionInit&,
-                                    VoidCallback*,
-                                    RTCPeerConnectionErrorCallback*);
+                                    V8VoidFunction*,
+                                    V8RTCPeerConnectionErrorCallback*);
   RTCSessionDescription* localDescription();
 
   ScriptPromise setRemoteDescription(ScriptState*,
                                      const RTCSessionDescriptionInit&);
   ScriptPromise setRemoteDescription(ScriptState*,
                                      const RTCSessionDescriptionInit&,
-                                     VoidCallback*,
-                                     RTCPeerConnectionErrorCallback*);
+                                     V8VoidFunction*,
+                                     V8RTCPeerConnectionErrorCallback*);
   RTCSessionDescription* remoteDescription();
 
   String signalingState() const;
@@ -129,8 +131,8 @@
                                 const RTCIceCandidateInitOrRTCIceCandidate&);
   ScriptPromise addIceCandidate(ScriptState*,
                                 const RTCIceCandidateInitOrRTCIceCandidate&,
-                                VoidCallback*,
-                                RTCPeerConnectionErrorCallback*);
+                                V8VoidFunction*,
+                                V8RTCPeerConnectionErrorCallback*);
 
   String iceGatheringState() const;
 
@@ -153,7 +155,7 @@
   void removeStream(MediaStream*, ExceptionState&);
 
   ScriptPromise getStats(ScriptState*,
-                         RTCStatsCallback* success_callback,
+                         V8RTCStatsCallback* success_callback,
                          MediaStreamTrack* selector = nullptr);
   ScriptPromise getStats(ScriptState*);
 
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.idl b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.idl
index 962fb327..fe166495 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.idl
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.idl
@@ -59,7 +59,6 @@
 
 // TODO(guidou): Many types are of the wrong type in this interface:
 //  * Dictionary -> specific dictionary types like RTCConfiguration
-//  * VoidCallback -> VoidFunction
 [
     ActiveScriptWrappable,
     // TODO(guidou): There should only be one constructor argument.
@@ -96,10 +95,10 @@
     [CallWith=ScriptState, RaisesException] Promise<void> createOffer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional Dictionary rtcOfferOptions);
     // TODO(guidou): There should be no mediaConstraints argument.
     [CallWith=ScriptState] Promise<void> createAnswer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional Dictionary mediaConstraints);
-    [CallWith=ScriptState] Promise<void> setLocalDescription(RTCSessionDescriptionInit description, VoidCallback successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback);
+    [CallWith=ScriptState] Promise<void> setLocalDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback);
     // TODO(guidou): The failureCallback argument should be non-optional.
-    [CallWith=ScriptState] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description, VoidCallback successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback);
-    [CallWith=ScriptState, MeasureAs=RTCPeerConnectionAddIceCandidateLegacy] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate, VoidCallback successCallback, RTCPeerConnectionErrorCallback failureCallback);
+    [CallWith=ScriptState] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, [Default=Undefined] optional RTCPeerConnectionErrorCallback failureCallback);
+    [CallWith=ScriptState, MeasureAs=RTCPeerConnectionAddIceCandidateLegacy] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
 
     // TODO(guidou): The selector argument should the first (nullable,
     // non-optional) argument, and there should be a third failureCallback
@@ -139,3 +138,14 @@
     attribute EventHandler onaddstream;
     attribute EventHandler onremovestream;
 };
+
+// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnectionerrorcallback
+callback RTCPeerConnectionErrorCallback = void (DOMException error);
+
+// https://w3c.github.io/webrtc-pc/#dom-rtcsessiondescriptioncallback
+// TODO(yukishiino): The argument type must be RTCSessionDescriptionInit instead
+// of RTCSessionDescription.
+callback RTCSessionDescriptionCallback = void (RTCSessionDescription description);
+
+// No spec.  Blink specific definition.
+callback RTCStatsCallback = void (RTCStatsResponse response);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionErrorCallback.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionErrorCallback.h
deleted file mode 100644
index 5d598d7e..0000000
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionErrorCallback.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef RTCPeerConnectionErrorCallback_h
-#define RTCPeerConnectionErrorCallback_h
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class DOMException;
-
-class RTCPeerConnectionErrorCallback
-    : public GarbageCollectedFinalized<RTCPeerConnectionErrorCallback> {
- public:
-  virtual ~RTCPeerConnectionErrorCallback() {}
-  virtual void handleEvent(DOMException*) = 0;
-  virtual void Trace(blink::Visitor* visitor) {}
-};
-
-}  // namespace blink
-
-#endif  // RTCPeerConnectionErrorCallback_h
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionErrorCallback.idl b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionErrorCallback.idl
deleted file mode 100644
index f42696d7..0000000
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnectionErrorCallback.idl
+++ /dev/null
@@ -1,9 +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.
-
-// https://w3c.github.io/webrtc-pc/#rtcpeerconnectionerrorcallback
-
-callback interface RTCPeerConnectionErrorCallback {
-    void handleEvent(DOMException exception);
-};
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionCallback.h b/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionCallback.h
deleted file mode 100644
index e4d789c9..0000000
--- a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionCallback.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 RTCSessionDescriptionCallback_h
-#define RTCSessionDescriptionCallback_h
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class RTCSessionDescription;
-
-class RTCSessionDescriptionCallback
-    : public GarbageCollectedFinalized<RTCSessionDescriptionCallback> {
- public:
-  virtual ~RTCSessionDescriptionCallback() {}
-  virtual void Trace(blink::Visitor* visitor) {}
-  virtual void handleEvent(RTCSessionDescription*) = 0;
-};
-
-}  // namespace blink
-
-#endif  // RTCSessionDescriptionCallback_h
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionCallback.idl b/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionCallback.idl
deleted file mode 100644
index 5bf268e..0000000
--- a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionCallback.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-callback interface RTCSessionDescriptionCallback {
-    void handleEvent(RTCSessionDescription sdp);
-};
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.cpp
index e4f9a82..2a243f3 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.cpp
@@ -34,9 +34,7 @@
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
 #include "modules/peerconnection/RTCPeerConnection.h"
-#include "modules/peerconnection/RTCPeerConnectionErrorCallback.h"
 #include "modules/peerconnection/RTCSessionDescription.h"
-#include "modules/peerconnection/RTCSessionDescriptionCallback.h"
 #include "public/platform/WebRTCSessionDescription.h"
 
 namespace blink {
@@ -44,8 +42,8 @@
 RTCSessionDescriptionRequestImpl* RTCSessionDescriptionRequestImpl::Create(
     ExecutionContext* context,
     RTCPeerConnection* requester,
-    RTCSessionDescriptionCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback) {
+    V8RTCSessionDescriptionCallback* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback) {
   return new RTCSessionDescriptionRequestImpl(context, requester,
                                               success_callback, error_callback);
 }
@@ -53,8 +51,8 @@
 RTCSessionDescriptionRequestImpl::RTCSessionDescriptionRequestImpl(
     ExecutionContext* context,
     RTCPeerConnection* requester,
-    RTCSessionDescriptionCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback)
+    V8RTCSessionDescriptionCallback* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback)
     : ContextLifecycleObserver(context),
       success_callback_(success_callback),
       error_callback_(error_callback),
@@ -68,18 +66,20 @@
     const WebRTCSessionDescription& web_session_description) {
   bool should_fire_callback =
       requester_ ? requester_->ShouldFireDefaultCallbacks() : false;
-  if (should_fire_callback && success_callback_)
-    success_callback_->handleEvent(
-        RTCSessionDescription::Create(web_session_description));
+  if (should_fire_callback && success_callback_) {
+    success_callback_->InvokeAndReportException(
+        nullptr, RTCSessionDescription::Create(web_session_description));
+  }
   Clear();
 }
 
 void RTCSessionDescriptionRequestImpl::RequestFailed(const String& error) {
   bool should_fire_callback =
       requester_ ? requester_->ShouldFireDefaultCallbacks() : false;
-  if (should_fire_callback && error_callback_)
-    error_callback_->handleEvent(DOMException::Create(kOperationError, error));
-
+  if (should_fire_callback && error_callback_) {
+    error_callback_->InvokeAndReportException(
+        nullptr, DOMException::Create(kOperationError, error));
+  }
   Clear();
 }
 
@@ -94,8 +94,6 @@
 }
 
 void RTCSessionDescriptionRequestImpl::Trace(blink::Visitor* visitor) {
-  visitor->Trace(success_callback_);
-  visitor->Trace(error_callback_);
   visitor->Trace(requester_);
   RTCSessionDescriptionRequest::Trace(visitor);
   ContextLifecycleObserver::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.h b/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.h
index 88670b3f..49da119 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCSessionDescriptionRequestImpl.h
@@ -32,6 +32,8 @@
 #define RTCSessionDescriptionRequestImpl_h
 
 #include "base/memory/scoped_refptr.h"
+#include "bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
+#include "bindings/modules/v8/v8_rtc_session_description_callback.h"
 #include "core/dom/ContextLifecycleObserver.h"
 #include "platform/heap/Handle.h"
 #include "platform/peerconnection/RTCSessionDescriptionRequest.h"
@@ -39,8 +41,6 @@
 namespace blink {
 
 class RTCPeerConnection;
-class RTCPeerConnectionErrorCallback;
-class RTCSessionDescriptionCallback;
 class WebRTCSessionDescription;
 
 class RTCSessionDescriptionRequestImpl final
@@ -52,8 +52,8 @@
   static RTCSessionDescriptionRequestImpl* Create(
       ExecutionContext*,
       RTCPeerConnection*,
-      RTCSessionDescriptionCallback*,
-      RTCPeerConnectionErrorCallback*);
+      V8RTCSessionDescriptionCallback*,
+      V8RTCPeerConnectionErrorCallback*);
   ~RTCSessionDescriptionRequestImpl() override;
 
   void RequestSucceeded(const WebRTCSessionDescription&) override;
@@ -67,13 +67,20 @@
  private:
   RTCSessionDescriptionRequestImpl(ExecutionContext*,
                                    RTCPeerConnection*,
-                                   RTCSessionDescriptionCallback*,
-                                   RTCPeerConnectionErrorCallback*);
+                                   V8RTCSessionDescriptionCallback*,
+                                   V8RTCPeerConnectionErrorCallback*);
 
   void Clear();
 
-  Member<RTCSessionDescriptionCallback> success_callback_;
-  Member<RTCPeerConnectionErrorCallback> error_callback_;
+  // This request object is held by WebRTCPeerConnectionHandler, which doesn't
+  // support wrapper-tracing. Thus, this object holds the underlying callback
+  // functions as persistent handles. This is acceptable because the request
+  // object will be discarded in a limited time due to success, failure, or
+  // destruction of the execution context.
+  V8RTCSessionDescriptionCallback::Persistent<V8RTCSessionDescriptionCallback>
+      success_callback_;
+  V8RTCPeerConnectionErrorCallback::Persistent<V8RTCPeerConnectionErrorCallback>
+      error_callback_;
   Member<RTCPeerConnection> requester_;
 };
 
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCStatsCallback.h b/third_party/WebKit/Source/modules/peerconnection/RTCStatsCallback.h
deleted file mode 100644
index 7821599..0000000
--- a/third_party/WebKit/Source/modules/peerconnection/RTCStatsCallback.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 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 APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCStatsCallback_h
-#define RTCStatsCallback_h
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class RTCStatsResponse;
-
-class RTCStatsCallback : public GarbageCollectedFinalized<RTCStatsCallback> {
- public:
-  virtual ~RTCStatsCallback() {}
-  virtual void Trace(blink::Visitor* visitor) {}
-  virtual void handleEvent(RTCStatsResponse*) = 0;
-};
-
-}  // namespace blink
-
-#endif  // RTCStatsCallback_h
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCStatsCallback.idl b/third_party/WebKit/Source/modules/peerconnection/RTCStatsCallback.idl
deleted file mode 100644
index acbecb2..0000000
--- a/third_party/WebKit/Source/modules/peerconnection/RTCStatsCallback.idl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 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 APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-callback interface RTCStatsCallback {
-    void handleEvent(RTCStatsResponse response);
-};
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.cpp
index 7d31d7e5..dc46f6ef 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.cpp
@@ -26,20 +26,19 @@
 
 #include "modules/mediastream/MediaStreamTrack.h"
 #include "modules/peerconnection/RTCPeerConnection.h"
-#include "modules/peerconnection/RTCStatsCallback.h"
 
 namespace blink {
 
 RTCStatsRequestImpl* RTCStatsRequestImpl::Create(ExecutionContext* context,
                                                  RTCPeerConnection* requester,
-                                                 RTCStatsCallback* callback,
+                                                 V8RTCStatsCallback* callback,
                                                  MediaStreamTrack* selector) {
   return new RTCStatsRequestImpl(context, requester, callback, selector);
 }
 
 RTCStatsRequestImpl::RTCStatsRequestImpl(ExecutionContext* context,
                                          RTCPeerConnection* requester,
-                                         RTCStatsCallback* callback,
+                                         V8RTCStatsCallback* callback,
                                          MediaStreamTrack* selector)
     : ContextLifecycleObserver(context),
       success_callback_(callback),
@@ -65,8 +64,10 @@
 void RTCStatsRequestImpl::RequestSucceeded(RTCStatsResponseBase* response) {
   bool should_fire_callback =
       requester_ ? requester_->ShouldFireGetStatsCallback() : false;
-  if (should_fire_callback && success_callback_)
-    success_callback_->handleEvent(static_cast<RTCStatsResponse*>(response));
+  if (should_fire_callback && success_callback_) {
+    success_callback_->InvokeAndReportException(
+        nullptr, static_cast<RTCStatsResponse*>(response));
+  }
   Clear();
 }
 
@@ -80,7 +81,6 @@
 }
 
 void RTCStatsRequestImpl::Trace(blink::Visitor* visitor) {
-  visitor->Trace(success_callback_);
   visitor->Trace(component_);
   visitor->Trace(requester_);
   RTCStatsRequest::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.h b/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.h
index f0aa0ad..b855541 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCStatsRequestImpl.h
@@ -25,6 +25,7 @@
 #ifndef RTCStatsRequestImpl_h
 #define RTCStatsRequestImpl_h
 
+#include "bindings/modules/v8/v8_rtc_stats_callback.h"
 #include "core/dom/ContextLifecycleObserver.h"
 #include "modules/peerconnection/RTCStatsResponse.h"
 #include "platform/heap/Handle.h"
@@ -36,7 +37,6 @@
 
 class MediaStreamTrack;
 class RTCPeerConnection;
-class RTCStatsCallback;
 
 class RTCStatsRequestImpl final : public RTCStatsRequest,
                                   public ContextLifecycleObserver {
@@ -45,7 +45,7 @@
  public:
   static RTCStatsRequestImpl* Create(ExecutionContext*,
                                      RTCPeerConnection*,
-                                     RTCStatsCallback*,
+                                     V8RTCStatsCallback*,
                                      MediaStreamTrack*);
   ~RTCStatsRequestImpl() override;
 
@@ -63,12 +63,17 @@
  private:
   RTCStatsRequestImpl(ExecutionContext*,
                       RTCPeerConnection*,
-                      RTCStatsCallback*,
+                      V8RTCStatsCallback*,
                       MediaStreamTrack*);
 
   void Clear();
 
-  Member<RTCStatsCallback> success_callback_;
+  // This request object is held by WebRTCPeerConnectionHandler, which doesn't
+  // support wrapper-tracing. Thus, this object holds the underlying callback
+  // functions as persistent handles. This is acceptable because the request
+  // object will be discarded in a limited time due to success, failure, or
+  // destruction of the execution context.
+  V8RTCStatsCallback::Persistent<V8RTCStatsCallback> success_callback_;
   Member<MediaStreamComponent> component_;
   Member<RTCPeerConnection> requester_;
 };
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.cpp
index d76439d..4af87b4 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.cpp
@@ -32,17 +32,15 @@
 
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/html/VoidCallback.h"
 #include "modules/peerconnection/RTCPeerConnection.h"
-#include "modules/peerconnection/RTCPeerConnectionErrorCallback.h"
 
 namespace blink {
 
 RTCVoidRequestImpl* RTCVoidRequestImpl::Create(
     ExecutionContext* context,
     RTCPeerConnection* requester,
-    VoidCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback) {
+    V8VoidFunction* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback) {
   return new RTCVoidRequestImpl(context, requester, success_callback,
                                 error_callback);
 }
@@ -50,8 +48,8 @@
 RTCVoidRequestImpl::RTCVoidRequestImpl(
     ExecutionContext* context,
     RTCPeerConnection* requester,
-    VoidCallback* success_callback,
-    RTCPeerConnectionErrorCallback* error_callback)
+    V8VoidFunction* success_callback,
+    V8RTCPeerConnectionErrorCallback* error_callback)
     : ContextLifecycleObserver(context),
       success_callback_(success_callback),
       error_callback_(error_callback),
@@ -65,7 +63,7 @@
   bool should_fire_callback =
       requester_ && requester_->ShouldFireDefaultCallbacks();
   if (should_fire_callback && success_callback_)
-    success_callback_->handleEvent();
+    success_callback_->InvokeAndReportException(nullptr);
 
   Clear();
 }
@@ -76,7 +74,8 @@
   if (should_fire_callback && error_callback_.Get()) {
     // TODO(guidou): The error code should come from the content layer. See
     // crbug.com/589455
-    error_callback_->handleEvent(DOMException::Create(kOperationError, error));
+    error_callback_->InvokeAndReportException(
+        nullptr, DOMException::Create(kOperationError, error));
   }
 
   Clear();
@@ -93,8 +92,6 @@
 }
 
 void RTCVoidRequestImpl::Trace(blink::Visitor* visitor) {
-  visitor->Trace(success_callback_);
-  visitor->Trace(error_callback_);
   visitor->Trace(requester_);
   RTCVoidRequest::Trace(visitor);
   ContextLifecycleObserver::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.h b/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.h
index ed5c097..dd351c09 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCVoidRequestImpl.h
@@ -31,6 +31,8 @@
 #ifndef RTCVoidRequestImpl_h
 #define RTCVoidRequestImpl_h
 
+#include "bindings/core/v8/v8_void_function.h"
+#include "bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
 #include "core/dom/ContextLifecycleObserver.h"
 #include "core/dom/ExceptionCode.h"
 #include "platform/heap/Handle.h"
@@ -39,8 +41,6 @@
 namespace blink {
 
 class RTCPeerConnection;
-class RTCPeerConnectionErrorCallback;
-class VoidCallback;
 
 class RTCVoidRequestImpl final : public RTCVoidRequest,
                                  public ContextLifecycleObserver {
@@ -49,8 +49,8 @@
  public:
   static RTCVoidRequestImpl* Create(ExecutionContext*,
                                     RTCPeerConnection*,
-                                    VoidCallback*,
-                                    RTCPeerConnectionErrorCallback*);
+                                    V8VoidFunction*,
+                                    V8RTCPeerConnectionErrorCallback*);
   ~RTCVoidRequestImpl() override;
 
   // RTCVoidRequest
@@ -65,13 +65,19 @@
  private:
   RTCVoidRequestImpl(ExecutionContext*,
                      RTCPeerConnection*,
-                     VoidCallback*,
-                     RTCPeerConnectionErrorCallback*);
+                     V8VoidFunction*,
+                     V8RTCPeerConnectionErrorCallback*);
 
   void Clear();
 
-  Member<VoidCallback> success_callback_;
-  Member<RTCPeerConnectionErrorCallback> error_callback_;
+  // This request object is held by WebRTCPeerConnectionHandler, which doesn't
+  // support wrapper-tracing. Thus, this object holds the underlying callback
+  // functions as persistent handles. This is acceptable because the request
+  // object will be discarded in a limited time due to success, failure, or
+  // destruction of the execution context.
+  V8VoidFunction::Persistent<V8VoidFunction> success_callback_;
+  V8RTCPeerConnectionErrorCallback::Persistent<V8RTCPeerConnectionErrorCallback>
+      error_callback_;
   Member<RTCPeerConnection> requester_;
 };
 
diff --git a/third_party/WebKit/Source/modules/quota/BUILD.gn b/third_party/WebKit/Source/modules/quota/BUILD.gn
index 7e2c269b..be0512e 100644
--- a/third_party/WebKit/Source/modules/quota/BUILD.gn
+++ b/third_party/WebKit/Source/modules/quota/BUILD.gn
@@ -18,14 +18,10 @@
     "DeprecatedStorageQuotaCallbacksImpl.h",
     "NavigatorStorageQuota.cpp",
     "NavigatorStorageQuota.h",
-    "StorageErrorCallback.cpp",
-    "StorageErrorCallback.h",
     "StorageManager.cpp",
     "StorageManager.h",
-    "StorageQuotaCallback.h",
     "StorageQuotaClient.cpp",
     "StorageQuotaClient.h",
-    "StorageUsageCallback.h",
     "WorkerNavigatorStorageQuota.cpp",
     "WorkerNavigatorStorageQuota.h",
   ]
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageCallbacks.idl b/third_party/WebKit/Source/modules/quota/DeprecatedStorageCallbacks.idl
new file mode 100644
index 0000000..d22c74b9
--- /dev/null
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageCallbacks.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://www.w3.org/TR/2012/WD-quota-api-20120703/#storageusagecallback-callback
+callback StorageUsageCallback = void (unsigned long long currentUsageInBytes, unsigned long long currentQuotaInBytes);
+
+// https://www.w3.org/TR/2012/WD-quota-api-20120703/#storagequotacallback-callback
+callback StorageQuotaCallback = void (unsigned long long grantedQuotaInBytes);
+
+// https://www.w3.org/TR/2012/WD-quota-api-20120703/#storageerrorcallback-callback
+callback StorageErrorCallback = void (DOMError error);
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp
index 3e6871dc..183cc031 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.cpp
@@ -34,9 +34,6 @@
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
 #include "modules/quota/DeprecatedStorageQuota.h"
-#include "modules/quota/StorageErrorCallback.h"
-#include "modules/quota/StorageQuotaCallback.h"
-#include "modules/quota/StorageUsageCallback.h"
 #include "platform/WebTaskRunner.h"
 #include "platform/bindings/ScriptState.h"
 #include "public/platform/TaskType.h"
@@ -48,37 +45,34 @@
 void DeprecatedStorageInfo::queryUsageAndQuota(
     ScriptState* script_state,
     int storage_type,
-    StorageUsageCallback* success_callback,
-    StorageErrorCallback* error_callback) {
+    V8StorageUsageCallback* success_callback,
+    V8StorageErrorCallback* error_callback) {
   // Dispatching the request to DeprecatedStorageQuota, as this interface is
   // deprecated in favor of DeprecatedStorageQuota.
   DeprecatedStorageQuota* storage_quota = GetStorageQuota(storage_type);
   if (!storage_quota) {
     // Unknown storage type is requested.
-    ExecutionContext::From(script_state)
-        ->GetTaskRunner(TaskType::kMiscPlatformAPI)
-        ->PostTask(FROM_HERE, StorageErrorCallback::CreateSameThreadTask(
-                                  error_callback, kNotSupportedError));
+    DeprecatedStorageQuota::EnqueueStorageErrorCallback(
+        script_state, error_callback, kNotSupportedError);
     return;
   }
   storage_quota->queryUsageAndQuota(script_state, success_callback,
                                     error_callback);
 }
 
-void DeprecatedStorageInfo::requestQuota(ScriptState* script_state,
-                                         int storage_type,
-                                         unsigned long long new_quota_in_bytes,
-                                         StorageQuotaCallback* success_callback,
-                                         StorageErrorCallback* error_callback) {
+void DeprecatedStorageInfo::requestQuota(
+    ScriptState* script_state,
+    int storage_type,
+    unsigned long long new_quota_in_bytes,
+    V8StorageQuotaCallback* success_callback,
+    V8StorageErrorCallback* error_callback) {
   // Dispatching the request to DeprecatedStorageQuota, as this interface is
   // deprecated in favor of DeprecatedStorageQuota.
   DeprecatedStorageQuota* storage_quota = GetStorageQuota(storage_type);
   if (!storage_quota) {
     // Unknown storage type is requested.
-    ExecutionContext::From(script_state)
-        ->GetTaskRunner(TaskType::kMiscPlatformAPI)
-        ->PostTask(FROM_HERE, StorageErrorCallback::CreateSameThreadTask(
-                                  error_callback, kNotSupportedError));
+    DeprecatedStorageQuota::EnqueueStorageErrorCallback(
+        script_state, error_callback, kNotSupportedError);
     return;
   }
   storage_quota->requestQuota(script_state, new_quota_in_bytes,
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.h b/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.h
index ad2337b..93cdeb1 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.h
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageInfo.h
@@ -39,9 +39,9 @@
 namespace blink {
 
 class ScriptState;
-class StorageErrorCallback;
-class StorageQuotaCallback;
-class StorageUsageCallback;
+class V8StorageErrorCallback;
+class V8StorageQuotaCallback;
+class V8StorageUsageCallback;
 
 class DeprecatedStorageInfo final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
@@ -56,14 +56,14 @@
 
   void queryUsageAndQuota(ScriptState*,
                           int storage_type,
-                          StorageUsageCallback*,
-                          StorageErrorCallback*);
+                          V8StorageUsageCallback* = nullptr,
+                          V8StorageErrorCallback* = nullptr);
 
   void requestQuota(ScriptState*,
                     int storage_type,
                     unsigned long long new_quota_in_bytes,
-                    StorageQuotaCallback*,
-                    StorageErrorCallback*);
+                    V8StorageQuotaCallback* = nullptr,
+                    V8StorageErrorCallback* = nullptr);
 
   void Trace(blink::Visitor*);
 
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
index 44a2a0f33..cdb7ba6 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
@@ -31,12 +31,12 @@
 #include "modules/quota/DeprecatedStorageQuota.h"
 
 #include "base/location.h"
+#include "bindings/modules/v8/v8_storage_error_callback.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
+#include "modules/quota/DOMError.h"
 #include "modules/quota/DeprecatedStorageQuotaCallbacksImpl.h"
-#include "modules/quota/StorageErrorCallback.h"
 #include "modules/quota/StorageQuotaClient.h"
-#include "modules/quota/StorageUsageCallback.h"
 #include "platform/StorageQuotaCallbacks.h"
 #include "platform/WebTaskRunner.h"
 #include "platform/bindings/ScriptState.h"
@@ -49,12 +49,28 @@
 
 namespace blink {
 
+void DeprecatedStorageQuota::EnqueueStorageErrorCallback(
+    ScriptState* script_state,
+    V8StorageErrorCallback* error_callback,
+    ExceptionCode exception_code) {
+  if (!error_callback)
+    return;
+
+  ExecutionContext::From(script_state)
+      ->GetTaskRunner(TaskType::kMiscPlatformAPI)
+      ->PostTask(
+          FROM_HERE,
+          WTF::Bind(&V8StorageErrorCallback::InvokeAndReportException,
+                    WrapPersistentCallbackFunction(error_callback), nullptr,
+                    WrapPersistent(DOMError::Create(exception_code))));
+}
+
 DeprecatedStorageQuota::DeprecatedStorageQuota(Type type) : type_(type) {}
 
 void DeprecatedStorageQuota::queryUsageAndQuota(
     ScriptState* script_state,
-    StorageUsageCallback* success_callback,
-    StorageErrorCallback* error_callback) {
+    V8StorageUsageCallback* success_callback,
+    V8StorageErrorCallback* error_callback) {
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
   DCHECK(execution_context);
 
@@ -62,20 +78,16 @@
   if (storage_type != kWebStorageQuotaTypeTemporary &&
       storage_type != kWebStorageQuotaTypePersistent) {
     // Unknown storage type is requested.
-    ExecutionContext::From(script_state)
-        ->GetTaskRunner(TaskType::kMiscPlatformAPI)
-        ->PostTask(FROM_HERE, StorageErrorCallback::CreateSameThreadTask(
-                                  error_callback, kNotSupportedError));
+    EnqueueStorageErrorCallback(script_state, error_callback,
+                                kNotSupportedError);
     return;
   }
 
   const SecurityOrigin* security_origin =
       execution_context->GetSecurityOrigin();
   if (security_origin->IsUnique()) {
-    ExecutionContext::From(script_state)
-        ->GetTaskRunner(TaskType::kMiscPlatformAPI)
-        ->PostTask(FROM_HERE, StorageErrorCallback::CreateSameThreadTask(
-                                  error_callback, kNotSupportedError));
+    EnqueueStorageErrorCallback(script_state, error_callback,
+                                kNotSupportedError);
     return;
   }
 
@@ -89,8 +101,8 @@
 void DeprecatedStorageQuota::requestQuota(
     ScriptState* script_state,
     unsigned long long new_quota_in_bytes,
-    StorageQuotaCallback* success_callback,
-    StorageErrorCallback* error_callback) {
+    V8StorageQuotaCallback* success_callback,
+    V8StorageErrorCallback* error_callback) {
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
   DCHECK(execution_context);
 
@@ -98,19 +110,15 @@
   if (storage_type != kWebStorageQuotaTypeTemporary &&
       storage_type != kWebStorageQuotaTypePersistent) {
     // Unknown storage type is requested.
-    ExecutionContext::From(script_state)
-        ->GetTaskRunner(TaskType::kMiscPlatformAPI)
-        ->PostTask(FROM_HERE, StorageErrorCallback::CreateSameThreadTask(
-                                  error_callback, kNotSupportedError));
+    EnqueueStorageErrorCallback(script_state, error_callback,
+                                kNotSupportedError);
     return;
   }
 
   StorageQuotaClient* client = StorageQuotaClient::From(execution_context);
   if (!client) {
-    ExecutionContext::From(script_state)
-        ->GetTaskRunner(TaskType::kMiscPlatformAPI)
-        ->PostTask(FROM_HERE, StorageErrorCallback::CreateSameThreadTask(
-                                  error_callback, kNotSupportedError));
+    EnqueueStorageErrorCallback(script_state, error_callback,
+                                kNotSupportedError);
     return;
   }
 
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.h b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.h
index df728bee3..e39ccb6 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.h
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.h
@@ -31,15 +31,16 @@
 #ifndef DeprecatedStorageQuota_h
 #define DeprecatedStorageQuota_h
 
+#include "core/dom/ExceptionCode.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
 
 class ScriptState;
-class StorageErrorCallback;
-class StorageQuotaCallback;
-class StorageUsageCallback;
+class V8StorageErrorCallback;
+class V8StorageQuotaCallback;
+class V8StorageUsageCallback;
 
 class DeprecatedStorageQuota final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
@@ -54,17 +55,22 @@
     return new DeprecatedStorageQuota(type);
   }
 
+  static void EnqueueStorageErrorCallback(ScriptState*,
+                                          V8StorageErrorCallback*,
+                                          ExceptionCode);
+
   void queryUsageAndQuota(ScriptState*,
-                          StorageUsageCallback*,
-                          StorageErrorCallback*);
+                          V8StorageUsageCallback*,
+                          V8StorageErrorCallback* = nullptr);
 
   void requestQuota(ScriptState*,
                     unsigned long long new_quota_in_bytes,
-                    StorageQuotaCallback*,
-                    StorageErrorCallback*);
+                    V8StorageQuotaCallback* = nullptr,
+                    V8StorageErrorCallback* = nullptr);
 
  private:
   explicit DeprecatedStorageQuota(Type);
+
   Type type_;
 };
 
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
index 623396ec..c919a5b 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
@@ -35,42 +35,46 @@
 namespace blink {
 
 DeprecatedStorageQuotaCallbacksImpl::DeprecatedStorageQuotaCallbacksImpl(
-    StorageUsageCallback* usage_callback,
-    StorageErrorCallback* error_callback)
-    : usage_callback_(usage_callback), error_callback_(error_callback) {}
+    V8StorageUsageCallback* usage_callback,
+    V8StorageErrorCallback* error_callback)
+    : usage_callback_(usage_callback),
+      quota_callback_(nullptr),
+      error_callback_(error_callback) {}
 
 DeprecatedStorageQuotaCallbacksImpl::DeprecatedStorageQuotaCallbacksImpl(
-    StorageQuotaCallback* quota_callback,
-    StorageErrorCallback* error_callback)
-    : quota_callback_(quota_callback), error_callback_(error_callback) {}
+    V8StorageQuotaCallback* quota_callback,
+    V8StorageErrorCallback* error_callback)
+    : usage_callback_(nullptr),
+      quota_callback_(quota_callback),
+      error_callback_(error_callback) {}
 
 DeprecatedStorageQuotaCallbacksImpl::~DeprecatedStorageQuotaCallbacksImpl() {}
 
 void DeprecatedStorageQuotaCallbacksImpl::Trace(blink::Visitor* visitor) {
-  visitor->Trace(usage_callback_);
-  visitor->Trace(quota_callback_);
-  visitor->Trace(error_callback_);
   StorageQuotaCallbacks::Trace(visitor);
 }
 
 void DeprecatedStorageQuotaCallbacksImpl::DidQueryStorageUsageAndQuota(
     unsigned long long usage_in_bytes,
     unsigned long long quota_in_bytes) {
-  if (usage_callback_)
-    usage_callback_->handleEvent(usage_in_bytes, quota_in_bytes);
+  if (usage_callback_) {
+    usage_callback_->InvokeAndReportException(nullptr, usage_in_bytes,
+                                              quota_in_bytes);
+  }
 }
 
 void DeprecatedStorageQuotaCallbacksImpl::DidGrantStorageQuota(
     unsigned long long usage_in_bytes,
     unsigned long long granted_quota_in_bytes) {
   if (quota_callback_)
-    quota_callback_->handleEvent(granted_quota_in_bytes);
+    quota_callback_->InvokeAndReportException(nullptr, granted_quota_in_bytes);
 }
 
 void DeprecatedStorageQuotaCallbacksImpl::DidFail(WebStorageQuotaError error) {
-  if (error_callback_)
-    error_callback_->handleEvent(
-        DOMError::Create(static_cast<ExceptionCode>(error)));
+  if (error_callback_) {
+    error_callback_->InvokeAndReportException(
+        nullptr, DOMError::Create(static_cast<ExceptionCode>(error)));
+  }
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
index ef39677..1773fb7 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
@@ -32,10 +32,10 @@
 #define DeprecatedStorageQuotaCallbacksImpl_h
 
 #include "base/memory/scoped_refptr.h"
+#include "bindings/modules/v8/v8_storage_error_callback.h"
+#include "bindings/modules/v8/v8_storage_quota_callback.h"
+#include "bindings/modules/v8/v8_storage_usage_callback.h"
 #include "modules/ModulesExport.h"
-#include "modules/quota/StorageErrorCallback.h"
-#include "modules/quota/StorageQuotaCallback.h"
-#include "modules/quota/StorageUsageCallback.h"
 #include "platform/StorageQuotaCallbacks.h"
 
 namespace blink {
@@ -44,14 +44,14 @@
     : public StorageQuotaCallbacks {
  public:
   static DeprecatedStorageQuotaCallbacksImpl* Create(
-      StorageUsageCallback* success,
-      StorageErrorCallback* error) {
+      V8StorageUsageCallback* success,
+      V8StorageErrorCallback* error) {
     return new DeprecatedStorageQuotaCallbacksImpl(success, error);
   }
 
   static DeprecatedStorageQuotaCallbacksImpl* Create(
-      StorageQuotaCallback* success,
-      StorageErrorCallback* error) {
+      V8StorageQuotaCallback* success,
+      V8StorageErrorCallback* error) {
     return new DeprecatedStorageQuotaCallbacksImpl(success, error);
   }
 
@@ -65,14 +65,20 @@
   void DidFail(WebStorageQuotaError) override;
 
  private:
-  DeprecatedStorageQuotaCallbacksImpl(StorageUsageCallback*,
-                                      StorageErrorCallback*);
-  DeprecatedStorageQuotaCallbacksImpl(StorageQuotaCallback*,
-                                      StorageErrorCallback*);
+  DeprecatedStorageQuotaCallbacksImpl(V8StorageUsageCallback*,
+                                      V8StorageErrorCallback*);
+  DeprecatedStorageQuotaCallbacksImpl(V8StorageQuotaCallback*,
+                                      V8StorageErrorCallback*);
 
-  Member<StorageUsageCallback> usage_callback_;
-  Member<StorageQuotaCallback> quota_callback_;
-  Member<StorageErrorCallback> error_callback_;
+  // This set of callbacks is held by WebStorageQuotaCallbacks and passed in
+  // Platform::QueryStorageUsageAndQuota, which doesn't support wrapper-tracing,
+  // and there is no other owner of this object. Thus, this object holds the
+  // underlying callback functions as persistent handles. This is acceptable
+  // because this object will be discarded in a limited time once
+  // Platform::QueryStorageUsageAndQuota finishes a task.
+  V8StorageUsageCallback::Persistent<V8StorageUsageCallback> usage_callback_;
+  V8StorageQuotaCallback::Persistent<V8StorageQuotaCallback> quota_callback_;
+  V8StorageErrorCallback::Persistent<V8StorageErrorCallback> error_callback_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.cpp b/third_party/WebKit/Source/modules/quota/StorageErrorCallback.cpp
deleted file mode 100644
index e14ea99e..0000000
--- a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2013 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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/quota/StorageErrorCallback.h"
-
-#include "modules/quota/DOMError.h"
-
-namespace blink {
-
-base::OnceClosure StorageErrorCallback::CreateSameThreadTask(
-    StorageErrorCallback* callback,
-    ExceptionCode ec) {
-  return WTF::Bind(&StorageErrorCallback::Run, WrapPersistent(callback), ec);
-}
-
-void StorageErrorCallback::Run(StorageErrorCallback* callback,
-                               ExceptionCode ec) {
-  if (!callback)
-    return;
-  callback->handleEvent(DOMError::Create(ec));
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.h b/third_party/WebKit/Source/modules/quota/StorageErrorCallback.h
deleted file mode 100644
index ee778cb0..0000000
--- a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2013 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 StorageErrorCallback_h
-#define StorageErrorCallback_h
-
-#include "core/dom/ExceptionCode.h"
-#include "modules/ModulesExport.h"
-#include "platform/heap/Handle.h"
-#include "platform/wtf/Forward.h"
-
-namespace blink {
-
-class DOMError;
-
-class StorageErrorCallback
-    : public GarbageCollectedFinalized<StorageErrorCallback> {
- public:
-  virtual ~StorageErrorCallback() {}
-  virtual void Trace(blink::Visitor* visitor) {}
-  virtual void handleEvent(DOMError*) = 0;
-
-  MODULES_EXPORT static base::OnceClosure CreateSameThreadTask(
-      StorageErrorCallback*,
-      ExceptionCode);
-
- private:
-  static void Run(StorageErrorCallback*, ExceptionCode);
-};
-
-}  // namespace blink
-
-#endif  // StorageErrorCallback_h
diff --git a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.idl b/third_party/WebKit/Source/modules/quota/StorageErrorCallback.idl
deleted file mode 100644
index 011df62f..0000000
--- a/third_party/WebKit/Source/modules/quota/StorageErrorCallback.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-callback interface StorageErrorCallback {
-    void handleEvent(DOMError error);
-};
diff --git a/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.h b/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.h
deleted file mode 100644
index e37ccbb8..0000000
--- a/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 StorageQuotaCallback_h
-#define StorageQuotaCallback_h
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class StorageQuotaCallback
-    : public GarbageCollectedFinalized<StorageQuotaCallback> {
- public:
-  virtual ~StorageQuotaCallback() {}
-  virtual void Trace(blink::Visitor* visitor) {}
-  virtual void handleEvent(uint64_t granted_quota_in_bytes) = 0;
-};
-
-}  // namespace
-
-#endif  // StorageQuotaCallback_h
diff --git a/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.idl b/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.idl
deleted file mode 100644
index 75bed94..0000000
--- a/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-callback interface StorageQuotaCallback {
-    void handleEvent(unsigned long long grantedQuotaInBytes);
-};
diff --git a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp
index 1b281b4..04d9ec04 100644
--- a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp
+++ b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp
@@ -36,8 +36,6 @@
 #include "core/page/Page.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "modules/quota/DeprecatedStorageQuotaCallbacksImpl.h"
-#include "modules/quota/StorageErrorCallback.h"
-#include "modules/quota/StorageQuotaCallback.h"
 #include "public/platform/TaskType.h"
 #include "public/platform/WebStorageQuotaType.h"
 #include "public/web/WebFrameClient.h"
@@ -51,8 +49,8 @@
 void StorageQuotaClient::RequestQuota(ScriptState* script_state,
                                       WebStorageQuotaType storage_type,
                                       unsigned long long new_quota_in_bytes,
-                                      StorageQuotaCallback* success_callback,
-                                      StorageErrorCallback* error_callback) {
+                                      V8StorageQuotaCallback* success_callback,
+                                      V8StorageErrorCallback* error_callback) {
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
   DCHECK(execution_context);
   DCHECK(execution_context->IsDocument())
diff --git a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h
index e522657a..97148176 100644
--- a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h
+++ b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h
@@ -43,8 +43,8 @@
 
 class ExecutionContext;
 class Page;
-class StorageErrorCallback;
-class StorageQuotaCallback;
+class V8StorageErrorCallback;
+class V8StorageQuotaCallback;
 
 class MODULES_EXPORT StorageQuotaClient
     : public GarbageCollectedFinalized<StorageQuotaClient>,
@@ -60,8 +60,8 @@
   void RequestQuota(ScriptState*,
                     WebStorageQuotaType,
                     unsigned long long new_quota_in_bytes,
-                    StorageQuotaCallback*,
-                    StorageErrorCallback*);
+                    V8StorageQuotaCallback*,
+                    V8StorageErrorCallback*);
 
   static const char* SupplementName();
   static StorageQuotaClient* From(ExecutionContext*);
diff --git a/third_party/WebKit/Source/modules/quota/StorageUsageCallback.h b/third_party/WebKit/Source/modules/quota/StorageUsageCallback.h
deleted file mode 100644
index a559d70..0000000
--- a/third_party/WebKit/Source/modules/quota/StorageUsageCallback.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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 StorageUsageCallback_h
-#define StorageUsageCallback_h
-
-#include "platform/heap/Handle.h"
-
-namespace blink {
-
-class StorageUsageCallback
-    : public GarbageCollectedFinalized<StorageUsageCallback> {
- public:
-  virtual ~StorageUsageCallback() {}
-  virtual void Trace(blink::Visitor* visitor) {}
-  virtual void handleEvent(uint64_t current_usage_in_bytes,
-                           uint64_t current_quota_in_bytes) = 0;
-};
-
-}  // namespace
-
-#endif  // StorageUsageCallback_h
diff --git a/third_party/WebKit/Source/modules/quota/StorageUsageCallback.idl b/third_party/WebKit/Source/modules/quota/StorageUsageCallback.idl
deleted file mode 100644
index 94774f8..0000000
--- a/third_party/WebKit/Source/modules/quota/StorageUsageCallback.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER 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.
- */
-
-callback interface StorageUsageCallback {
-    void handleEvent(unsigned long long currentUsageInBytes, unsigned long long currentQuotaInBytes);
-};
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp
index 5dd55de..7b8020c 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp
@@ -77,10 +77,8 @@
   DCHECK_EQ(GetNumberOfGlobalScopes(), 0u);
 
   AudioWorkletMessagingProxy* proxy =
-      new AudioWorkletMessagingProxy(GetExecutionContext(),
-                                     WorkerClients::Create(),
-                                     this);
-  proxy->Initialize();
+      new AudioWorkletMessagingProxy(GetExecutionContext(), this);
+  proxy->Initialize(WorkerClients::Create());
   return proxy;
 }
 
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp
index e844b88..47230c6f 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp
@@ -18,10 +18,8 @@
 
 AudioWorkletMessagingProxy::AudioWorkletMessagingProxy(
     ExecutionContext* execution_context,
-    WorkerClients* worker_clients,
     AudioWorklet* worklet)
-    : ThreadedWorkletMessagingProxy(execution_context, worker_clients),
-      worklet_(worklet) {}
+    : ThreadedWorkletMessagingProxy(execution_context), worklet_(worklet) {}
 
 void AudioWorkletMessagingProxy::CreateProcessor(
     AudioWorkletHandler* handler,
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h
index f7eb17a..7157648 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h
+++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h
@@ -24,7 +24,7 @@
 // scope via AudioWorkletObjectProxy.
 class AudioWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy {
  public:
-  AudioWorkletMessagingProxy(ExecutionContext*, WorkerClients*, AudioWorklet*);
+  AudioWorkletMessagingProxy(ExecutionContext*, AudioWorklet*);
 
   // Since the creation of AudioWorkletProcessor needs to be done in the
   // different thread, this method is a wrapper for cross-thread task posting.
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
index 9f458a5..c17a437 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
@@ -111,11 +111,11 @@
                                        unsigned start,
                                        bool backwards,
                                        bool* is_hyphenated) const {
+  DCHECK(is_hyphenated && !*is_hyphenated);
   const String& text = GetText();
   unsigned word_end = break_iterator_->NextBreakOpportunity(offset);
   if (word_end == offset) {
     DCHECK_EQ(offset, break_iterator_->PreviousBreakOpportunity(offset, start));
-    *is_hyphenated = false;
     return word_end;
   }
   unsigned previous_break_opportunity =
@@ -134,7 +134,6 @@
       return word_start + prefix_length;
     }
   }
-  *is_hyphenated = false;
   return backwards ? previous_break_opportunity : word_end;
 }
 
@@ -142,6 +141,7 @@
     unsigned offset,
     unsigned start,
     bool* is_hyphenated) const {
+  DCHECK(is_hyphenated && !*is_hyphenated);
   if (UNLIKELY(!IsSoftHyphenEnabled())) {
     const String& text = GetText();
     for (;; offset--) {
@@ -161,6 +161,7 @@
 unsigned ShapingLineBreaker::NextBreakOpportunity(unsigned offset,
                                                   unsigned start,
                                                   bool* is_hyphenated) const {
+  DCHECK(is_hyphenated && !*is_hyphenated);
   if (UNLIKELY(!IsSoftHyphenEnabled())) {
     const String& text = GetText();
     for (;; offset++) {
@@ -324,7 +325,7 @@
           break;
         // Doesn't fit after the reshape. Try previous break opportunity, or
         // overflow if there were none.
-        bool is_previous_break_opportunity_hyphenated;
+        bool is_previous_break_opportunity_hyphenated = false;
         unsigned previous_break_opportunity =
             PreviousBreakOpportunity(break_opportunity - 1, start,
                                      &is_previous_break_opportunity_hyphenated);
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
index 1363bbc..23af003 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
@@ -81,6 +81,9 @@
   const PaintCanvas* Canvas() const { return canvas_; }
 
   PaintController& GetPaintController() { return paint_controller_; }
+  const PaintController& GetPaintController() const {
+    return paint_controller_;
+  }
 
   bool ContextDisabled() const { return disabled_state_; }
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 7e7a05e3..166278c 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -201,8 +201,8 @@
   // Force new paint chunk which is required for subsequence caching.
   new_paint_chunks_.ForceNewChunk();
 
-  DCHECK(new_cached_subsequences_.find(&client) ==
-         new_cached_subsequences_.end());
+  DCHECK(!new_cached_subsequences_.Contains(&client))
+      << "Multiple subsequences for client: " << client.DebugName();
 
   new_cached_subsequences_.insert(&client, SubsequenceMarkers(start, end));
   last_cached_subsequence_end_ = end;
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
index 540c43a..cb91102 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -1428,7 +1428,7 @@
                                         uint32_t inflight_keepalive_bytes) {
   DCHECK(resource);
 
-  DCHECK_LE(inflight_keepalive_bytes_, inflight_keepalive_bytes);
+  DCHECK_LE(inflight_keepalive_bytes, inflight_keepalive_bytes_);
   inflight_keepalive_bytes_ -= inflight_keepalive_bytes;
 
   RemoveResourceLoader(resource->Loader());
diff --git a/third_party/WebKit/public/platform/oom_intervention.mojom b/third_party/WebKit/public/platform/oom_intervention.mojom
index 50fc28e..e54c7dde 100644
--- a/third_party/WebKit/public/platform/oom_intervention.mojom
+++ b/third_party/WebKit/public/platform/oom_intervention.mojom
@@ -4,8 +4,27 @@
 
 module blink.mojom;
 
-// Renderer interface for OOM intervention. An instance of this interface
-// will be created when NearOomMonitor detects near-OOM situation to activate
-// intervention (e.g. pausing the renderer). The instance will be destroyed
-// when the intervention is declined.
-interface OomIntervention {};
+// There are two phases to estimate a near-OOM situation. First phase takes
+// place in the browser process. When the browser detects a high memory
+// pressure it starts the second phase in the foreground renderer process,
+// as the renderer has the best knowledge about memory usage of pages.
+// The renderer schedules tasks to check memory workload from pages. If the
+// workload exceeds a threshold the renderer notifies that a high memory usage
+// is detected.
+
+// Browser side interface for OOM intervention. This interface is used to check
+// high memory usage in a renderer.
+interface OomInterventionHost {
+  // Called when a renderer detects high memory usage. |intervention_triggered|
+  // is set to true when the OOM intervention is activated in the renderer.
+  OnHighMemoryUsage(bool intervention_triggered);
+};
+
+// Renderer side interface for OOM intervention. An instance of this interface
+// will be created when the browser gets a high memory pressure signal.
+// It monitors memory usage in renderer side to detect near-OOM situation.
+interface OomIntervention {
+  // Starts monitoring memory usage in renderer side.
+  StartDetection(OomInterventionHost host,
+                 bool trigger_intervention);
+};
diff --git a/third_party/WebKit/public/web/WebSurroundingText.h b/third_party/WebKit/public/web/WebSurroundingText.h
index 97d36ad..450b3cbb 100644
--- a/third_party/WebKit/public/web/WebSurroundingText.h
+++ b/third_party/WebKit/public/web/WebSurroundingText.h
@@ -25,52 +25,49 @@
 #ifndef WebSurroundingText_h
 #define WebSurroundingText_h
 
+#if INSIDE_BLINK
+#include "core/editing/Forward.h"
+#endif
 #include "public/platform/WebString.h"
-#include "WebNode.h"
-#include "WebRange.h"
-#include <memory>
 
 namespace blink {
 
-class SurroundingText;
-class WebNode;
-class WebRange;
 class WebLocalFrame;
-struct WebPoint;
 
 // WebSurroundingText is a Blink API that gives access to the SurroundingText
 // API. It allows caller to know the text surrounding a point or a range.
 class WebSurroundingText {
  public:
   BLINK_EXPORT WebSurroundingText();
-  BLINK_EXPORT ~WebSurroundingText();
 
+  // TODO(xiaochengh): Rename to IsEmpty() to be more intuitive.
   BLINK_EXPORT bool IsNull() const;
 
   // Initializes the object with the current selection in a given frame.
   // The maximum length of the contents retrieved is defined by maxLength.
   // It does not include the text inside the range.
+  // TODO(xiaochengh): Merge this funciton into the constructor.
   BLINK_EXPORT void InitializeFromCurrentSelection(WebLocalFrame*,
                                                    size_t max_length);
 
+#if INSIDE_BLINK
+  BLINK_EXPORT void InitializeFromRange(const EphemeralRange&,
+                                        size_t max_length);
+#endif
+
   // Surrounding text content retrieved.
   BLINK_EXPORT WebString TextContent() const;
 
-  // Offset in the text content of the initial hit position (or provided
-  // offset in the node).
-  // This should only be called when WebSurroundingText has been initialized
-  // with a WebPoint.
-  // DEPRECATED: use startOffsetInTextContent() or endOffsetInTextContent().
-  BLINK_EXPORT size_t HitOffsetInTextContent() const;
-
   // Start offset of the initial text in the text content.
   BLINK_EXPORT size_t StartOffsetInTextContent() const;
 
   // End offset of the initial text in the text content.
   BLINK_EXPORT size_t EndOffsetInTextContent() const;
 
- protected:
-  std::unique_ptr<SurroundingText> private_;
+ private:
+  WebString text_content_;
+  size_t start_offset_in_text_content_;
+  size_t end_offset_in_text_content_;
 };
 
 }  // namespace blink
diff --git a/third_party/minizip/BUILD.gn b/third_party/minizip/BUILD.gn
index c9dbc22..fdbd1a8098 100644
--- a/third_party/minizip/BUILD.gn
+++ b/third_party/minizip/BUILD.gn
@@ -57,7 +57,10 @@
     "src/zip.h",
   ]
 
-  defines = [ "HAVE_AES" ]
+  defines = [
+    "HAVE_AES",
+    "NOCRYPT",
+  ]
 
   if (is_nacl) {
     defines += [ "USE_FILE32API" ]
diff --git a/third_party/minizip/README.chromium b/third_party/minizip/README.chromium
index 57309c86..d321525 100644
--- a/third_party/minizip/README.chromium
+++ b/third_party/minizip/README.chromium
@@ -2,7 +2,7 @@
 Short name: minizip
 URL: https://github.com/nmoinvaz/minizip
 Version: 0
-Revision: e07e141475220196b55294c8172b274cc32d642d
+Revision: 53a657318af1fccc4bac7ed230729302b2391d1d
 Security critical: yes
 License: Custom license
 License File: src/LICENSE
diff --git a/ui/app_list/views/suggestions_container_view.cc b/ui/app_list/views/suggestions_container_view.cc
index 6a991a2..ac12afc 100644
--- a/ui/app_list/views/suggestions_container_view.cc
+++ b/ui/app_list/views/suggestions_container_view.cc
@@ -103,7 +103,6 @@
   DCHECK(search_result_tile_views_.empty());
   views::GridLayout* tiles_layout_manager =
       SetLayoutManager(std::make_unique<views::GridLayout>(this));
-  SetLayoutManager(tiles_layout_manager);
 
   views::ColumnSet* column_set = tiles_layout_manager->AddColumnSet(0);
   for (int col = 0; col < kNumStartPageTiles; ++col) {
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 277cf83..8f0b77b 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -262,10 +262,6 @@
     "template_expressions.h",
     "theme_provider.cc",
     "theme_provider.h",
-    "touch/touch_device.h",
-    "touch/touch_device_util.cc",
-    "touch/touch_editing_controller.cc",
-    "touch/touch_editing_controller.h",
     "ui_base_export.h",
     "ui_base_exports.cc",
     "ui_base_features.cc",
@@ -364,6 +360,10 @@
       "idle/idle_win.cc",
       "text/bytes_formatting.cc",
       "text/bytes_formatting.h",
+      "touch/touch_device.h",
+      "touch/touch_device_util.cc",
+      "touch/touch_editing_controller.cc",
+      "touch/touch_editing_controller.h",
     ]
   }
 
diff --git a/ui/file_manager/file_manager/background/js/launcher_search.js b/ui/file_manager/file_manager/background/js/launcher_search.js
index 2f752de..ed635ec6f 100644
--- a/ui/file_manager/file_manager/background/js/launcher_search.js
+++ b/ui/file_manager/file_manager/background/js/launcher_search.js
@@ -117,53 +117,22 @@
   // initialized. In this method, chrome.fileManagerPrivate.searchDriveMetadata
   // resolves url internally, and it fails if filesystem of the url is not
   // initialized.
-  volumeManagerFactory.getInstance().then(function() {
-    chrome.fileManagerPrivate.searchDriveMetadata(
-        {
-          query: query,
-          types: 'ALL',
-          maxResults: limit
-        }, function(results) {
-          // If query is already changed, discard the results.
-          if (queryId !== this.queryId_ || results.length === 0)
-            return;
+  volumeManagerFactory.getInstance()
+      .then(() => {
+        return Promise.all([
+          this.queryDriveEntries_(queryId, query, limit),
+          this.queryLocalEntries_(queryId, query)
+        ]);
+      })
+      .then((results) => {
+        const entries = results[0].concat(results[1]);
+        if (queryId !== this.queryId_ || entries.length === 0)
+          return;
 
-          chrome.launcherSearchProvider.setSearchResults(
-              queryId,
-              results.map(function(result) {
-                // TODO(yawano): Use filetype_folder_shared.png for a shared
-                //     folder.
-                // TODO(yawano): Add archive launcher filetype icon.
-                var icon = FileType.getIcon(result.entry);
-                if (icon === 'UNKNOWN' || icon === 'archive')
-                  icon = 'generic';
-
-                var useHighDpiIcon = window.devicePixelRatio > 1.0;
-                var iconUrl = chrome.runtime.getURL(
-                    'foreground/images/launcher_filetypes/' +
-                    (useHighDpiIcon ? '2x/' : '') + 'launcher_filetype_' +
-                    icon + '.png');
-
-                // Hide extensions for hosted files.
-                var title = FileType.isHosted(result.entry) ?
-                    result.entry.name.substr(
-                        0,
-                        result.entry.name.length -
-                            FileType.getExtension(result.entry).length) :
-                    result.entry.name;
-
-                return {
-                  itemId: result.entry.toURL(),
-                  title: title,
-                  iconUrl: iconUrl,
-                  // Relevance is set as 2 for all results as a temporary
-                  // implementation. 2 is the middle value.
-                  // TODO(yawano): Implement practical relevance calculation.
-                  relevance: 2
-                };
-              }));
-        }.bind(this));
-  }.bind(this));
+        const resultEntries = this.chooseEntries_(entries, query, limit);
+        const searchResults = resultEntries.map(this.createSearchResult_);
+        chrome.launcherSearchProvider.setSearchResults(queryId, searchResults);
+      });
 };
 
 /**
@@ -250,3 +219,144 @@
       undefined, /* App ID */
       LaunchType.FOCUS_SAME_OR_CREATE);
 };
+
+/**
+ * Queries entries which match the given query in Google Drive.
+ * @param {number} queryId
+ * @param {string} query
+ * @param {number} limit
+ * @return {!Promise<!Array<!Entry>>}
+ * @private
+ */
+LauncherSearch.prototype.queryDriveEntries_ = function(queryId, query, limit) {
+  var param = {query: query, types: 'ALL', maxResults: limit};
+  return new Promise((resolve, reject) => {
+    chrome.fileManagerPrivate.searchDriveMetadata(param, function(results) {
+      resolve(results.map(result => result.entry));
+    });
+  });
+};
+
+/**
+ * Queries entries which match the given query in Downloads.
+ * @param {number} queryId
+ * @param {string} query
+ * @return {!Promise<!Array<!Entry>>}
+ * @private
+ */
+LauncherSearch.prototype.queryLocalEntries_ = function(queryId, query) {
+  if (!query)
+    return Promise.resolve([]);
+
+  return this.getDownloadsEntry_()
+      .then((downloadsEntry) => {
+        return this.queryEntriesRecursively_(
+            downloadsEntry, queryId, query.toLowerCase());
+      })
+      .catch((error) => {
+        if (error.name != 'AbortError')
+          console.error('Query local entries failed.', error);
+        return [];
+      });
+};
+
+/**
+ * Returns root entry of Downloads volume.
+ * @return {!Promise<!DirectoryEntry>}
+ * @private
+ */
+LauncherSearch.prototype.getDownloadsEntry_ = function() {
+  return volumeManagerFactory.getInstance().then((volumeManager) => {
+    var downloadsVolumeInfo = volumeManager.getCurrentProfileVolumeInfo(
+        VolumeManagerCommon.VolumeType.DOWNLOADS);
+    return downloadsVolumeInfo.resolveDisplayRoot();
+  });
+};
+
+/**
+ * Queries entries which match the given query inside rootEntry recursively.
+ * @param {!DirectoryEntry} rootEntry
+ * @param {number} queryId
+ * @param {string} query
+ * @return {!Promise<!Array<!Entry>>}
+ * @private
+ */
+LauncherSearch.prototype.queryEntriesRecursively_ = function(
+    rootEntry, queryId, query) {
+  return new Promise((resolve, reject) => {
+    let foundEntries = [];
+    util.readEntriesRecursively(
+        rootEntry,
+        (entries) => {
+          const matchEntries = entries.filter(
+              entry => entry.name.toLowerCase().indexOf(query) >= 0);
+          if (matchEntries.length > 0)
+            foundEntries = foundEntries.concat(matchEntries);
+        },
+        () => {
+          resolve(foundEntries);
+        },
+        reject,
+        () => {
+          return this.queryId_ != queryId;
+        });
+  });
+};
+
+/**
+ * Chooses entries to show among the given entries.
+ * @param {!Array<!Entry>} entries
+ * @param {string} query
+ * @param {number} limit
+ * @return {!Array<!Entry>}
+ * @private
+ */
+LauncherSearch.prototype.chooseEntries_ = function(entries, query, limit) {
+  query = query.toLowerCase();
+  const scoreEntry = (entry) => {
+    // Prefer entry which has the query string as a prefix.
+    if (entry.name.toLowerCase().indexOf(query) === 0)
+      return 1;
+    return 0;
+  };
+  const sortedEntries = entries.sort((a, b) => {
+    return scoreEntry(b) - scoreEntry(a);
+  });
+  return sortedEntries.slice(0, limit);
+};
+
+/**
+ * Creates a search result from entry to pass to launcherSearchProvider API.
+ * @param {!Entry} entry
+ * @return {!Object}
+ * @private
+ */
+LauncherSearch.prototype.createSearchResult_ = function(entry) {
+  // TODO(yawano): Use filetype_folder_shared.png for a shared
+  //     folder.
+  // TODO(yawano): Add archive launcher filetype icon.
+  var icon = FileType.getIcon(entry);
+  if (icon === 'UNKNOWN' || icon === 'archive')
+    icon = 'generic';
+
+  var useHighDpiIcon = window.devicePixelRatio > 1.0;
+  var iconUrl = chrome.runtime.getURL(
+      'foreground/images/launcher_filetypes/' + (useHighDpiIcon ? '2x/' : '') +
+      'launcher_filetype_' + icon + '.png');
+
+  // Hide extensions for hosted files.
+  var title = FileType.isHosted(entry) ?
+      entry.name.substr(
+          0, entry.name.length - FileType.getExtension(entry).length) :
+      entry.name;
+
+  return {
+    itemId: entry.toURL(),
+    title: title,
+    iconUrl: iconUrl,
+    // Relevance is set as 2 for all results as a temporary
+    // implementation. 2 is the middle value.
+    // TODO(yawano): Implement practical relevance calculation.
+    relevance: 2
+  };
+};
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js
index bdd51c00..473a682 100644
--- a/ui/file_manager/file_manager/common/js/util.js
+++ b/ui/file_manager/file_manager/common/js/util.js
@@ -1288,3 +1288,59 @@
         });
   });
 };
+
+/**
+ * Retrieves all entries inside the given |rootEntry|.
+ * @param {!DirectoryEntry} rootEntry
+ * @param {function(!Array<!Entry>)} entriesCallback Called when some chunk of
+ *     entries are read. This can be called a couple of times until the
+ *     completion.
+ * @param {function()} successCallback Called when the read is completed.
+ * @param {function(DOMError)} errorCallback Called when an error occurs.
+ * @param {function():boolean} shouldStop Callback to check if the read process
+ *     should stop or not. When this callback is called and it returns false,
+ *     the remaining recursive reads will be aborted.
+ */
+util.readEntriesRecursively = function(
+    rootEntry, entriesCallback, successCallback, errorCallback, shouldStop) {
+  var numRunningTasks = 0;
+  var error = null;
+  var maybeRunCallback = function() {
+    if (numRunningTasks === 0) {
+      if (shouldStop())
+        errorCallback(util.createDOMError(util.FileError.ABORT_ERR));
+      else if (error)
+        errorCallback(error);
+      else
+        successCallback();
+    }
+  };
+  var processEntry = function(entry) {
+    var onError = function(fileError) {
+      if (!error)
+        error = fileError;
+      numRunningTasks--;
+      maybeRunCallback();
+    };
+    var onSuccess = function(entries) {
+      if (shouldStop() || error || entries.length === 0) {
+        numRunningTasks--;
+        maybeRunCallback();
+        return;
+      }
+      entriesCallback(entries);
+      for (var i = 0; i < entries.length; i++) {
+        if (entries[i].isDirectory)
+          processEntry(entries[i]);
+      }
+      // Read remaining entries.
+      reader.readEntries(onSuccess, onError);
+    };
+
+    numRunningTasks++;
+    var reader = entry.createReader();
+    reader.readEntries(onSuccess, onError);
+  };
+
+  processEntry(rootEntry);
+};
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js
index 33165631..dccba56 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_contents.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -202,57 +202,12 @@
  */
 LocalSearchContentScanner.prototype.scan = function(
     entriesCallback, successCallback, errorCallback) {
-  var numRunningTasks = 0;
-  var error = null;
-  var maybeRunCallback = function() {
-    if (numRunningTasks === 0) {
-      if (this.cancelled_)
-        errorCallback(util.createDOMError(util.FileError.ABORT_ERR));
-      else if (error)
-        errorCallback(error);
-      else
-        successCallback();
-    }
-  }.bind(this);
-
-  var processEntry = function(entry) {
-    numRunningTasks++;
-    var onError = function(fileError) {
-      if (!error)
-        error = fileError;
-      numRunningTasks--;
-      maybeRunCallback();
-    };
-
-    var onSuccess = function(entries) {
-      if (this.cancelled_ || error || entries.length === 0) {
-        numRunningTasks--;
-        maybeRunCallback();
-        return;
-      }
-
-      // Filters by the query, and if found, run entriesCallback.
-      var foundEntries = entries.filter(function(entry) {
-        return entry.name.toLowerCase().indexOf(this.query_) >= 0;
-      }.bind(this));
-      if (foundEntries.length > 0)
-        entriesCallback(foundEntries);
-
-      // Start to process sub directories.
-      for (var i = 0; i < entries.length; i++) {
-        if (entries[i].isDirectory)
-          processEntry(entries[i]);
-      }
-
-      // Read remaining entries.
-      reader.readEntries(onSuccess, onError);
-    }.bind(this);
-
-    var reader = entry.createReader();
-    reader.readEntries(onSuccess, onError);
-  }.bind(this);
-
-  processEntry(this.entry_);
+  util.readEntriesRecursively(assert(this.entry_), (entries) => {
+    const matchEntries = entries.filter(
+        entry => entry.name.toLowerCase().indexOf(this.query_) >= 0);
+    if (matchEntries.length > 0)
+      entriesCallback(matchEntries);
+  }, successCallback, errorCallback, () => this.cancelled_);
 };
 
 /**
@@ -574,7 +529,7 @@
     snapshot[entries[i].toURL()] = metadata[i];
   }
   return snapshot;
-}
+};
 
 /**
  * Sets metadata snapshot which is used to check changed files.
@@ -582,7 +537,7 @@
  */
 DirectoryContents.prototype.setMetadataSnapshot = function(metadataSnapshot) {
   this.metadataSnapshot_ = metadataSnapshot;
-}
+};
 
 /**
  * Use the filelist from the context and replace its contents with the entries
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc
index b147709b..1fa4490e 100644
--- a/ui/message_center/views/notification_view_md.cc
+++ b/ui/message_center/views/notification_view_md.cc
@@ -1008,7 +1008,7 @@
 
   // |settings_row_| contains inline settings.
   settings_row_ = new views::View();
-  settings_row_->SetLayoutManager(new views::BoxLayout(
+  settings_row_->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::kVertical, kSettingsRowPadding, 0));
   settings_row_->SetBackground(
       views::CreateSolidBackground(kActionsRowBackgroundColor));
@@ -1032,11 +1032,11 @@
       this, false, l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_DONE),
       base::EmptyString16());
   auto* settings_button_row = new views::View;
-  auto* settings_button_layout = new views::BoxLayout(
+  auto settings_button_layout = std::make_unique<views::BoxLayout>(
       views::BoxLayout::kHorizontal, kSettingsButtonRowPadding, 0);
   settings_button_layout->set_main_axis_alignment(
       views::BoxLayout::MAIN_AXIS_ALIGNMENT_END);
-  settings_button_row->SetLayoutManager(settings_button_layout);
+  settings_button_row->SetLayoutManager(std::move(settings_button_layout));
   settings_button_row->AddChildView(settings_done_button_);
   settings_row_->AddChildView(settings_button_row);
 
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 7ad8a12..34ab4b4d 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -635,14 +635,6 @@
   SetLayoutManagerImpl(nullptr);
 }
 
-void View::SetLayoutManager(LayoutManager* layout) {
-  // Some callers of this deprecated function may set the same layout manager
-  // twice, which used to be a no-op. Retain this behavior to avoid crashing.
-  if (layout == layout_manager_.get())
-    return;
-  SetLayoutManager(std::unique_ptr<LayoutManager>(layout));
-}
-
 // Attributes ------------------------------------------------------------------
 
 const char* View::GetClassName() const {
diff --git a/ui/views/view.h b/ui/views/view.h
index 4a4f120..6f7cd83 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -531,8 +531,6 @@
     return lm;
   }
   void SetLayoutManager(nullptr_t);
-  // DEPRECATED version that takes ownership of a raw pointer.
-  void SetLayoutManager(LayoutManager* layout);
 
   // Attributes ----------------------------------------------------------------
 
diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc
index 56c2369..5d0dddf 100644
--- a/ui/views/widget/root_view.cc
+++ b/ui/views/widget/root_view.cc
@@ -188,7 +188,7 @@
       "Can't be called until after the native widget is created!";
   // The ContentsView must be set up _after_ the window is created so that its
   // Widget pointer is valid.
-  SetLayoutManager(new FillLayout);
+  SetLayoutManager(std::make_unique<FillLayout>());
   if (has_children())
     RemoveAllChildViews(true);
   AddChildView(contents_view);