diff --git a/.gitattributes b/.gitattributes
index dfb4ad1..9cc142c 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,3 +3,43 @@
 
 # Force LF checkout of the pins files to avoid transport_security_state_generator errors.
 /net/http/*.pins  text eol=lf
+
+# Force LF checkout for all source files
+*.c text eol=lf
+*.cc text eol=lf
+*.cpp text eol=lf
+*.grd   text eol=lf
+*.grdp   text eol=lf
+*.gn text eol=lf
+*.gni text eol=lf
+*.h text eol=lf
+*.html   text eol=lf
+*.in   text eol=lf
+*.inc   text eol=lf
+*.java   text eol=lf
+*.js   text eol=lf
+*.json   text eol=lf
+*.md text eol=lf
+*.mm text eol=lf
+*.sh text eol=lf
+*.sql   text eol=lf
+*.txt   text eol=lf
+*.xml   text eol=lf
+*.xslt   text eol=lf
+.clang-format   text eol=lf
+.eslintrc.js   text eol=lf
+.git-blame-ignore-revs   text eol=lf
+.gitattributes   text eol=lf
+.gitignore   text eol=lf
+.vpython   text eol=lf
+codereview.settings   text eol=lf
+DEPS   text eol=lf
+ENG_REVIEW_OWNERS   text eol=lf
+LICENSE text eol=lf
+LICENSE.* text eol=lf
+MAJOR_BRANCH_DATE   text eol=lf
+OWNERS   text eol=lf
+README   text eol=lf
+README.*   text eol=lf
+WATCHLISTS   text eol=lf
+VERSION   text eol=lf
diff --git a/DEPS b/DEPS
index ff9efa0..085a136 100644
--- a/DEPS
+++ b/DEPS
@@ -105,11 +105,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': 'dc5c69842e1e77efaf5ebfcb356b2589a00c1eeb',
+  'skia_revision': 'a391c72a20574053a00e05848aa7460d30d7b649',
   # 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': 'f057dc1254d527b26b4c3e59c71f312bb29a926e',
+  'v8_revision': 'f474ca1de96cc8d320e15f0e79fa7630673a3946',
   # 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.
@@ -165,7 +165,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '8a075d7c378a41458358c27c69a9091b1a0d2891',
+  'catapult_revision': '9eaedb7fa00f7b1c3bba87eeb82f75e7a147f8d2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -1035,7 +1035,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a5c263cc63ffc2cc189b5214074c8792067c1853',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'fb994de04de78ae4501cb9a030ea7135ea62bc7e',
+    Var('webrtc_git') + '/src.git' + '@' + 'd497e6bd6b6520d08ff5e2df3a50a46d8c9f9b6e',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/browser/aw_field_trial_creator.cc b/android_webview/browser/aw_field_trial_creator.cc
index 2f8cae9..263e2cf 100644
--- a/android_webview/browser/aw_field_trial_creator.cc
+++ b/android_webview/browser/aw_field_trial_creator.cc
@@ -28,7 +28,6 @@
 #include "components/variations/seed_response.h"
 #include "components/variations/service/safe_seed_manager.h"
 #include "components/variations/service/variations_service.h"
-#include "components/variations/variations_switches.h"
 
 namespace android_webview {
 namespace {
@@ -64,14 +63,6 @@
 AwFieldTrialCreator::~AwFieldTrialCreator() {}
 
 void AwFieldTrialCreator::SetUpFieldTrials() {
-  // Workaround for https://crbug.com/853832: In testing, Chrome's experiments
-  // are applied to WebView. Some of these break WebView. So disable the testing
-  // config. TODO(paulmiller): Remove after 853832 is fixed.
-  auto* cmd = base::CommandLine::ForCurrentProcess();
-  if (!cmd->HasSwitch(variations::switches::kDisableFieldTrialTestingConfig)) {
-    cmd->AppendSwitch(variations::switches::kDisableFieldTrialTestingConfig);
-  }
-
   DoSetUpFieldTrials();
 
   // If DoSetUpFieldTrials failed, it might have skipped creating
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index a86077c..1284970 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -2279,7 +2279,7 @@
         if (TRACE) Log.i(TAG, "%s flingScroll", this);
         if (isDestroyedOrNoOperation(WARN)) return;
         mWebContents.getEventForwarder().startFling(
-                SystemClock.uptimeMillis(), -velocityX, -velocityY, false);
+                SystemClock.uptimeMillis(), -velocityX, -velocityY, false, true);
     }
 
     /**
diff --git a/ash/accessibility/touch_exploration_manager.cc b/ash/accessibility/touch_exploration_manager.cc
index da8e4ee..99dc1961 100644
--- a/ash/accessibility/touch_exploration_manager.cc
+++ b/ash/accessibility/touch_exploration_manager.cc
@@ -37,7 +37,8 @@
 TouchExplorationManager::TouchExplorationManager(
     RootWindowController* root_window_controller)
     : root_window_controller_(root_window_controller),
-      audio_handler_(chromeos::CrasAudioHandler::Get()) {
+      audio_handler_(chromeos::CrasAudioHandler::Get()),
+      observing_window_(nullptr) {
   Shell::Get()->AddShellObserver(this);
   Shell::Get()->accessibility_controller()->AddObserver(this);
   Shell::Get()->activation_client()->AddObserver(this);
@@ -54,12 +55,23 @@
   keyboard::KeyboardController::Get()->RemoveObserver(this);
   display::Screen::GetScreen()->RemoveObserver(this);
   Shell::Get()->RemoveShellObserver(this);
+  if (observing_window_)
+    observing_window_->RemoveObserver(this);
 }
 
 void TouchExplorationManager::OnAccessibilityStatusChanged() {
   UpdateTouchExplorationState();
 }
 
+void TouchExplorationManager::OnWindowPropertyChanged(aura::Window* winodw,
+                                                      const void* key,
+                                                      intptr_t old) {
+  if (key != aura::client::kAccessibilityTouchExplorationPassThrough)
+    return;
+
+  UpdateTouchExplorationState();
+}
+
 void TouchExplorationManager::SetOutputLevel(int volume) {
   if (volume > 0) {
     if (audio_handler_->IsOutputMuted()) {
@@ -151,6 +163,16 @@
     ::wm::ActivationChangeObserver::ActivationReason reason,
     aura::Window* gained_active,
     aura::Window* lost_active) {
+  if (lost_active && lost_active->HasObserver(this)) {
+    lost_active->RemoveObserver(this);
+    observing_window_ = nullptr;
+  }
+
+  if (gained_active && !gained_active->HasObserver(this)) {
+    gained_active->AddObserver(this);
+    observing_window_ = gained_active;
+  }
+
   UpdateTouchExplorationState();
 }
 
diff --git a/ash/accessibility/touch_exploration_manager.h b/ash/accessibility/touch_exploration_manager.h
index d8364e4..f2fcf74 100644
--- a/ash/accessibility/touch_exploration_manager.h
+++ b/ash/accessibility/touch_exploration_manager.h
@@ -34,6 +34,7 @@
 // on Windows, which we don't ship anymore.
 class ASH_EXPORT TouchExplorationManager
     : public AccessibilityObserver,
+      public aura::WindowObserver,
       public TouchExplorationControllerDelegate,
       public TouchAccessibilityEnablerDelegate,
       public display::DisplayObserver,
@@ -48,6 +49,11 @@
   // AccessibilityObserver overrides:
   void OnAccessibilityStatusChanged() override;
 
+  // aura::WindowObserver overrides:
+  void OnWindowPropertyChanged(aura::Window* window,
+                               const void* key,
+                               intptr_t old) override;
+
   // TouchExplorationControllerDelegate overrides:
   void SetOutputLevel(int volume) override;
   void SilenceSpokenFeedback() override;
@@ -90,6 +96,7 @@
   std::unique_ptr<TouchAccessibilityEnabler> touch_accessibility_enabler_;
   RootWindowController* root_window_controller_;
   chromeos::CrasAudioHandler* audio_handler_;
+  aura::Window* observing_window_;
 
   DISALLOW_COPY_AND_ASSIGN(TouchExplorationManager);
 };
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc
index eaaa655..1ece7fd 100644
--- a/ash/login/ui/lock_contents_view.cc
+++ b/ash/login/ui/lock_contents_view.cc
@@ -1376,10 +1376,10 @@
       to_update_auth = LoginAuthUserView::AUTH_PASSWORD;
       keyboard::KeyboardController* keyboard_controller =
           GetKeyboardController();
-      const bool IsKeyboardVisible =
+      const bool is_keyboard_visible =
           keyboard_controller ? keyboard_controller->IsKeyboardVisible()
                               : false;
-      if (state->show_pin && !IsKeyboardVisible &&
+      if (state->show_pin && !is_keyboard_visible &&
           state->fingerprint_state ==
               mojom::FingerprintUnlockState::UNAVAILABLE) {
         to_update_auth |= LoginAuthUserView::AUTH_PIN;
diff --git a/ash/login/ui/login_pin_view_unittest.cc b/ash/login/ui/login_pin_view_unittest.cc
index ea0aa56..d617d5c9 100644
--- a/ash/login/ui/login_pin_view_unittest.cc
+++ b/ash/login/ui/login_pin_view_unittest.cc
@@ -122,12 +122,10 @@
   LoginPinView::TestApi test_api(view_);
 
   // Install mock timers into the PIN view.
-  auto delay_timer0 = std::make_unique<base::MockTimer>(
-      true /*retain_user_task*/, false /*is_repeating*/);
-  auto repeat_timer0 = std::make_unique<base::MockTimer>(
-      true /*retain_user_task*/, true /*is_repeating*/);
-  base::MockTimer* delay_timer = delay_timer0.get();
-  base::MockTimer* repeat_timer = repeat_timer0.get();
+  auto delay_timer0 = std::make_unique<base::MockOneShotTimer>();
+  auto repeat_timer0 = std::make_unique<base::MockRepeatingTimer>();
+  base::MockOneShotTimer* delay_timer = delay_timer0.get();
+  base::MockRepeatingTimer* repeat_timer = repeat_timer0.get();
   test_api.SetBackspaceTimers(std::move(delay_timer0),
                               std::move(repeat_timer0));
 
diff --git a/ash/system/audio/unified_volume_view.cc b/ash/system/audio/unified_volume_view.cc
index 650f108..e9f5c09f 100644
--- a/ash/system/audio/unified_volume_view.cc
+++ b/ash/system/audio/unified_volume_view.cc
@@ -55,7 +55,7 @@
   DCHECK(CrasAudioHandler::IsInitialized());
   CrasAudioHandler::Get()->AddAudioObserver(this);
   AddChildView(more_button_);
-  Update();
+  Update(false /* by_user */);
 }
 
 UnifiedVolumeView::~UnifiedVolumeView() {
@@ -63,7 +63,7 @@
   CrasAudioHandler::Get()->RemoveAudioObserver(this);
 }
 
-void UnifiedVolumeView::Update() {
+void UnifiedVolumeView::Update(bool by_user) {
   bool is_muted = CrasAudioHandler::Get()->IsOutputMuted();
   float level = CrasAudioHandler::Get()->GetOutputVolumePercent() / 100.f;
 
@@ -84,32 +84,32 @@
   if (std::abs(level - slider()->value()) < kSliderIgnoreUpdateThreshold)
     return;
 
-  slider()->SetValue(level);
+  SetSliderValue(level, by_user);
 }
 
 void UnifiedVolumeView::OnOutputNodeVolumeChanged(uint64_t node_id,
                                                   int volume) {
-  Update();
+  Update(true /* by_user */);
 }
 
 void UnifiedVolumeView::OnOutputMuteChanged(bool mute_on, bool system_adjust) {
-  Update();
+  Update(true /* by_user */);
 }
 
 void UnifiedVolumeView::OnAudioNodesChanged() {
-  Update();
+  Update(true /* by_user */);
 }
 
 void UnifiedVolumeView::OnActiveOutputNodeChanged() {
-  Update();
+  Update(true /* by_user */);
 }
 
 void UnifiedVolumeView::OnActiveInputNodeChanged() {
-  Update();
+  Update(true /* by_user */);
 }
 
 void UnifiedVolumeView::ChildVisibilityChanged(views::View* child) {
-  Layout();
+  Update(true /* by_user */);
 }
 
 }  // namespace ash
diff --git a/ash/system/audio/unified_volume_view.h b/ash/system/audio/unified_volume_view.h
index 6705c3d..3e8f399 100644
--- a/ash/system/audio/unified_volume_view.h
+++ b/ash/system/audio/unified_volume_view.h
@@ -23,7 +23,7 @@
   views::Button* more_button() { return more_button_; }
 
  private:
-  void Update();
+  void Update(bool by_user);
 
   // CrasAudioHandler::AudioObserver:
   void OnOutputNodeVolumeChanged(uint64_t node_id, int volume) override;
diff --git a/ash/system/brightness/unified_brightness_view.cc b/ash/system/brightness/unified_brightness_view.cc
index 33680baa..fc60c2e3 100644
--- a/ash/system/brightness/unified_brightness_view.cc
+++ b/ash/system/brightness/unified_brightness_view.cc
@@ -29,7 +29,7 @@
 }
 
 void UnifiedBrightnessView::OnDisplayBrightnessChanged(bool by_user) {
-  slider()->SetValue(model_->display_brightness());
+  SetSliderValue(model_->display_brightness(), by_user);
 }
 
 }  // namespace ash
diff --git a/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc b/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc
index b7506b3..2ce8ec8 100644
--- a/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc
+++ b/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc
@@ -31,7 +31,7 @@
 
   // UnifiedSystemTrayModel::Observer:
   void OnKeyboardBrightnessChanged(bool by_user) override {
-    slider()->SetValue(model_->keyboard_brightness());
+    SetSliderValue(model_->keyboard_brightness(), by_user);
   }
 
  private:
diff --git a/ash/system/network/auto_connect_notifier_unittest.cc b/ash/system/network/auto_connect_notifier_unittest.cc
index f766c86..3483561a 100644
--- a/ash/system/network/auto_connect_notifier_unittest.cc
+++ b/ash/system/network/auto_connect_notifier_unittest.cc
@@ -46,8 +46,7 @@
     CHECK(chromeos::NetworkHandler::Get()->auto_connect_handler());
     AshTestBase::SetUp();
 
-    mock_notification_timer_ = new base::MockTimer(true /* retain_user_task */,
-                                                   false /* is_repeating */);
+    mock_notification_timer_ = new base::MockOneShotTimer();
     Shell::Get()
         ->system_notification_controller()
         ->auto_connect_->set_timer_for_testing(
@@ -88,7 +87,7 @@
   }
 
   // Ownership passed to Shell owned AutoConnectNotifier instance.
-  base::MockTimer* mock_notification_timer_;
+  base::MockOneShotTimer* mock_notification_timer_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AutoConnectNotifierTest);
diff --git a/ash/system/unified/feature_pods_container_view.cc b/ash/system/unified/feature_pods_container_view.cc
index d106200..43a3253 100644
--- a/ash/system/unified/feature_pods_container_view.cc
+++ b/ash/system/unified/feature_pods_container_view.cc
@@ -14,30 +14,6 @@
 
 FeaturePodsContainerView::~FeaturePodsContainerView() = default;
 
-gfx::Size FeaturePodsContainerView::CalculatePreferredSize() const {
-  const int collapsed_height = 2 * kUnifiedFeaturePodCollapsedVerticalPadding +
-                               kUnifiedFeaturePodCollapsedSize.height();
-
-  int visible_count = 0;
-  for (int i = 0; i < child_count(); ++i) {
-    if (static_cast<const FeaturePodButton*>(child_at(i))->visible_preferred())
-      ++visible_count;
-  }
-
-  // floor(visible_count / kUnifiedFeaturePodItemsInRow)
-  int number_of_lines = (visible_count + kUnifiedFeaturePodItemsInRow - 1) /
-                        kUnifiedFeaturePodItemsInRow;
-  const int expanded_height =
-      kUnifiedFeaturePodVerticalPadding +
-      (kUnifiedFeaturePodVerticalPadding + kUnifiedFeaturePodSize.height()) *
-          number_of_lines;
-
-  return gfx::Size(
-      kTrayMenuWidth,
-      static_cast<int>(collapsed_height * (1.0 - expanded_amount_) +
-                       expanded_height * expanded_amount_));
-}
-
 void FeaturePodsContainerView::SetExpandedAmount(double expanded_amount) {
   DCHECK(0.0 <= expanded_amount && expanded_amount <= 1.0);
   if (expanded_amount_ == expanded_amount)
@@ -53,6 +29,21 @@
   Layout();
 }
 
+int FeaturePodsContainerView::GetExpandedHeight() const {
+  int visible_count = 0;
+  for (int i = 0; i < child_count(); ++i) {
+    if (static_cast<const FeaturePodButton*>(child_at(i))->visible_preferred())
+      ++visible_count;
+  }
+
+  // floor(visible_count / kUnifiedFeaturePodItemsInRow)
+  int number_of_lines = (visible_count + kUnifiedFeaturePodItemsInRow - 1) /
+                        kUnifiedFeaturePodItemsInRow;
+  return kUnifiedFeaturePodVerticalPadding +
+         (kUnifiedFeaturePodVerticalPadding + kUnifiedFeaturePodSize.height()) *
+             number_of_lines;
+}
+
 void FeaturePodsContainerView::SaveFocus() {
   focused_button_ = nullptr;
   for (int i = 0; i < child_count(); ++i) {
@@ -69,6 +60,15 @@
     focused_button_->RequestFocus();
 }
 
+gfx::Size FeaturePodsContainerView::CalculatePreferredSize() const {
+  const int collapsed_height = 2 * kUnifiedFeaturePodCollapsedVerticalPadding +
+                               kUnifiedFeaturePodCollapsedSize.height();
+  return gfx::Size(
+      kTrayMenuWidth,
+      static_cast<int>(collapsed_height * (1.0 - expanded_amount_) +
+                       GetExpandedHeight() * expanded_amount_));
+}
+
 void FeaturePodsContainerView::ChildVisibilityChanged(View* child) {
   // ChildVisibilityChanged can change child visibility using
   // SetVisibleByContainer() in UpdateChildVisibility(), so we have to prevent
diff --git a/ash/system/unified/feature_pods_container_view.h b/ash/system/unified/feature_pods_container_view.h
index 6e5684d..5185c8e 100644
--- a/ash/system/unified/feature_pods_container_view.h
+++ b/ash/system/unified/feature_pods_container_view.h
@@ -25,6 +25,9 @@
   // horizontally placed.
   void SetExpandedAmount(double expanded_amount);
 
+  // Get height of the view when |expanded_amount| is set to 1.0.
+  int GetExpandedHeight() const;
+
   // Save and restore keyboard focus of a child feature pod button. If no button
   // has focus or no focus is saved, these methods are no-op.
   void SaveFocus();
diff --git a/ash/system/unified/unified_slider_bubble_controller.cc b/ash/system/unified/unified_slider_bubble_controller.cc
index 67230d9..49716ba4 100644
--- a/ash/system/unified/unified_slider_bubble_controller.cc
+++ b/ash/system/unified/unified_slider_bubble_controller.cc
@@ -35,8 +35,10 @@
 void UnifiedSliderBubbleController::CloseBubble() {
   autoclose_.Stop();
   slider_controller_.reset();
-  if (bubble_widget_)
-    bubble_widget_->Close();
+  if (!bubble_widget_)
+    return;
+  bubble_widget_->Close();
+  tray_->SetTrayBubbleHeight(0);
 }
 
 bool UnifiedSliderBubbleController::IsBubbleShown() const {
@@ -97,7 +99,9 @@
       slider_type_ = slider_type;
       CreateSliderController();
 
-      bubble_view_->AddChildView(slider_controller_->CreateView());
+      UnifiedSliderView* slider_view =
+          static_cast<UnifiedSliderView*>(slider_controller_->CreateView());
+      bubble_view_->AddChildView(slider_view);
       bubble_view_->Layout();
     }
 
@@ -122,7 +126,9 @@
       tray_->shelf()->GetSystemTrayAnchor()->GetBubbleAnchor();
 
   bubble_view_ = new views::TrayBubbleView(init_params);
-  bubble_view_->AddChildView(slider_controller_->CreateView());
+  UnifiedSliderView* slider_view =
+      static_cast<UnifiedSliderView*>(slider_controller_->CreateView());
+  bubble_view_->AddChildView(slider_view);
   bubble_view_->SetBorder(
       views::CreateEmptyBorder(kUnifiedTopShortcutSpacing, 0, 0, 0));
   bubble_view_->set_color(kUnifiedMenuBackgroundColor);
@@ -134,7 +140,15 @@
   TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
   bubble_view_->InitializeAndShowBubble();
 
+  // Notify value change accessibility event because the popup is triggered by
+  // changing value using an accessor key like VolUp.
+  slider_view->slider()->NotifyAccessibilityEvent(
+      ax::mojom::Event::kValueChanged, true);
+
   StartAutoCloseTimer();
+
+  tray_->SetTrayBubbleHeight(
+      bubble_widget_->GetWindowBoundsInScreen().height());
 }
 
 void UnifiedSliderBubbleController::CreateSliderController() {
diff --git a/ash/system/unified/unified_slider_view.cc b/ash/system/unified/unified_slider_view.cc
index 61346c0..7af5d75 100644
--- a/ash/system/unified/unified_slider_view.cc
+++ b/ash/system/unified/unified_slider_view.cc
@@ -97,13 +97,23 @@
   AddChildView(button_);
   AddChildView(slider_);
 
+  // Prevent an accessibility event while initiallizing this view. Typically
+  // the first update of the slider value is conducted by the caller function
+  // to reflect the current value.
   slider_->set_enable_accessibility_events(false);
+
   slider_->GetViewAccessibility().OverrideName(
       l10n_util::GetStringUTF16(accessible_name_id));
   slider_->SetBorder(views::CreateEmptyBorder(kUnifiedSliderPadding));
   layout->SetFlexForView(slider_, 1);
 }
 
+void UnifiedSliderView::SetSliderValue(float value, bool by_user) {
+  slider_->SetValue(value);
+  if (by_user)
+    slider_->set_enable_accessibility_events(true);
+}
+
 UnifiedSliderView::~UnifiedSliderView() = default;
 
 }  // namespace ash
diff --git a/ash/system/unified/unified_slider_view.h b/ash/system/unified/unified_slider_view.h
index ba99a372..6465b10e 100644
--- a/ash/system/unified/unified_slider_view.h
+++ b/ash/system/unified/unified_slider_view.h
@@ -81,6 +81,10 @@
   UnifiedSliderButton* button() { return button_; }
   views::Slider* slider() { return slider_; }
 
+  // Sets a slider value. If |by_user| is false, accessibility events will not
+  // be triggered.
+  void SetSliderValue(float value, bool by_user);
+
  private:
   // Unowned. Owned by views hierarchy.
   UnifiedSliderButton* const button_;
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc
index cddc5c4..cfb1e8b 100644
--- a/ash/system/unified/unified_system_tray.cc
+++ b/ash/system/unified/unified_system_tray.cc
@@ -47,6 +47,10 @@
 
   message_center::UiController* ui_controller() { return ui_controller_.get(); }
 
+  void SetTrayBubbleHeight(int height) {
+    popup_alignment_delegate_->SetTrayBubbleHeight(height);
+  }
+
  private:
   std::unique_ptr<message_center::UiController> ui_controller_;
   std::unique_ptr<AshPopupAlignmentDelegate> popup_alignment_delegate_;
@@ -89,6 +93,7 @@
 
 void UnifiedSystemTray::UiDelegate::HidePopups() {
   message_popup_collection_->MarkAllPopupsShown();
+  popup_alignment_delegate_->SetTrayBubbleHeight(0);
 }
 
 bool UnifiedSystemTray::UiDelegate::ShowMessageCenter(bool show_by_click) {
@@ -205,6 +210,10 @@
       UnifiedSliderBubbleController::SLIDER_TYPE_VOLUME);
 }
 
+void UnifiedSystemTray::SetTrayBubbleHeight(int height) {
+  ui_delegate_->SetTrayBubbleHeight(height);
+}
+
 gfx::Rect UnifiedSystemTray::GetBubbleBoundsInScreen() const {
   return bubble_ ? bubble_->GetBoundsInScreen() : gfx::Rect();
 }
diff --git a/ash/system/unified/unified_system_tray.h b/ash/system/unified/unified_system_tray.h
index dd5ce3af..48383c6 100644
--- a/ash/system/unified/unified_system_tray.h
+++ b/ash/system/unified/unified_system_tray.h
@@ -70,6 +70,11 @@
   // open when disabling, also close it.
   void SetTrayEnabled(bool enabled);
 
+  // Sets the height of the system tray bubble from the edge of the work area
+  // so that the notification popups don't overlap with the tray. Pass 0 if no
+  // bubble is shown.
+  void SetTrayBubbleHeight(int height);
+
   // TrayBackgroundView:
   bool PerformAction(const ui::Event& event) override;
   void ShowBubble(bool show_by_click) override;
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc
index a5b316d..3cfb910 100644
--- a/ash/system/unified/unified_system_tray_bubble.cc
+++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -22,11 +22,46 @@
 
 constexpr int kPaddingFromScreenTop = 8;
 
+// Container view of UnifiedSystemTrayView to return fake preferred size for
+// animation optimization. See UnifiedSystemTrayBubble::UpdateTransform().
+// The fake size is specific to the structure of TrayBubbleView, so it is better
+// to keep it separate from UnifiedSystemTrayView.
+class ContainerView : public views::View {
+ public:
+  explicit ContainerView(UnifiedSystemTrayView* unified_view)
+      : unified_view_(unified_view) {
+    AddChildView(unified_view);
+  }
+
+  ~ContainerView() override = default;
+
+  // views::View:
+  void Layout() override { unified_view_->SetBoundsRect(GetContentsBounds()); }
+
+  gfx::Size CalculatePreferredSize() const override {
+    // If transform is used, always return the maximum height. Otherwise, return
+    // the actual height.
+    return gfx::Size(kTrayMenuWidth, unified_view_->IsTransformEnabled()
+                                         ? unified_view_->GetExpandedHeight()
+                                         : unified_view_->GetCurrentHeight());
+  }
+
+  void ChildPreferredSizeChanged(views::View* child) override {
+    PreferredSizeChanged();
+  }
+
+ private:
+  UnifiedSystemTrayView* const unified_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(ContainerView);
+};
+
 }  // namespace
 
 UnifiedSystemTrayBubble::UnifiedSystemTrayBubble(UnifiedSystemTray* tray,
                                                  bool show_by_click)
-    : controller_(std::make_unique<UnifiedSystemTrayController>(tray->model())),
+    : controller_(
+          std::make_unique<UnifiedSystemTrayController>(tray->model(), this)),
       tray_(tray) {
   if (show_by_click)
     time_shown_by_click_ = base::TimeTicks::Now();
@@ -53,7 +88,7 @@
       std::make_unique<TimeToClickRecorder>(this, unified_view_);
   unified_view_->SetMaxHeight(max_height);
   bubble_view_->SetMaxHeight(max_height);
-  bubble_view_->AddChildView(unified_view_);
+  bubble_view_->AddChildView(new ContainerView(unified_view_));
   bubble_view_->set_anchor_view_insets(
       tray->shelf()->GetSystemTrayAnchor()->GetBubbleAnchorInsets());
   bubble_view_->set_color(SK_ColorTRANSPARENT);
@@ -65,8 +100,7 @@
   TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
   bubble_view_->InitializeAndShowBubble();
   if (app_list::features::IsBackgroundBlurEnabled()) {
-    // ClientView's layer (See TrayBubbleView::InitializeAndShowBubble())
-    bubble_view_->layer()->parent()->SetBackgroundBlur(
+    bubble_widget_->client_view()->layer()->SetBackgroundBlur(
         kUnifiedMenuBackgroundBlur);
   }
 
@@ -129,6 +163,37 @@
   controller_->EnsureExpanded();
 }
 
+void UnifiedSystemTrayBubble::UpdateTransform() {
+  if (!bubble_widget_)
+    return;
+
+  DCHECK(unified_view_);
+
+  if (!unified_view_->IsTransformEnabled()) {
+    unified_view_->SetTransform(gfx::Transform());
+    DestroyBlurLayerForAnimation();
+    SetFrameVisible(true);
+    return;
+  }
+
+  SetFrameVisible(false);
+
+  const int y_offset =
+      unified_view_->GetExpandedHeight() - unified_view_->GetCurrentHeight();
+
+  gfx::Transform transform;
+  transform.Translate(0, y_offset);
+  unified_view_->SetTransform(transform);
+
+  CreateBlurLayerForAnimation();
+
+  if (blur_layer_) {
+    gfx::Rect blur_bounds = bubble_widget_->client_view()->layer()->bounds();
+    blur_bounds.Inset(gfx::Insets(y_offset, 0, 0, 0));
+    blur_layer_->layer()->SetBounds(blur_bounds);
+  }
+}
+
 TrayBackgroundView* UnifiedSystemTrayBubble::GetTray() const {
   return tray_;
 }
@@ -186,4 +251,45 @@
   bubble_view_->GetWidget()->GetNativeWindow()->SetBounds(bounds);
 }
 
+void UnifiedSystemTrayBubble::CreateBlurLayerForAnimation() {
+  if (!app_list::features::IsBackgroundBlurEnabled())
+    return;
+
+  if (blur_layer_)
+    return;
+
+  DCHECK(bubble_widget_);
+
+  bubble_widget_->client_view()->layer()->SetBackgroundBlur(0);
+
+  blur_layer_ = views::Painter::CreatePaintedLayer(
+      views::Painter::CreateSolidRoundRectPainter(SK_ColorTRANSPARENT, 0));
+  blur_layer_->layer()->SetFillsBoundsOpaquely(false);
+
+  bubble_widget_->GetLayer()->Add(blur_layer_->layer());
+  bubble_widget_->GetLayer()->StackAtBottom(blur_layer_->layer());
+
+  blur_layer_->layer()->SetBounds(
+      bubble_widget_->client_view()->layer()->bounds());
+  blur_layer_->layer()->SetBackgroundBlur(kUnifiedMenuBackgroundBlur);
+}
+
+void UnifiedSystemTrayBubble::DestroyBlurLayerForAnimation() {
+  if (!app_list::features::IsBackgroundBlurEnabled())
+    return;
+
+  if (!blur_layer_)
+    return;
+
+  blur_layer_.reset();
+
+  bubble_widget_->client_view()->layer()->SetBackgroundBlur(
+      kUnifiedMenuBackgroundBlur);
+}
+
+void UnifiedSystemTrayBubble::SetFrameVisible(bool visible) {
+  DCHECK(bubble_widget_);
+  bubble_widget_->non_client_view()->frame_view()->SetVisible(visible);
+}
+
 }  // namespace ash
diff --git a/ash/system/unified/unified_system_tray_bubble.h b/ash/system/unified/unified_system_tray_bubble.h
index 61ed3ba..c6bda6f 100644
--- a/ash/system/unified/unified_system_tray_bubble.h
+++ b/ash/system/unified/unified_system_tray_bubble.h
@@ -15,9 +15,13 @@
 #include "base/time/time.h"
 #include "ui/views/widget/widget_observer.h"
 
+namespace ui {
+class LayerOwner;
+}  // namespace ui
+
 namespace views {
 class Widget;
-}
+}  // namespace views
 
 namespace ash {
 
@@ -52,6 +56,12 @@
   // Ensure the bubble is expanded.
   void EnsureExpanded();
 
+  // Update layer transform during expand / collapse animation. During
+  // animation, the height of the view changes, but resizing of the bubble is
+  // performance bottleneck. This method makes use of layer transform to avoid
+  // resizing of the bubble during animation.
+  void UpdateTransform();
+
   // TrayBubbleBase:
   TrayBackgroundView* GetTray() const override;
   views::TrayBubbleView* GetBubbleView() const override;
@@ -72,6 +82,14 @@
 
   void UpdateBubbleBounds();
 
+  // Create / destroy background blur layer that is used during animation.
+  void CreateBlurLayerForAnimation();
+  void DestroyBlurLayerForAnimation();
+
+  // Set visibility of bubble frame border. Used for disabling the border during
+  // animation.
+  void SetFrameVisible(bool visible);
+
   // Controller of UnifiedSystemTrayView. As the view is owned by views
   // hierarchy, we have to own the controller here.
   std::unique_ptr<UnifiedSystemTrayController> controller_;
@@ -93,6 +111,9 @@
   // click (|show_by_click| in ctor is false), it is not set.
   base::Optional<base::TimeTicks> time_shown_by_click_;
 
+  // Background blur layer that is used during animation.
+  std::unique_ptr<ui::LayerOwner> blur_layer_;
+
   views::TrayBubbleView* bubble_view_ = nullptr;
   UnifiedSystemTrayView* unified_view_ = nullptr;
 
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc
index 6ec855b..c5096d1 100644
--- a/ash/system/unified/unified_system_tray_controller.cc
+++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -33,6 +33,7 @@
 #include "ash/system/unified/feature_pod_controller_base.h"
 #include "ash/system/unified/quiet_mode_feature_pod_controller.h"
 #include "ash/system/unified/unified_notifier_settings_controller.h"
+#include "ash/system/unified/unified_system_tray_bubble.h"
 #include "ash/system/unified/unified_system_tray_model.h"
 #include "ash/system/unified/unified_system_tray_view.h"
 #include "ash/system/unified/user_chooser_view.h"
@@ -58,8 +59,11 @@
 }  // namespace
 
 UnifiedSystemTrayController::UnifiedSystemTrayController(
-    UnifiedSystemTrayModel* model)
-    : model_(model), animation_(std::make_unique<gfx::SlideAnimation>(this)) {
+    UnifiedSystemTrayModel* model,
+    UnifiedSystemTrayBubble* bubble)
+    : model_(model),
+      bubble_(bubble),
+      animation_(std::make_unique<gfx::SlideAnimation>(this)) {
   animation_->Reset(model->expanded_on_open() ? 1.0 : 0.0);
   animation_->SetSlideDuration(kExpandAnimationDurationMs);
   animation_->SetTweenType(gfx::Tween::EASE_IN_OUT);
@@ -147,6 +151,9 @@
 }
 
 void UnifiedSystemTrayController::ToggleExpanded() {
+  if (animation_->is_animating())
+    return;
+
   UMA_HISTOGRAM_ENUMERATION("ChromeOS.SystemTray.ToggleExpanded",
                             TOGGLE_EXPANDED_TYPE_BY_BUTTON,
                             TOGGLE_EXPANDED_TYPE_COUNT);
@@ -364,6 +371,9 @@
 void UnifiedSystemTrayController::UpdateExpandedAmount() {
   double expanded_amount = animation_->GetCurrentValue();
   unified_view_->SetExpandedAmount(expanded_amount);
+  // Can be null in unit tests.
+  if (bubble_)
+    bubble_->UpdateTransform();
   if (expanded_amount == 0.0 || expanded_amount == 1.0)
     model_->set_expanded_on_open(expanded_amount == 1.0);
 }
diff --git a/ash/system/unified/unified_system_tray_controller.h b/ash/system/unified/unified_system_tray_controller.h
index c6bad93e..0fc2eaa 100644
--- a/ash/system/unified/unified_system_tray_controller.h
+++ b/ash/system/unified/unified_system_tray_controller.h
@@ -24,13 +24,15 @@
 class FeaturePodControllerBase;
 class UnifiedBrightnessSliderController;
 class UnifiedVolumeSliderController;
+class UnifiedSystemTrayBubble;
 class UnifiedSystemTrayModel;
 class UnifiedSystemTrayView;
 
 // Controller class of UnifiedSystemTrayView. Handles events of the view.
 class ASH_EXPORT UnifiedSystemTrayController : public gfx::AnimationDelegate {
  public:
-  explicit UnifiedSystemTrayController(UnifiedSystemTrayModel* model);
+  UnifiedSystemTrayController(UnifiedSystemTrayModel* model,
+                              UnifiedSystemTrayBubble* bubble = nullptr);
   ~UnifiedSystemTrayController() override;
 
   // Create the view. The created view is unowned.
@@ -149,6 +151,9 @@
   // Unowned. Owned by Views hierarchy.
   UnifiedSystemTrayView* unified_view_ = nullptr;
 
+  // Unowned.
+  UnifiedSystemTrayBubble* bubble_ = nullptr;
+
   // The controller of the current detailed view. If the main view is shown,
   // it's null. Owned.
   std::unique_ptr<DetailedViewController> detailed_view_controller_;
diff --git a/ash/system/unified/unified_system_tray_view.cc b/ash/system/unified/unified_system_tray_view.cc
index ffbe438..ffb1d80e 100644
--- a/ash/system/unified/unified_system_tray_view.cc
+++ b/ash/system/unified/unified_system_tray_view.cc
@@ -20,6 +20,7 @@
 #include "ui/views/background.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/painter.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 
@@ -88,6 +89,13 @@
   UpdateOpacity();
 }
 
+int UnifiedSlidersContainerView::GetExpandedHeight() const {
+  int height = 0;
+  for (int i = 0; i < child_count(); ++i)
+    height += child_at(i)->GetHeightForWidth(kTrayMenuWidth);
+  return height;
+}
+
 void UnifiedSlidersContainerView::Layout() {
   int y = 0;
   for (int i = 0; i < child_count(); ++i) {
@@ -99,10 +107,7 @@
 }
 
 gfx::Size UnifiedSlidersContainerView::CalculatePreferredSize() const {
-  int height = 0;
-  for (int i = 0; i < child_count(); ++i)
-    height += child_at(i)->GetHeightForWidth(kTrayMenuWidth);
-  return gfx::Size(kTrayMenuWidth, height * expanded_amount_);
+  return gfx::Size(kTrayMenuWidth, GetExpandedHeight() * expanded_amount_);
 }
 
 void UnifiedSlidersContainerView::UpdateOpacity() {
@@ -127,7 +132,8 @@
 UnifiedSystemTrayView::UnifiedSystemTrayView(
     UnifiedSystemTrayController* controller,
     bool initially_expanded)
-    : controller_(controller),
+    : expanded_amount_(initially_expanded ? 1.0 : 0.0),
+      controller_(controller),
       message_center_view_(
           new UnifiedMessageCenterView(controller,
                                        message_center::MessageCenter::Get())),
@@ -164,7 +170,7 @@
   detailed_view_container_->SetVisible(false);
   AddChildView(detailed_view_container_);
 
-  top_shortcuts_view_->SetExpandedAmount(initially_expanded ? 1.0 : 0.0);
+  top_shortcuts_view_->SetExpandedAmount(expanded_amount_);
 }
 
 UnifiedSystemTrayView::~UnifiedSystemTrayView() = default;
@@ -218,15 +224,43 @@
 
 void UnifiedSystemTrayView::SetExpandedAmount(double expanded_amount) {
   DCHECK(0.0 <= expanded_amount && expanded_amount <= 1.0);
+  expanded_amount_ = expanded_amount;
+
   top_shortcuts_view_->SetExpandedAmount(expanded_amount);
   feature_pods_container_->SetExpandedAmount(expanded_amount);
   sliders_container_->SetExpandedAmount(expanded_amount);
-  PreferredSizeChanged();
-  // It is possible that the ratio between |message_center_view_| and others
-  // can change while the bubble size remain unchanged.
+
+  if (!IsTransformEnabled()) {
+    PreferredSizeChanged();
+    // It is possible that the ratio between |message_center_view_| and others
+    // can change while the bubble size remain unchanged.
+    Layout();
+    return;
+  }
+
+  if (height() != GetExpandedHeight())
+    PreferredSizeChanged();
   Layout();
 }
 
+int UnifiedSystemTrayView::GetExpandedHeight() const {
+  return top_shortcuts_view_->GetPreferredSize().height() +
+         feature_pods_container_->GetExpandedHeight() +
+         sliders_container_->GetExpandedHeight() +
+         system_info_view_->GetPreferredSize().height();
+}
+
+int UnifiedSystemTrayView::GetCurrentHeight() const {
+  return GetPreferredSize().height();
+}
+
+bool UnifiedSystemTrayView::IsTransformEnabled() const {
+  // TODO(tetsui): Support animation by transform even when
+  // UnifiedMessageCenterview is visible.
+  return expanded_amount_ != 0.0 && expanded_amount_ != 1.0 &&
+         !message_center_view_->visible();
+}
+
 void UnifiedSystemTrayView::ShowClearAllAnimation() {
   message_center_view_->ShowClearAllAnimation();
 }
diff --git a/ash/system/unified/unified_system_tray_view.h b/ash/system/unified/unified_system_tray_view.h
index 5c1cc8d2..25c5d70e 100644
--- a/ash/system/unified/unified_system_tray_view.h
+++ b/ash/system/unified/unified_system_tray_view.h
@@ -29,6 +29,9 @@
   // Otherwise, it shows intermediate state.
   void SetExpandedAmount(double expanded_amount);
 
+  // Get height of the view when |expanded_amount| is set to 1.0.
+  int GetExpandedHeight() const;
+
   // Update opacity of each child slider views based on |expanded_amount_|.
   void UpdateOpacity();
 
@@ -77,6 +80,18 @@
   // Otherwise, it shows intermediate state.
   void SetExpandedAmount(double expanded_amount);
 
+  // Get height of the view when |expanded_amount| is set to 1.0.
+  int GetExpandedHeight() const;
+
+  // Get current height of the view.
+  int GetCurrentHeight() const;
+
+  // Return true if layer transform can be used against the view. During
+  // animation, the height of the view changes, but resizing of the bubble
+  // is performance bottleneck. If this method returns true, the embedder can
+  // call SetTransform() to move this view in order to avoid resizing.
+  bool IsTransformEnabled() const;
+
   void ShowClearAllAnimation();
 
   // views::View:
@@ -84,6 +99,8 @@
   void ChildPreferredSizeChanged(views::View* child) override;
 
  private:
+  double expanded_amount_;
+
   // Unowned.
   UnifiedSystemTrayController* controller_;
 
diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
index d3163e5..e1289e7e 100644
--- a/base/memory/shared_memory_posix.cc
+++ b/base/memory/shared_memory_posix.cc
@@ -164,13 +164,6 @@
         return false;
       }
     }
-    if (fd.is_valid()) {
-      // "a+" is always appropriate: if it's a new file, a+ is similar to w+.
-      if (!fdopen(fd.get(), "a+")) {
-        PLOG(ERROR) << "Creating file stream in " << path.value() << " failed";
-        return false;
-      }
-    }
   }
   if (fd.is_valid() && fix_size) {
     // Get current size.
diff --git a/base/test/data/file_util/.gitattributes b/base/test/data/file_util/.gitattributes
new file mode 100644
index 0000000..07998b9
--- /dev/null
+++ b/base/test/data/file_util/.gitattributes
@@ -0,0 +1,2 @@
+/blank_line_crlf.txt -text
+/crlf.txt -text
\ No newline at end of file
diff --git a/base/timer/mock_timer.cc b/base/timer/mock_timer.cc
index 2589c18..e55bf14 100644
--- a/base/timer/mock_timer.cc
+++ b/base/timer/mock_timer.cc
@@ -23,24 +23,6 @@
 
 }  // namespace
 
-MockTimer::MockTimer(bool retain_user_task, bool is_repeating)
-    : Timer(retain_user_task, is_repeating, &clock_),
-      test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) {
-  Timer::SetTaskRunner(test_task_runner_);
-}
-
-MockTimer::~MockTimer() = default;
-
-void MockTimer::SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) {
-  NOTREACHED() << "MockTimer doesn't support SetTaskRunner().";
-}
-
-void MockTimer::Fire() {
-  DCHECK(IsRunning());
-  clock_.Advance(std::max(TimeDelta(), desired_run_time() - clock_.NowTicks()));
-  FlushPendingTasks(test_task_runner_.get());
-}
-
 MockOneShotTimer::MockOneShotTimer()
     : OneShotTimer(&clock_),
       test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) {
diff --git a/base/timer/mock_timer.h b/base/timer/mock_timer.h
index 81dc2bc..a2263d4e 100644
--- a/base/timer/mock_timer.h
+++ b/base/timer/mock_timer.h
@@ -15,25 +15,7 @@
 // A mock implementation of base::Timer which requires being explicitly
 // Fire()'d.
 // Prefer using ScopedTaskEnvironment::MOCK_TIME + FastForward*() to this when
-// possible
-class MockTimer : public Timer {
- public:
-  MockTimer(bool retain_user_task, bool is_repeating);
-  ~MockTimer() override;
-
-  // Testing method.
-  void Fire();
-
- private:
-  // Timer implementation.
-  // MockTimer doesn't support SetTaskRunner. Do not use this.
-  void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) override;
-
-  SimpleTestTickClock clock_;
-  scoped_refptr<TestSimpleTaskRunner> test_task_runner_;
-};
-
-// See MockTimer's comment. Prefer using ScopedTaskEnvironment::MOCK_TIME.
+// possible.
 class MockOneShotTimer : public OneShotTimer {
  public:
   MockOneShotTimer();
@@ -51,7 +33,8 @@
   scoped_refptr<TestSimpleTaskRunner> test_task_runner_;
 };
 
-// See MockTimer's comment. Prefer using ScopedTaskEnvironment::MOCK_TIME.
+// See MockOneShotTimer's comment. Prefer using
+// ScopedTaskEnvironment::MOCK_TIME.
 class MockRepeatingTimer : public RepeatingTimer {
  public:
   MockRepeatingTimer();
@@ -69,7 +52,8 @@
   scoped_refptr<TestSimpleTaskRunner> test_task_runner_;
 };
 
-// See MockTimer's comment. Prefer using ScopedTaskEnvironment::MOCK_TIME.
+// See MockOneShotTimer's comment. Prefer using
+// ScopedTaskEnvironment::MOCK_TIME.
 class MockRetainingOneShotTimer : public RetainingOneShotTimer {
  public:
   MockRetainingOneShotTimer();
diff --git a/base/timer/timer.h b/base/timer/timer.h
index 4471067..bbd1f7fe 100644
--- a/base/timer/timer.h
+++ b/base/timer/timer.h
@@ -293,7 +293,7 @@
 //
 // If destroyed, the timeout is canceled and will not occur even if already
 // inflight.
-class DelayTimer : protected Timer {
+class DelayTimer {
  public:
   template <class Receiver>
   DelayTimer(const Location& posted_from,
@@ -308,13 +308,17 @@
              Receiver* receiver,
              void (Receiver::*method)(),
              const TickClock* tick_clock)
-      : Timer(posted_from,
-              delay,
-              base::Bind(method, base::Unretained(receiver)),
-              false,
-              tick_clock) {}
+      : timer_(posted_from,
+               delay,
+               BindRepeating(method, Unretained(receiver)),
+               tick_clock) {}
 
-  using Timer::Reset;
+  void Reset() { timer_.Reset(); }
+
+ private:
+  RetainingOneShotTimer timer_;
+
+  DISALLOW_COPY_AND_ASSIGN(DelayTimer);
 };
 
 }  // namespace base
diff --git a/build/android/gyp/aar.py b/build/android/gyp/aar.py
index 6145cb0..da39e34 100755
--- a/build/android/gyp/aar.py
+++ b/build/android/gyp/aar.py
@@ -7,13 +7,11 @@
 """Processes an Android AAR file."""
 
 import argparse
-import filecmp
 import os
 import posixpath
 import re
 import shutil
 import sys
-import tempfile
 from xml.etree import ElementTree
 import zipfile
 
@@ -124,28 +122,9 @@
         raise Exception('android_aar_prebuilt() cached .info file is '
                         'out-of-date. Run gn gen with '
                         'update_android_aar_prebuilts=true to update it.')
-
-    # Clear previously extracted versions of the AAR if it is obsolete.
-    with build_utils.TempDir() as tmp_root:
-      build_utils.ExtractAll(args.aar_file, path=tmp_root)
-
-      # Compare files and copy/delete if necessary.
-      dcmp = filecmp.dircmp(args.output_dir, tmp_root, ignore=[])
-      for f in dcmp.left_only:
-        shutil.rmtree(os.path.join(args.output_dir, f), ignore_errors=True)
-
-      for f in dcmp.right_list:
-        tmp_path = os.path.join(tmp_root, f)
-        dst = os.path.join(args.output_dir, f)
-        if os.path.isdir(tmp_path):
-          build_utils.MakeDirectory(dst)
-          continue
-
-        if os.path.isdir(dst):
-          shutil.rmtree(dst, ignore_errors=True)
-        elif os.path.isfile(dst) and filecmp.cmp(dst, tmp_path, shallow=False):
-          continue
-        shutil.copy(tmp_path, dst)
+    # Clear previously extracted versions of the AAR.
+    shutil.rmtree(args.output_dir, True)
+    build_utils.ExtractAll(args.aar_file, path=args.output_dir)
 
   elif args.command == 'list':
     aar_info = _CreateInfo(args.aar_file)
diff --git a/build/android/gyp/copy_ex.py b/build/android/gyp/copy_ex.py
index a9f6a9f4..7a5136c 100755
--- a/build/android/gyp/copy_ex.py
+++ b/build/android/gyp/copy_ex.py
@@ -6,7 +6,6 @@
 
 """Copies files to a directory."""
 
-import filecmp
 import itertools
 import optparse
 import os
@@ -31,14 +30,16 @@
     shutil.copytree(f, os.path.join(dest, os.path.basename(f)))
     deps.extend(_get_all_files(f))
   else:
-    if os.path.isfile(os.path.join(dest, os.path.basename(f))):
-      dest = os.path.join(dest, os.path.basename(f))
-
-    deps.append(f)
-    if os.path.isfile(dest) and filecmp.cmp(dest, f, shallow=False):
-      return
-
+    if os.path.exists(dest):
+      # We remove the destination here if it already exists because,
+      # if the destination is a symlink, shutil.copy() will copy to
+      # the link target rather than replacing the link.
+      if os.path.isfile(dest):
+        os.remove(dest)
+      elif os.path.isfile(os.path.join(dest, os.path.basename(f))):
+        os.remove(os.path.join(dest, os.path.basename(f)))
     shutil.copy(f, dest)
+    deps.append(f)
 
 def DoCopy(options, deps):
   """Copy files or directories given in options.files and update deps."""
@@ -120,3 +121,4 @@
 
 if __name__ == '__main__':
   sys.exit(main(sys.argv[1:]))
+
diff --git a/build/fuchsia/sdk.sha1 b/build/fuchsia/sdk.sha1
index 7a892e7..187a78c 100644
--- a/build/fuchsia/sdk.sha1
+++ b/build/fuchsia/sdk.sha1
@@ -1 +1 @@
-caf1d697c547dbc26b92f426eb1c6899329435e4
\ No newline at end of file
+33e37c7d51ae5aa92cc2e63c54cbf5f6068941c2
\ No newline at end of file
diff --git a/chrome/VERSION b/chrome/VERSION
index a38cba5..8295825f 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=69
 MINOR=0
-BUILD=3485
+BUILD=3487
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index 03f19ad..44394f03b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -55,28 +55,24 @@
     /**
      * Defines the Groups of each Context Menu Item
      */
+    @IntDef({ContextMenuGroup.LINK, ContextMenuGroup.IMAGE, ContextMenuGroup.VIDEO})
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({LINK, IMAGE, VIDEO})
-    public @interface ContextMenuGroup {}
-
-    public static final int LINK = 0;
-    public static final int IMAGE = 1;
-    public static final int VIDEO = 2;
+    public @interface ContextMenuGroup {
+        int LINK = 0;
+        int IMAGE = 1;
+        int VIDEO = 2;
+    }
 
     /**
      * Defines the context menu modes
      */
+    @IntDef({ContextMenuMode.NORMAL, ContextMenuMode.CUSTOM_TAB, ContextMenuMode.WEB_APP})
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-            NORMAL_MODE, /* Default mode */
-            CUSTOM_TAB_MODE, /* Custom tab mode */
-            WEB_APP_MODE /* Full screen mode */
-    })
-    public @interface ContextMenuMode {}
-
-    public static final int NORMAL_MODE = 0;
-    public static final int CUSTOM_TAB_MODE = 1;
-    public static final int WEB_APP_MODE = 2;
+    public @interface ContextMenuMode {
+        int NORMAL = 0; /* Default mode*/
+        int CUSTOM_TAB = 1; /* Custom tab mode */
+        int WEB_APP = 2; /* Full screen mode */
+    }
 
     // Items that are included in all context menus.
     private static final Set<? extends ContextMenuItem> BASE_WHITELIST =
@@ -142,65 +138,85 @@
             CollectionUtil.newArrayList(ChromeContextMenuItem.OPEN_IN_CHROME));
 
     private final ContextMenuItemDelegate mDelegate;
-    private final int mMode;
+    private final @ContextMenuMode int mMode;
 
     static class ContextMenuUma {
         // Note: these values must match the ContextMenuOption enum in histograms.xml.
-        static final int ACTION_OPEN_IN_NEW_TAB = 0;
-        static final int ACTION_OPEN_IN_INCOGNITO_TAB = 1;
-        static final int ACTION_COPY_LINK_ADDRESS = 2;
-        static final int ACTION_COPY_EMAIL_ADDRESS = 3;
-        static final int ACTION_COPY_LINK_TEXT = 4;
-        static final int ACTION_SAVE_LINK = 5;
-        static final int ACTION_SAVE_IMAGE = 6;
-        static final int ACTION_OPEN_IMAGE = 7;
-        static final int ACTION_OPEN_IMAGE_IN_NEW_TAB = 8;
-        static final int ACTION_SEARCH_BY_IMAGE = 11;
-        static final int ACTION_LOAD_ORIGINAL_IMAGE = 13;
-        static final int ACTION_SAVE_VIDEO = 14;
-        static final int ACTION_SHARE_IMAGE = 19;
-        static final int ACTION_OPEN_IN_OTHER_WINDOW = 20;
-        static final int ACTION_SEND_EMAIL = 23;
-        static final int ACTION_ADD_TO_CONTACTS = 24;
-        static final int ACTION_CALL = 30;
-        static final int ACTION_SEND_TEXT_MESSAGE = 31;
-        static final int ACTION_COPY_PHONE_NUMBER = 32;
-        static final int ACTION_OPEN_IN_NEW_CHROME_TAB = 33;
-        static final int ACTION_OPEN_IN_CHROME_INCOGNITO_TAB = 34;
-        static final int ACTION_OPEN_IN_BROWSER = 35;
-        static final int ACTION_OPEN_IN_CHROME = 36;
-        static final int ACTION_SHARE_LINK = 37;
-        static final int NUM_ACTIONS = 38;
+        @IntDef({Action.OPEN_IN_NEW_TAB, Action.OPEN_IN_INCOGNITO_TAB, Action.COPY_LINK_ADDRESS,
+                Action.COPY_EMAIL_ADDRESS, Action.COPY_LINK_TEXT, Action.SAVE_LINK,
+                Action.SAVE_IMAGE, Action.OPEN_IMAGE, Action.OPEN_IMAGE_IN_NEW_TAB,
+                Action.SEARCH_BY_IMAGE, Action.LOAD_ORIGINAL_IMAGE, Action.SAVE_VIDEO,
+                Action.SHARE_IMAGE, Action.OPEN_IN_OTHER_WINDOW, Action.SEND_EMAIL,
+                Action.ADD_TO_CONTACTS, Action.CALL, Action.SEND_TEXT_MESSAGE,
+                Action.COPY_PHONE_NUMBER, Action.OPEN_IN_NEW_CHROME_TAB,
+                Action.OPEN_IN_CHROME_INCOGNITO_TAB, Action.OPEN_IN_BROWSER, Action.OPEN_IN_CHROME,
+                Action.SHARE_LINK})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Action {
+            int OPEN_IN_NEW_TAB = 0;
+            int OPEN_IN_INCOGNITO_TAB = 1;
+            int COPY_LINK_ADDRESS = 2;
+            int COPY_EMAIL_ADDRESS = 3;
+            int COPY_LINK_TEXT = 4;
+            int SAVE_LINK = 5;
+            int SAVE_IMAGE = 6;
+            int OPEN_IMAGE = 7;
+            int OPEN_IMAGE_IN_NEW_TAB = 8;
+            int SEARCH_BY_IMAGE = 11;
+            int LOAD_ORIGINAL_IMAGE = 13;
+            int SAVE_VIDEO = 14;
+            int SHARE_IMAGE = 19;
+            int OPEN_IN_OTHER_WINDOW = 20;
+            int SEND_EMAIL = 23;
+            int ADD_TO_CONTACTS = 24;
+            int CALL = 30;
+            int SEND_TEXT_MESSAGE = 31;
+            int COPY_PHONE_NUMBER = 32;
+            int OPEN_IN_NEW_CHROME_TAB = 33;
+            int OPEN_IN_CHROME_INCOGNITO_TAB = 34;
+            int OPEN_IN_BROWSER = 35;
+            int OPEN_IN_CHROME = 36;
+            int SHARE_LINK = 37;
+            int NUM_ENTRIES = 38;
+        }
 
         // Note: these values must match the ContextMenuSaveLinkType enum in histograms.xml.
         // Only add new values at the end, right before NUM_TYPES. We depend on these specific
         // values in UMA histograms.
-        static final int TYPE_UNKNOWN = 0;
-        static final int TYPE_TEXT = 1;
-        static final int TYPE_IMAGE = 2;
-        static final int TYPE_AUDIO = 3;
-        static final int TYPE_VIDEO = 4;
-        static final int TYPE_PDF = 5;
-        static final int NUM_TYPES = 6;
+        @IntDef({Type.UNKNOWN, Type.TEXT, Type.IMAGE, Type.AUDIO, Type.VIDEO, Type.PDF})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Type {
+            int UNKNOWN = 0;
+            int TEXT = 1;
+            int IMAGE = 2;
+            int AUDIO = 3;
+            int VIDEO = 4;
+            int PDF = 5;
+            int NUM_ENTRIES = 6;
+        }
 
         // Note: these values must match the ContextMenuSaveImage enum in histograms.xml.
-        // Only add new values at the end, right before NUM_SAVE_IMAGE_TYPES.
-        static final int TYPE_SAVE_IMAGE_LOADED = 0;
-        static final int TYPE_SAVE_IMAGE_FETCHED_LOFI = 1;
-        static final int TYPE_SAVE_IMAGE_NOT_DOWNLOADABLE = 2;
-        static final int TYPE_SAVE_IMAGE_DISABLED_AND_IS_NOT_IMAGE_PARAM = 3;
-        static final int TYPE_SAVE_IMAGE_DISABLED_AND_IS_IMAGE_PARAM = 4;
-        static final int TYPE_SAVE_IMAGE_SHOWN = 5;
-        static final int NUM_SAVE_IMAGE_TYPES = 6;
+        // Only add new values at the end, right before NUM_ENTRIES.
+        @IntDef({TypeSaveImage.LOADED, TypeSaveImage.FETCHED_LOFI, TypeSaveImage.NOT_DOWNLOADABLE,
+                TypeSaveImage.DISABLED_AND_IS_NOT_IMAGE_PARAM,
+                TypeSaveImage.DISABLED_AND_IS_IMAGE_PARAM, TypeSaveImage.SHOWN})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface TypeSaveImage {
+            int LOADED = 0;
+            int FETCHED_LOFI = 1;
+            int NOT_DOWNLOADABLE = 2;
+            int DISABLED_AND_IS_NOT_IMAGE_PARAM = 3;
+            int DISABLED_AND_IS_IMAGE_PARAM = 4;
+            int SHOWN = 5;
+            int NUM_ENTRIES = 6;
+        }
 
         /**
          * Records a histogram entry when the user selects an item from a context menu.
          * @param params The ContextMenuParams describing the current context menu.
          * @param action The action that the user selected (e.g. ACTION_SAVE_IMAGE).
          */
-        static void record(ContextMenuParams params, int action) {
-            assert action >= 0;
-            assert action < NUM_ACTIONS;
+        static void record(ContextMenuParams params, @Action int action) {
             String histogramName;
             if (params.isVideo()) {
                 histogramName = "ContextMenu.SelectedOption.Video";
@@ -212,7 +228,7 @@
                 assert params.isAnchor();
                 histogramName = "ContextMenu.SelectedOption.Link";
             }
-            RecordHistogram.recordEnumeratedHistogram(histogramName, action, NUM_ACTIONS);
+            RecordHistogram.recordEnumeratedHistogram(histogramName, action, Action.NUM_ENTRIES);
         }
 
         /**
@@ -221,25 +237,26 @@
          */
         static void recordSaveLinkTypes(String url) {
             String extension = MimeTypeMap.getFileExtensionFromUrl(url);
-            int mimeType = TYPE_UNKNOWN;
+            @Type
+            int mimeType = Type.UNKNOWN;
             if (extension != null) {
                 String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
                 if (type != null) {
                     if (type.startsWith("text")) {
-                        mimeType = TYPE_TEXT;
+                        mimeType = Type.TEXT;
                     } else if (type.startsWith("image")) {
-                        mimeType = TYPE_IMAGE;
+                        mimeType = Type.IMAGE;
                     } else if (type.startsWith("audio")) {
-                        mimeType = TYPE_AUDIO;
+                        mimeType = Type.AUDIO;
                     } else if (type.startsWith("video")) {
-                        mimeType = TYPE_VIDEO;
+                        mimeType = Type.VIDEO;
                     } else if (type.equals("application/pdf")) {
-                        mimeType = TYPE_PDF;
+                        mimeType = Type.PDF;
                     }
                 }
             }
             RecordHistogram.recordEnumeratedHistogram(
-                    "ContextMenu.SaveLinkType", mimeType, NUM_TYPES);
+                    "ContextMenu.SaveLinkType", mimeType, Type.NUM_ENTRIES);
         }
 
         /**
@@ -248,7 +265,7 @@
          */
         static void recordSaveImageUma(int type) {
             RecordHistogram.recordEnumeratedHistogram(
-                    "MobileDownload.ContextMenu.SaveImage", type, NUM_SAVE_IMAGE_TYPES);
+                    "MobileDownload.ContextMenu.SaveImage", type, TypeSaveImage.NUM_ENTRIES);
         }
     }
 
@@ -296,9 +313,9 @@
         Set<ContextMenuItem> supportedOptions = new HashSet<>();
         if (FirstRunStatus.getFirstRunFlowComplete()) {
             supportedOptions.addAll(BASE_WHITELIST);
-            if (mMode == WEB_APP_MODE) {
+            if (mMode == ContextMenuMode.WEB_APP) {
                 supportedOptions.addAll(WEB_APP_MODE_WHITELIST);
-            } else if (mMode == CUSTOM_TAB_MODE) {
+            } else if (mMode == ContextMenuMode.CUSTOM_TAB) {
                 supportedOptions.addAll(CUSTOM_TAB_MODE_WHITELIST);
             } else {
                 supportedOptions.addAll(NORMAL_MODE_WHITELIST);
@@ -313,16 +330,16 @@
         // Split the items into their respective groups.
         List<Pair<Integer, List<ContextMenuItem>>> groupedItems = new ArrayList<>();
         if (params.isAnchor()) {
-            populateItemGroup(LINK, R.string.contextmenu_link_title, groupedItems, supportedOptions,
-                    disabledOptions);
+            populateItemGroup(ContextMenuGroup.LINK, R.string.contextmenu_link_title, groupedItems,
+                    supportedOptions, disabledOptions);
         }
         if (params.isImage()) {
-            populateItemGroup(IMAGE, R.string.contextmenu_image_title, groupedItems,
-                    supportedOptions, disabledOptions);
+            populateItemGroup(ContextMenuGroup.IMAGE, R.string.contextmenu_image_title,
+                    groupedItems, supportedOptions, disabledOptions);
         }
         if (params.isVideo()) {
-            populateItemGroup(VIDEO, R.string.contextmenu_video_title, groupedItems,
-                    supportedOptions, disabledOptions);
+            populateItemGroup(ContextMenuGroup.VIDEO, R.string.contextmenu_video_title,
+                    groupedItems, supportedOptions, disabledOptions);
         }
 
         // If there are no groups there still needs to be a way to add items from the OTHER_GROUP
@@ -343,7 +360,7 @@
         // list.
         addValidItems(groupedItems.get(groupedItems.size() - 1).second, OTHER_GROUP,
                 supportedOptions, disabledOptions);
-        if (mMode == CUSTOM_TAB_MODE) {
+        if (mMode == ContextMenuMode.CUSTOM_TAB) {
             addValidItemsToFront(groupedItems.get(0).second, CUSTOM_TAB_GROUP, supportedOptions,
                     disabledOptions);
         }
@@ -369,11 +386,10 @@
                             .isStartupSuccessfullyCompleted()) {
                 if (!hasSaveImage) {
                     ContextMenuUma.recordSaveImageUma(params.isImage()
-                                    ? ContextMenuUma.TYPE_SAVE_IMAGE_DISABLED_AND_IS_IMAGE_PARAM
-                                    : ContextMenuUma
-                                              .TYPE_SAVE_IMAGE_DISABLED_AND_IS_NOT_IMAGE_PARAM);
+                                    ? ContextMenuUma.TypeSaveImage.DISABLED_AND_IS_IMAGE_PARAM
+                                    : ContextMenuUma.TypeSaveImage.DISABLED_AND_IS_NOT_IMAGE_PARAM);
                 } else {
-                    ContextMenuUma.recordSaveImageUma(ContextMenuUma.TYPE_SAVE_IMAGE_SHOWN);
+                    ContextMenuUma.recordSaveImageUma(ContextMenuUma.TypeSaveImage.SHOWN);
                 }
             }
         }
@@ -386,14 +402,14 @@
             Set<ContextMenuItem> supportedOptions, Set<ContextMenuItem> disabledOptions) {
         List<ContextMenuItem> items = new ArrayList<>();
         switch (contextMenuType) {
-            case LINK:
+            case ContextMenuGroup.LINK:
                 addValidItems(items, LINK_GROUP, supportedOptions, disabledOptions);
                 addValidItems(items, MESSAGE_GROUP, supportedOptions, disabledOptions);
                 break;
-            case IMAGE:
+            case ContextMenuGroup.IMAGE:
                 addValidItems(items, IMAGE_GROUP, supportedOptions, disabledOptions);
                 break;
-            case VIDEO:
+            case ContextMenuGroup.VIDEO:
                 addValidItems(items, VIDEO_GROUP, supportedOptions, disabledOptions);
                 break;
             default:
@@ -541,7 +557,7 @@
             }
         }
 
-        if (mMode == CUSTOM_TAB_MODE) {
+        if (mMode == ContextMenuMode.CUSTOM_TAB) {
             try {
                 URI uri = new URI(params.getUrl());
                 if (UrlUtilities.isInternalScheme(uri) || isEmptyUrl(params.getUrl())) {
@@ -572,22 +588,22 @@
     @Override
     public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams params, int itemId) {
         if (itemId == R.id.contextmenu_open_in_other_window) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_OTHER_WINDOW);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_OTHER_WINDOW);
             mDelegate.onOpenInOtherWindow(params.getUrl(), params.getReferrer());
         } else if (itemId == R.id.contextmenu_open_in_new_tab) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_NEW_TAB);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_NEW_TAB);
             mDelegate.onOpenInNewTab(params.getUrl(), params.getReferrer());
         } else if (itemId == R.id.contextmenu_open_in_incognito_tab) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_INCOGNITO_TAB);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_INCOGNITO_TAB);
             mDelegate.onOpenInNewIncognitoTab(params.getUrl());
         } else if (itemId == R.id.contextmenu_open_image) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IMAGE);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IMAGE);
             mDelegate.onOpenImageUrl(params.getSrcUrl(), params.getReferrer());
         } else if (itemId == R.id.contextmenu_open_image_in_new_tab) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IMAGE_IN_NEW_TAB);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IMAGE_IN_NEW_TAB);
             mDelegate.onOpenImageInNewTab(params.getSrcUrl(), params.getReferrer());
         } else if (itemId == R.id.contextmenu_load_original_image) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_LOAD_ORIGINAL_IMAGE);
+            ContextMenuUma.record(params, ContextMenuUma.Action.LOAD_ORIGINAL_IMAGE);
             DataReductionProxyUma.previewsLoFiContextMenuAction(
                     DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGE_CONTEXT_MENU_CLICKED);
             if (!mDelegate.wasLoadOriginalImageRequestedForPageLoad()) {
@@ -596,57 +612,57 @@
             }
             mDelegate.onLoadOriginalImage();
         } else if (itemId == R.id.contextmenu_copy_link_address) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_COPY_LINK_ADDRESS);
-            mDelegate.onSaveToClipboard(params.getUnfilteredLinkUrl(),
-                    ContextMenuItemDelegate.CLIPBOARD_TYPE_LINK_URL);
+            ContextMenuUma.record(params, ContextMenuUma.Action.COPY_LINK_ADDRESS);
+            mDelegate.onSaveToClipboard(
+                    params.getUnfilteredLinkUrl(), ContextMenuItemDelegate.ClipboardType.LINK_URL);
         } else if (itemId == R.id.contextmenu_call) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_CALL);
+            ContextMenuUma.record(params, ContextMenuUma.Action.CALL);
             mDelegate.onCall(params.getLinkUrl());
         } else if (itemId == R.id.contextmenu_send_message) {
             if (MailTo.isMailTo(params.getLinkUrl())) {
-                ContextMenuUma.record(params, ContextMenuUma.ACTION_SEND_EMAIL);
+                ContextMenuUma.record(params, ContextMenuUma.Action.SEND_EMAIL);
                 mDelegate.onSendEmailMessage(params.getLinkUrl());
             } else if (UrlUtilities.isTelScheme(params.getLinkUrl())) {
-                ContextMenuUma.record(params, ContextMenuUma.ACTION_SEND_TEXT_MESSAGE);
+                ContextMenuUma.record(params, ContextMenuUma.Action.SEND_TEXT_MESSAGE);
                 mDelegate.onSendTextMessage(params.getLinkUrl());
             }
         } else if (itemId == R.id.contextmenu_add_to_contacts) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_ADD_TO_CONTACTS);
+            ContextMenuUma.record(params, ContextMenuUma.Action.ADD_TO_CONTACTS);
             mDelegate.onAddToContacts(params.getLinkUrl());
         } else if (itemId == R.id.contextmenu_copy) {
             if (MailTo.isMailTo(params.getLinkUrl())) {
-                ContextMenuUma.record(params, ContextMenuUma.ACTION_COPY_EMAIL_ADDRESS);
+                ContextMenuUma.record(params, ContextMenuUma.Action.COPY_EMAIL_ADDRESS);
                 mDelegate.onSaveToClipboard(MailTo.parse(params.getLinkUrl()).getTo(),
-                        ContextMenuItemDelegate.CLIPBOARD_TYPE_LINK_URL);
+                        ContextMenuItemDelegate.ClipboardType.LINK_URL);
             } else if (UrlUtilities.isTelScheme(params.getLinkUrl())) {
-                ContextMenuUma.record(params, ContextMenuUma.ACTION_COPY_PHONE_NUMBER);
+                ContextMenuUma.record(params, ContextMenuUma.Action.COPY_PHONE_NUMBER);
                 mDelegate.onSaveToClipboard(UrlUtilities.getTelNumber(params.getLinkUrl()),
-                        ContextMenuItemDelegate.CLIPBOARD_TYPE_LINK_URL);
+                        ContextMenuItemDelegate.ClipboardType.LINK_URL);
             }
         } else if (itemId == R.id.contextmenu_copy_link_text) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_COPY_LINK_TEXT);
+            ContextMenuUma.record(params, ContextMenuUma.Action.COPY_LINK_TEXT);
             mDelegate.onSaveToClipboard(
-                    params.getLinkText(), ContextMenuItemDelegate.CLIPBOARD_TYPE_LINK_TEXT);
+                    params.getLinkText(), ContextMenuItemDelegate.ClipboardType.LINK_TEXT);
         } else if (itemId == R.id.contextmenu_save_image) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_SAVE_IMAGE);
+            ContextMenuUma.record(params, ContextMenuUma.Action.SAVE_IMAGE);
             if (mDelegate.startDownload(params.getSrcUrl(), false)) {
                 helper.startContextMenuDownload(
                         false, mDelegate.isDataReductionProxyEnabledForURL(params.getSrcUrl()));
             }
         } else if (itemId == R.id.contextmenu_save_video) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_SAVE_VIDEO);
+            ContextMenuUma.record(params, ContextMenuUma.Action.SAVE_VIDEO);
             if (mDelegate.startDownload(params.getSrcUrl(), false)) {
                 helper.startContextMenuDownload(false, false);
             }
         } else if (itemId == R.id.contextmenu_save_link_as) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_SAVE_LINK);
+            ContextMenuUma.record(params, ContextMenuUma.Action.SAVE_LINK);
             String url = params.getUnfilteredLinkUrl();
             if (mDelegate.startDownload(url, true)) {
                 ContextMenuUma.recordSaveLinkTypes(url);
                 helper.startContextMenuDownload(true, false);
             }
         } else if (itemId == R.id.contextmenu_share_link) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_SHARE_LINK);
+            ContextMenuUma.record(params, ContextMenuUma.Action.SHARE_LINK);
             ShareParams linkShareParams =
                     new ShareParams.Builder(helper.getActivity(), params.getUrl(), params.getUrl())
                             .setShareDirectly(false)
@@ -654,22 +670,22 @@
                             .build();
             ShareHelper.share(linkShareParams);
         } else if (itemId == R.id.contextmenu_search_by_image) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_SEARCH_BY_IMAGE);
+            ContextMenuUma.record(params, ContextMenuUma.Action.SEARCH_BY_IMAGE);
             helper.searchForImage();
         } else if (itemId == R.id.contextmenu_share_image) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_SHARE_IMAGE);
+            ContextMenuUma.record(params, ContextMenuUma.Action.SHARE_IMAGE);
             helper.shareImage();
         } else if (itemId == R.id.contextmenu_open_in_chrome) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_CHROME);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_CHROME);
             mDelegate.onOpenInChrome(params.getUrl(), params.getPageUrl());
         } else if (itemId == R.id.contextmenu_open_in_new_chrome_tab) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_NEW_CHROME_TAB);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_NEW_CHROME_TAB);
             mDelegate.onOpenInNewChromeTabFromCCT(params.getUrl(), false);
         } else if (itemId == R.id.contextmenu_open_in_chrome_incognito_tab) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_CHROME_INCOGNITO_TAB);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_CHROME_INCOGNITO_TAB);
             mDelegate.onOpenInNewChromeTabFromCCT(params.getUrl(), true);
         } else if (itemId == R.id.contextmenu_open_in_browser_id) {
-            ContextMenuUma.record(params, ContextMenuUma.ACTION_OPEN_IN_BROWSER);
+            ContextMenuUma.record(params, ContextMenuUma.Action.OPEN_IN_BROWSER);
             mDelegate.onOpenInDefaultBrowser(params.getUrl());
         } else {
             assert false;
@@ -706,15 +722,15 @@
             return;
         }
 
-        ContextMenuUma.recordSaveImageUma(ContextMenuUma.TYPE_SAVE_IMAGE_LOADED);
+        ContextMenuUma.recordSaveImageUma(ContextMenuUma.TypeSaveImage.LOADED);
 
         if (wasFetchedLoFi) {
-            ContextMenuUma.recordSaveImageUma(ContextMenuUma.TYPE_SAVE_IMAGE_FETCHED_LOFI);
+            ContextMenuUma.recordSaveImageUma(ContextMenuUma.TypeSaveImage.FETCHED_LOFI);
             return;
         }
 
         if (!isDownloadableScheme) {
-            ContextMenuUma.recordSaveImageUma(ContextMenuUma.TYPE_SAVE_IMAGE_NOT_DOWNLOADABLE);
+            ContextMenuUma.recordSaveImageUma(ContextMenuUma.TypeSaveImage.NOT_DOWNLOADABLE);
         }
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
index 1a408fc..f284123 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
@@ -4,18 +4,27 @@
 
 package org.chromium.chrome.browser.contextmenu;
 
+import android.support.annotation.IntDef;
+
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content_public.browser.ContentViewCore;
 import org.chromium.content_public.common.Referrer;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A delegate responsible for taking actions based on context menu selections.
  */
 public interface ContextMenuItemDelegate {
     // The type of the data to save to the clipboard.
-    public static final int CLIPBOARD_TYPE_LINK_URL = 0;
-    public static final int CLIPBOARD_TYPE_LINK_TEXT = 1;
-    public static final int CLIPBOARD_TYPE_IMAGE_URL = 2;
+    @IntDef({ClipboardType.LINK_URL, ClipboardType.LINK_TEXT, ClipboardType.IMAGE_URL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ClipboardType {
+        int LINK_URL = 0;
+        int LINK_TEXT = 1;
+        int IMAGE_URL = 2;
+    }
 
     /**
      * Called when this ContextMenuItemDelegate is about to be destroyed.
@@ -101,7 +110,7 @@
      * @param text The text to save to the clipboard.
      * @param clipboardType The type of data in {@code text}.
      */
-    void onSaveToClipboard(String text, int clipboardType);
+    void onSaveToClipboard(String text, @ClipboardType int clipboardType);
 
     /**
      * @return whether an activity is available to handle an intent to call a phone number.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuPagerAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuPagerAdapter.java
index 436eca1..f5eea55 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuPagerAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuPagerAdapter.java
@@ -33,10 +33,7 @@
 
     // Addresses the RTL display bug: https://code.google.com/p/android/issues/detail?id=56831
     private int adjustIndexForDirectionality(int index, int count) {
-        if (mIsRightToLeft) {
-            return count - 1 - index;
-        }
-        return index;
+        return mIsRightToLeft ? count - 1 - index : index;
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
index b725ee0..6d26fed 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
@@ -236,7 +236,7 @@
     @Override
     public ContextMenuPopulator createContextMenuPopulator(Tab tab) {
         return new ChromeContextMenuPopulator(new TabContextMenuItemDelegate(tab),
-                ChromeContextMenuPopulator.CUSTOM_TAB_MODE);
+                ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java
index 2c1940c..e66335e3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java
@@ -8,6 +8,7 @@
 import android.content.Context;
 import android.content.Intent;
 
+import org.chromium.base.Log;
 import org.chromium.chrome.browser.AppHooks;
 
 /**
@@ -19,9 +20,12 @@
 public abstract class MediaButtonReceiver extends BroadcastReceiver {
     public abstract Class<?> getServiceClass();
 
+    private static final String TAG = "MediaButtonReceiver";
+
     @Override
     public void onReceive(Context context, Intent intent) {
         intent.setClass(context, getServiceClass());
+        Log.i(TAG, "Receive broadcast message, starting foreground service");
         AppHooks.get().startForegroundService(intent);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
index b3c89f63..ec6e4a2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -286,7 +286,7 @@
     // responsible for hiding it afterwards.
     private static void finishStartingForegroundService(ListenerService s) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
-
+        Log.i(TAG, "finish starting foreground service, calling startForeground!");
         ChromeNotificationBuilder builder =
                 NotificationBuilderFactory.createChromeNotificationBuilder(
                         true /* preferCompat */, ChannelDefinitions.CHANNEL_ID_MEDIA);
@@ -340,6 +340,7 @@
 
         @Override
         public int onStartCommand(Intent intent, int flags, int startId) {
+            Log.i(TAG, "onStartCommand, intent: " + intent);
             if (!processIntent(intent)) stopListenerService();
 
             return START_NOT_STICKY;
@@ -354,6 +355,7 @@
 
         @VisibleForTesting
         void stopListenerService() {
+            Log.i(TAG, "stop listener service!");
             // Call stopForeground to guarantee  Android unset the foreground bit.
             stopForeground(true /* removeNotification */);
             stopSelf();
@@ -373,7 +375,7 @@
                 }
                 return false;
             }
-
+            Log.i(TAG, "process intent, intent Action:" + intent.getAction());
             if (intent.getAction() == null) {
                 // The intent comes from  {@link AppHooks#startForegroundService}.
                 manager.onServiceStarted(this);
@@ -393,9 +395,10 @@
             // ACTION_MEDIA_BUTTON intents which stores the information about the key event.
             if (Intent.ACTION_MEDIA_BUTTON.equals(action)) {
                 KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                Log.i(TAG, "process action, has key event:" + event);
                 if (event == null) return;
                 if (event.getAction() != KeyEvent.ACTION_DOWN) return;
-
+                Log.i(TAG, "process key code, key code:" + event.getKeyCode());
                 switch (event.getKeyCode()) {
                     case KeyEvent.KEYCODE_MEDIA_PLAY:
                         manager.onPlay(
@@ -843,6 +846,7 @@
         if (mService == null) {
             updateMediaSession();
             updateNotificationBuilder();
+            Log.i(TAG, "about to show notification, startForegroundService called!");
             AppHooks.get().startForegroundService(createIntent());
         } else {
             updateNotification(false);
@@ -857,6 +861,10 @@
 
     @VisibleForTesting
     void clearNotification() {
+        Log.i(TAG,
+                "clear notification! has mMediaNotificationInfo: "
+                        + (mMediaNotificationInfo != null) + ", has mMediaSession"
+                        + (mMediaSession != null) + ", has mService:" + (mService != null));
         mThrottler.clearPendingNotifications();
         if (mMediaNotificationInfo == null) return;
 
@@ -913,6 +921,7 @@
 
     @VisibleForTesting
     void updateNotification(boolean serviceStarting) {
+        Log.i(TAG, "update notification! serviceStarting = " + serviceStarting);
         if (mService == null) return;
 
         if (mMediaNotificationInfo == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java
index 5b808aec..86a9edd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java
@@ -38,7 +38,7 @@
      */
     public ContextMenuPopulator createContextMenuPopulator(Tab tab) {
         return new ChromeContextMenuPopulator(new TabContextMenuItemDelegate(tab),
-                ChromeContextMenuPopulator.NORMAL_MODE);
+                ChromeContextMenuPopulator.ContextMenuMode.NORMAL);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java
index 206ce803..a0d4df1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java
@@ -70,8 +70,8 @@
 
     @Override
     public ContextMenuPopulator createContextMenuPopulator(Tab tab) {
-        return new ChromeContextMenuPopulator(
-                new TabContextMenuItemDelegate(tab), ChromeContextMenuPopulator.WEB_APP_MODE);
+        return new ChromeContextMenuPopulator(new TabContextMenuItemDelegate(tab),
+                ChromeContextMenuPopulator.ContextMenuMode.WEB_APP);
     }
 
     @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
index e3f7d636..36278db 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -1375,7 +1375,8 @@
                 mTestServer.getURL("/chrome/test/data/android/tabstest/text_page.html"));
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             WebContents webContents = mActivityTestRule.getWebContents();
-            webContents.getEventForwarder().startFling(SystemClock.uptimeMillis(), 0, -2000, false);
+            webContents.getEventForwarder().startFling(
+                    SystemClock.uptimeMillis(), 0, -2000, false, true);
         });
         ChromeTabUtils.closeCurrentTab(
                 InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
index 29ba15f..4dd6e71 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
@@ -25,6 +25,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
@@ -49,9 +50,13 @@
 import org.chromium.content.browser.test.util.TestTouchUtils;
 import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content.browser.test.util.UiUtils;
+import org.chromium.content_public.browser.GestureListenerManager;
+import org.chromium.content_public.browser.GestureStateListener;
 import org.chromium.content_public.browser.SelectionPopupController;
+import org.chromium.content_public.browser.WebContents;
 import org.chromium.net.test.EmbeddedTestServer;
 
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -78,8 +83,8 @@
                     + "</body>"
                     + "</html>");
 
-    private static final String LONG_HTML_TEST_PAGE = UrlUtils.encodeHtmlDataUri(
-            "<html><body style='height:10000px;'></body></html>");
+    private static final String LONG_HTML_TEST_PAGE =
+            UrlUtils.encodeHtmlDataUri("<html><body style='height:100000px;'></body></html>");
     private static final String LONG_FULLSCREEN_API_HTML_TEST_PAGE = UrlUtils.encodeHtmlDataUri(
             "<html>"
             + "<head>"
@@ -246,6 +251,103 @@
 
     @Test
     @LargeTest
+    @RetryOnFailure
+    public void testHideBrowserControlsAfterFlingBoosting() throws InterruptedException {
+        // Test that fling boosting doesn't break the scroll state management
+        // that's used by the FullscreenManager to dispatch URL bar based
+        // resizes to the renderer.
+        FullscreenManagerTestUtils.disableBrowserOverrides();
+        mActivityTestRule.startMainActivityWithURL(LONG_HTML_TEST_PAGE);
+
+        FullscreenManagerTestUtils.waitForBrowserControlsToBeMoveable(
+                mActivityTestRule, mActivityTestRule.getActivity().getActivityTab());
+
+        final CallbackHelper flingEndCallback = new CallbackHelper();
+        final CallbackHelper scrollStartCallback = new CallbackHelper();
+        GestureStateListener scrollListener = new GestureStateListener() {
+            @Override
+            public void onScrollStarted(int scrollOffsetY, int scrollExtentY) {
+                scrollStartCallback.notifyCalled();
+            }
+
+            @Override
+            public void onFlingEndGesture(int scrollOffsetY, int scrollExtentY) {
+                flingEndCallback.notifyCalled();
+            }
+
+        };
+
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
+        WebContents webContents = tab.getWebContents();
+        GestureListenerManager gestureListenerManager =
+                GestureListenerManager.fromWebContents(webContents);
+        gestureListenerManager.addListener(scrollListener);
+
+        final CallbackHelper viewportCallback = new CallbackHelper();
+        ChromeFullscreenManager.FullscreenListener fullscreenListener =
+                new ChromeFullscreenManager.FullscreenListener() {
+                    @Override
+                    public void onContentOffsetChanged(float offset) {}
+                    @Override
+                    public void onControlsOffsetChanged(
+                            float topOffset, float bottomOffset, boolean needsAnimate) {}
+                    @Override
+                    public void onToggleOverlayVideoMode(boolean enabled) {}
+                    @Override
+                    public void onBottomControlsHeightChanged(int bottomControlsHeight) {}
+                    @Override
+                    public void onUpdateViewportSize() {
+                        viewportCallback.notifyCalled();
+                    }
+                };
+
+        ChromeFullscreenManager fullscreenManager =
+                mActivityTestRule.getActivity().getFullscreenManager();
+        fullscreenManager.addListener(fullscreenListener);
+
+        Assert.assertEquals(0, scrollStartCallback.getCallCount());
+        Assert.assertEquals(0, viewportCallback.getCallCount());
+
+        // Start the first fling.
+        FullscreenManagerTestUtils.fling(mActivityTestRule, 0, -2000);
+
+        // Wait until we hear the gesture scroll begin before we try to fling
+        // again since we'll hit DCHECKs in the fling controller state
+        // management.
+        try {
+            scrollStartCallback.waitForCallback(0, 1, 1000, TimeUnit.MILLISECONDS);
+        } catch (TimeoutException e) {
+            Assert.fail("Timeout waiting for scroll to start");
+        }
+
+        // Fling again while the first fling is still active. This will boost
+        // the first fling.
+        FullscreenManagerTestUtils.fling(mActivityTestRule, 0, -2000);
+
+        Assert.assertEquals(0, flingEndCallback.getCallCount());
+        Assert.assertTrue(gestureListenerManager.isScrollInProgress());
+
+        try {
+            flingEndCallback.waitForCallback(0, 1, 5000, TimeUnit.MILLISECONDS);
+        } catch (TimeoutException e) {
+            Assert.fail("Timeout waiting for scroll to end");
+        }
+
+        // Make sure we call the viewport changed callback since the URL bar was hidden.
+        // Can be called once for the FlingEnd and once for the ScrollEnd.
+        try {
+            viewportCallback.waitForCallback(0, 1, 500, TimeUnit.MILLISECONDS);
+        } catch (TimeoutException e) {
+            Assert.fail("Failed to update viewport");
+        }
+
+        // Ensure we don't still think we're scrolling.
+        Assert.assertFalse(
+                "Failed to reset scrolling state", gestureListenerManager.isScrollInProgress());
+    }
+
+    @Test
+    @LargeTest
     @Feature({"Fullscreen"})
     public void testHidingBrowserControlsRemovesSurfaceFlingerOverlay()
             throws InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java
index 640bc77..ef00309 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java
@@ -16,7 +16,10 @@
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TouchCommon;
+import org.chromium.content_public.browser.GestureListenerManager;
+import org.chromium.content_public.browser.GestureStateListener;
 import org.chromium.content_public.browser.RenderCoordinates;
+import org.chromium.content_public.browser.WebContents;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
@@ -131,7 +134,29 @@
         float dragX = 50f;
         float dragStartY = tab.getView().getHeight() - 50f;
 
+        WebContents webContents = tab.getWebContents();
+
+        final CallbackHelper scrollEndCallback = new CallbackHelper();
+        final CallbackHelper flingEndCallback = new CallbackHelper();
+        GestureStateListener scrollEndListener = new GestureStateListener() {
+            @Override
+            public void onScrollEnded(int scrollOffsetY, int scrollExtentY) {
+                scrollEndCallback.notifyCalled();
+            }
+
+            @Override
+            public void onFlingEndGesture(int scrollOffsetY, int scrollExtentY) {
+                flingEndCallback.notifyCalled();
+            }
+
+        };
+        GestureListenerManager gestureListenerManager =
+                GestureListenerManager.fromWebContents(webContents);
+        gestureListenerManager.addListener(scrollEndListener);
+
         for (int i = 0; i < 10; i++) {
+            int numScrollEndCalled = scrollEndCallback.getCallCount();
+            int numFlingEndCalled = flingEndCallback.getCallCount();
             float dragEndY = dragStartY - fullscreenManager.getTopControlsHeight();
 
             long downTime = SystemClock.uptimeMillis();
@@ -143,9 +168,49 @@
             try {
                 contentMovedCallback.waitForCallback(0, 1, 500, TimeUnit.MILLISECONDS);
 
+                try {
+                    scrollEndCallback.waitForCallback(
+                            numScrollEndCalled, 1, 5000, TimeUnit.MILLISECONDS);
+                    flingEndCallback.waitForCallback(
+                            numFlingEndCalled, 1, 5000, TimeUnit.MILLISECONDS);
+                } catch (TimeoutException e) {
+                    Assert.fail("Didn't get expected ScrollEnd gestures");
+                }
+
+                try {
+                    flingEndCallback.waitForCallback(
+                            numFlingEndCalled, 1, 200, TimeUnit.MILLISECONDS);
+                } catch (TimeoutException e) {
+                    // Depending on timing - the above scroll may not have
+                    // generated a fling. If it did, it the fling end may
+                    // sometimes be called after the scroll end so wait a little
+                    // for it.
+                }
+
+                numFlingEndCalled = flingEndCallback.getCallCount();
+
                 scrollBrowserControls(testRule, false);
                 scrollBrowserControls(testRule, true);
 
+                // Make sure the gesture stream is finished before we hand back control.
+                try {
+                    scrollEndCallback.waitForCallback(
+                            numScrollEndCalled + 1, 2, 5000, TimeUnit.MILLISECONDS);
+                } catch (TimeoutException e) {
+                    Assert.fail("Didn't get expected ScrollEnd gestures");
+                }
+
+                try {
+                    flingEndCallback.waitForCallback(
+                            numFlingEndCalled, 2, 200, TimeUnit.MILLISECONDS);
+                } catch (TimeoutException e) {
+                    // Depending on timing - the above scrolls may not have
+                    // generated flings. If they did, the fling end may sometimes
+                    // be called after the scroll end so wait a little for it.
+                }
+
+                gestureListenerManager.removeListener(scrollEndListener);
+
                 return;
             } catch (TimeoutException e) {
                 // Ignore and retry
@@ -166,4 +231,20 @@
             }
         });
     }
+
+    public static void fling(ChromeTabbedActivityTestRule testRule, final int vx, final int vy) {
+        try {
+            ThreadUtils.runOnUiThread(new Callable<Boolean>() {
+                @Override
+                public Boolean call() {
+                    testRule.getWebContents().getEventForwarder().startFling(
+                            SystemClock.uptimeMillis(), vx, vy, /*synthetic_scroll*/ false,
+                            /*prevent_boosting*/ false);
+                    return true;
+                }
+            });
+        } catch (Throwable e) {
+            Assert.fail("Failed to fling");
+        }
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
index 81b095c4..2453950 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -67,7 +67,7 @@
 
         doReturn(PAGE_URL).when(mItemDelegate).getPageUrl();
 
-        initializePopulator(ChromeContextMenuPopulator.NORMAL_MODE);
+        initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL);
     }
 
     private void initializePopulator(@ContextMenuMode int mode) {
@@ -86,13 +86,13 @@
                 Matchers.contains(ChromeContextMenuItem.COPY_LINK_ADDRESS,
                         ChromeContextMenuItem.COPY_LINK_TEXT));
 
-        initializePopulator(ChromeContextMenuPopulator.CUSTOM_TAB_MODE);
+        initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB);
         enabledItems = getEnabledItems(contextMenuParams);
         Assert.assertThat(enabledItems,
                 Matchers.contains(ChromeContextMenuItem.COPY_LINK_ADDRESS,
                         ChromeContextMenuItem.COPY_LINK_TEXT));
 
-        initializePopulator(ChromeContextMenuPopulator.WEB_APP_MODE);
+        initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP);
         enabledItems = getEnabledItems(contextMenuParams);
         Assert.assertThat(enabledItems,
                 Matchers.contains(ChromeContextMenuItem.COPY_LINK_ADDRESS,
@@ -108,11 +108,11 @@
         List<ContextMenuItem> enabledItems = getEnabledItems(contextMenuParams);
         Assert.assertThat(enabledItems, Matchers.empty());
 
-        initializePopulator(ChromeContextMenuPopulator.CUSTOM_TAB_MODE);
+        initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB);
         enabledItems = getEnabledItems(contextMenuParams);
         Assert.assertThat(enabledItems, Matchers.empty());
 
-        initializePopulator(ChromeContextMenuPopulator.WEB_APP_MODE);
+        initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP);
         enabledItems = getEnabledItems(contextMenuParams);
         Assert.assertThat(enabledItems, Matchers.empty());
     }
@@ -127,12 +127,12 @@
         Assert.assertThat(
                 enabledItems, Matchers.containsInAnyOrder(ChromeContextMenuItem.COPY_LINK_ADDRESS));
 
-        initializePopulator(ChromeContextMenuPopulator.CUSTOM_TAB_MODE);
+        initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB);
         enabledItems = getEnabledItems(contextMenuParams);
         Assert.assertThat(
                 enabledItems, Matchers.containsInAnyOrder(ChromeContextMenuItem.COPY_LINK_ADDRESS));
 
-        initializePopulator(ChromeContextMenuPopulator.WEB_APP_MODE);
+        initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP);
         enabledItems = getEnabledItems(contextMenuParams);
         Assert.assertThat(
                 enabledItems, Matchers.containsInAnyOrder(ChromeContextMenuItem.COPY_LINK_ADDRESS));
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 7e5e245f..c13c4f1d 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-69.0.3483.0_rc-r1.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-69.0.3486.0_rc-r1.afdo.bz2
\ No newline at end of file
diff --git a/chrome/browser/android/vr/vr_controller.cc b/chrome/browser/android/vr/vr_controller.cc
index a26de05..58c3e75 100644
--- a/chrome/browser/android/vr/vr_controller.cc
+++ b/chrome/browser/android/vr/vr_controller.cc
@@ -26,10 +26,6 @@
 constexpr float kFadeDistanceFromFace = 0.34f;
 constexpr float kDeltaAlpha = 3.0f;
 
-// Very small deadzone that should be undetectable to users, but prevents the
-// head offset from being updated every frame on 3DOF devices.
-constexpr float kHeadOffsetDeadzone = 0.0005f;
-
 void ClampTouchpadPosition(gfx::Vector2dF* position) {
   position->set_x(base::ClampToRange(position->x(), 0.0f, 1.0f));
   position->set_y(base::ClampToRange(position->y(), 0.0f, 1.0f));
@@ -303,13 +299,7 @@
   if (head_pose.GetInverse(&inv_pose)) {
     auto current_head_offset = gfx::Point3F();
     inv_pose.TransformPoint(&current_head_offset);
-    // The head offset drifts by a very tiny amount even in 3DOF devices, so
-    // apply a small deadzone to only update the head offset when the head
-    // actually moves.
-    if (head_offset_.SquaredDistanceTo(current_head_offset) >
-        kHeadOffsetDeadzone) {
-      head_offset_ = current_head_offset;
-    }
+    head_offset_ = current_head_offset;
   }
 
   gvr::Mat4f gvr_head_pose;
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
index 12b9530..c34ca94 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -161,6 +161,47 @@
   base::OnceClosure quit_closure_;
 };
 
+// Returns the sum of the number of datatypes per host.
+int GetCookiesTreeModelCount(const CookieTreeNode* root) {
+  int count = 0;
+  for (int i = 0; i < root->child_count(); i++) {
+    const CookieTreeNode* node = root->GetChild(i);
+    EXPECT_GE(node->child_count(), 1);
+    for (int j = 0; j < node->child_count(); j++) {
+      const CookieTreeNode* child = node->GetChild(j);
+      // Quota nodes are not included in the UI due to crbug.com/642955.
+      if (child->GetDetailedInfo().node_type ==
+          CookieTreeNode::DetailedInfo::TYPE_QUOTA) {
+        continue;
+      }
+      count++;
+    }
+  }
+  return count;
+}
+
+// Returns a string with information about the content of the
+// cookie tree model.
+std::string GetCookiesTreeModelInfo(const CookieTreeNode* root) {
+  std::stringstream info;
+  info << "CookieTreeModel: " << std::endl;
+  for (int i = 0; i < root->child_count(); i++) {
+    const CookieTreeNode* node = root->GetChild(i);
+    info << node->GetTitle() << std::endl;
+    for (int j = 0; j < node->child_count(); j++) {
+      const CookieTreeNode* child = node->GetChild(j);
+      // Quota nodes are not included in the UI due to crbug.com/642955.
+      if (child->GetDetailedInfo().node_type ==
+          CookieTreeNode::DetailedInfo::TYPE_QUOTA) {
+        continue;
+      }
+      info << "  " << child->GetTitle() << " "
+           << child->GetDetailedInfo().node_type << std::endl;
+    }
+  }
+  return info.str();
+}
+
 }  // namespace
 
 class BrowsingDataRemoverBrowserTest : public InProcessBrowserTest {
@@ -255,18 +296,18 @@
     ui_test_utils::NavigateToURL(browser(), url);
 
     EXPECT_EQ(0, GetSiteDataCount());
-    EXPECT_EQ(0, GetCookieTreeModelCount());
+    ExpectCookieTreeModelCount(0);
     EXPECT_FALSE(HasDataForType(type));
 
     SetDataForType(type);
     EXPECT_EQ(1, GetSiteDataCount());
-    EXPECT_EQ(1, GetCookieTreeModelCount());
+    ExpectCookieTreeModelCount(1);
     EXPECT_TRUE(HasDataForType(type));
 
     RemoveAndWait(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA,
                   delete_begin);
     EXPECT_EQ(0, GetSiteDataCount());
-    EXPECT_EQ(0, GetCookieTreeModelCount());
+    ExpectCookieTreeModelCount(0);
     EXPECT_FALSE(HasDataForType(type));
   }
 
@@ -274,20 +315,20 @@
   // creates an empty store, are counted and deleted correctly.
   void TestEmptySiteData(const std::string& type, base::Time delete_begin) {
     EXPECT_EQ(0, GetSiteDataCount());
-    EXPECT_EQ(0, GetCookieTreeModelCount());
+    ExpectCookieTreeModelCount(0);
     GURL url = embedded_test_server()->GetURL("/browsing_data/site_data.html");
     ui_test_utils::NavigateToURL(browser(), url);
     EXPECT_EQ(0, GetSiteDataCount());
-    EXPECT_EQ(0, GetCookieTreeModelCount());
+    ExpectCookieTreeModelCount(0);
     // Opening a store of this type creates a site data entry.
     EXPECT_FALSE(HasDataForType(type));
     EXPECT_EQ(1, GetSiteDataCount());
-    EXPECT_EQ(1, GetCookieTreeModelCount());
+    ExpectCookieTreeModelCount(1);
     RemoveAndWait(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA,
                   delete_begin);
 
     EXPECT_EQ(0, GetSiteDataCount());
-    EXPECT_EQ(0, GetCookieTreeModelCount());
+    ExpectCookieTreeModelCount(0);
   }
 
   bool HasDataForType(const std::string& type) {
@@ -312,41 +353,10 @@
     return count;
   }
 
-  int GetCookieTreeModelCount() {
-    Profile* profile = browser()->profile();
-    content::StoragePartition* storage_partition =
-        content::BrowserContext::GetDefaultStoragePartition(profile);
-    content::IndexedDBContext* indexed_db_context =
-        storage_partition->GetIndexedDBContext();
-    content::ServiceWorkerContext* service_worker_context =
-        storage_partition->GetServiceWorkerContext();
-    content::CacheStorageContext* cache_storage_context =
-        storage_partition->GetCacheStorageContext();
-    storage::FileSystemContext* file_system_context =
-        storage_partition->GetFileSystemContext();
-    auto container = std::make_unique<LocalDataContainer>(
-        new BrowsingDataCookieHelper(storage_partition),
-        new BrowsingDataDatabaseHelper(profile),
-        new BrowsingDataLocalStorageHelper(profile),
-        /*session_storage_helper=*/nullptr,
-        new BrowsingDataAppCacheHelper(profile),
-        new BrowsingDataIndexedDBHelper(indexed_db_context),
-        BrowsingDataFileSystemHelper::Create(file_system_context),
-        BrowsingDataQuotaHelper::Create(profile),
-        BrowsingDataChannelIDHelper::Create(profile->GetRequestContext()),
-        new BrowsingDataServiceWorkerHelper(service_worker_context),
-        new BrowsingDataSharedWorkerHelper(storage_partition,
-                                           profile->GetResourceContext()),
-        new BrowsingDataCacheStorageHelper(cache_storage_context),
-        BrowsingDataFlashLSOHelper::Create(profile),
-        BrowsingDataMediaLicenseHelper::Create(file_system_context));
-    base::RunLoop run_loop;
-    CookiesTreeObserver observer(run_loop.QuitClosure());
-    CookiesTreeModel model(std::move(container),
-                           profile->GetExtensionSpecialStoragePolicy());
-    model.AddCookiesTreeObserver(&observer);
-    run_loop.Run();
-    return model.GetRoot()->child_count();
+  inline void ExpectCookieTreeModelCount(int expected) {
+    std::unique_ptr<CookiesTreeModel> model = GetCookiesTreeModel();
+    EXPECT_EQ(expected, GetCookiesTreeModelCount(model->GetRoot()))
+        << GetCookiesTreeModelInfo(model->GetRoot());
   }
 
   void OnVideoDecodePerfInfo(base::RunLoop* run_loop,
@@ -380,6 +390,43 @@
     run_loop->Quit();
   }
 
+  std::unique_ptr<CookiesTreeModel> GetCookiesTreeModel() {
+    Profile* profile = browser()->profile();
+    content::StoragePartition* storage_partition =
+        content::BrowserContext::GetDefaultStoragePartition(profile);
+    content::IndexedDBContext* indexed_db_context =
+        storage_partition->GetIndexedDBContext();
+    content::ServiceWorkerContext* service_worker_context =
+        storage_partition->GetServiceWorkerContext();
+    content::CacheStorageContext* cache_storage_context =
+        storage_partition->GetCacheStorageContext();
+    storage::FileSystemContext* file_system_context =
+        storage_partition->GetFileSystemContext();
+    auto container = std::make_unique<LocalDataContainer>(
+        new BrowsingDataCookieHelper(storage_partition),
+        new BrowsingDataDatabaseHelper(profile),
+        new BrowsingDataLocalStorageHelper(profile),
+        /*session_storage_helper=*/nullptr,
+        new BrowsingDataAppCacheHelper(profile),
+        new BrowsingDataIndexedDBHelper(indexed_db_context),
+        BrowsingDataFileSystemHelper::Create(file_system_context),
+        BrowsingDataQuotaHelper::Create(profile),
+        BrowsingDataChannelIDHelper::Create(profile->GetRequestContext()),
+        new BrowsingDataServiceWorkerHelper(service_worker_context),
+        new BrowsingDataSharedWorkerHelper(storage_partition,
+                                           profile->GetResourceContext()),
+        new BrowsingDataCacheStorageHelper(cache_storage_context),
+        BrowsingDataFlashLSOHelper::Create(profile),
+        BrowsingDataMediaLicenseHelper::Create(file_system_context));
+    base::RunLoop run_loop;
+    CookiesTreeObserver observer(run_loop.QuitClosure());
+    auto model = std::make_unique<CookiesTreeModel>(
+        std::move(container), profile->GetExtensionSpecialStoragePolicy());
+    model->AddCookiesTreeObserver(&observer);
+    run_loop.Run();
+    return model;
+  }
+
   base::test::ScopedFeatureList feature_list_;
 };
 
@@ -660,14 +707,14 @@
 // Test that session storage is not counted until crbug.com/772337 is fixed.
 IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest, SessionStorageCounting) {
   EXPECT_EQ(0, GetSiteDataCount());
-  EXPECT_EQ(0, GetCookieTreeModelCount());
+  ExpectCookieTreeModelCount(0);
   GURL url = embedded_test_server()->GetURL("/browsing_data/site_data.html");
   ui_test_utils::NavigateToURL(browser(), url);
   EXPECT_EQ(0, GetSiteDataCount());
-  EXPECT_EQ(0, GetCookieTreeModelCount());
+  ExpectCookieTreeModelCount(0);
   SetDataForType("SessionStorage");
   EXPECT_EQ(0, GetSiteDataCount());
-  EXPECT_EQ(0, GetCookieTreeModelCount());
+  ExpectCookieTreeModelCount(0);
   EXPECT_TRUE(HasDataForType("SessionStorage"));
 }
 
@@ -707,11 +754,16 @@
   TestEmptySiteData("IndexedDb", GetParam());
 }
 
+const std::vector<std::string> kStorageTypes{
+    "Cookie",    "LocalStorage", "FileSystem",    "SessionStorage",
+    "IndexedDb", "WebSql",       "ServiceWorker", "CacheStorage",
+};
+
 // Test that storage doesn't leave any traces on disk.
 IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest,
                        PRE_PRE_StorageRemovedFromDisk) {
   ASSERT_EQ(0, GetSiteDataCount());
-  EXPECT_EQ(0, GetCookieTreeModelCount());
+  ExpectCookieTreeModelCount(0);
   ASSERT_EQ(0, CheckUserDirectoryForString(kLocalHost, {}));
   // To use secure-only features on a host name, we need an https server.
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
@@ -725,11 +777,7 @@
   GURL url = https_server.GetURL(kLocalHost, "/browsing_data/site_data.html");
   ui_test_utils::NavigateToURL(browser(), url);
 
-  const std::vector<std::string> types{
-      "Cookie",    "LocalStorage", "FileSystem",    "SessionStorage",
-      "IndexedDb", "WebSql",       "ServiceWorker", "CacheStorage",
-  };
-  for (const std::string& type : types) {
+  for (const std::string& type : kStorageTypes) {
     SetDataForType(type);
     EXPECT_TRUE(HasDataForType(type));
   }
@@ -742,13 +790,15 @@
 IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest,
                        PRE_StorageRemovedFromDisk) {
   EXPECT_EQ(1, GetSiteDataCount());
-  EXPECT_EQ(1, GetCookieTreeModelCount());
+  // Expect all datatypes from above except SessionStorage. SessionStorage is
+  // not supported by the CookieTreeModel yet.
+  ExpectCookieTreeModelCount(kStorageTypes.size() - 1);
   RemoveAndWait(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA |
                 content::BrowsingDataRemover::DATA_TYPE_CACHE |
                 ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY |
                 ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS);
   EXPECT_EQ(0, GetSiteDataCount());
-  EXPECT_EQ(0, GetCookieTreeModelCount());
+  ExpectCookieTreeModelCount(0);
 }
 
 // Check if any data remains after a deletion and a Chrome restart to force
@@ -775,6 +825,48 @@
   EXPECT_EQ(0, found) << "A non-whitelisted file contains the hostname.";
 }
 
+// TODO(crbug.com/840080, crbug.com/824533): Filesystem, IndexedDb and
+// CacheStorage can't be deleted on exit correctly at the moment.
+const std::vector<std::string> kSessionOnlyStorageTestTypes{
+    "Cookie", "LocalStorage",
+    // "FileSystem",
+    "SessionStorage",
+    // "IndexedDb",
+    "WebSql", "ServiceWorker",
+    // "CacheStorage",
+};
+
+// Test that storage gets deleted if marked as SessionOnly.
+IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest,
+                       PRE_SessionOnlyStorageRemoved) {
+  ExpectCookieTreeModelCount(0);
+  GURL url = embedded_test_server()->GetURL("/browsing_data/site_data.html");
+  ui_test_utils::NavigateToURL(browser(), url);
+
+  for (const std::string& type : kSessionOnlyStorageTestTypes) {
+    SetDataForType(type);
+    EXPECT_TRUE(HasDataForType(type));
+  }
+  // Expect the datatypes from above except SessionStorage. SessionStorage is
+  // not supported by the CookieTreeModel yet.
+  ExpectCookieTreeModelCount(kSessionOnlyStorageTestTypes.size() - 1);
+  HostContentSettingsMapFactory::GetForProfile(browser()->profile())
+      ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
+                                 CONTENT_SETTING_SESSION_ONLY);
+}
+
+// Restart to delete session only storage.
+IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest,
+                       SessionOnlyStorageRemoved) {
+  // All cookies should have been deleted.
+  ExpectCookieTreeModelCount(0);
+  GURL url = embedded_test_server()->GetURL("/browsing_data/site_data.html");
+  ui_test_utils::NavigateToURL(browser(), url);
+  for (const std::string& type : kSessionOnlyStorageTestTypes) {
+    EXPECT_FALSE(HasDataForType(type));
+  }
+}
+
 // Some storage backend use a different code path for full deletions and
 // partial deletions, so we need to test both.
 INSTANTIATE_TEST_CASE_P(/* no prefix */,
diff --git a/chrome/browser/chromeos/crostini/crostini_app_launch_observer.h b/chrome/browser/chromeos/crostini/crostini_app_launch_observer.h
index 501f288..ea4d692 100644
--- a/chrome/browser/chromeos/crostini/crostini_app_launch_observer.h
+++ b/chrome/browser/chromeos/crostini/crostini_app_launch_observer.h
@@ -10,7 +10,7 @@
 class CrostiniAppLaunchObserver {
  public:
   // Invoked when a Crostini app launch has been requested.
-  virtual void OnAppLaunchRequested(const std::string& startup_id,
+  virtual void OnAppLaunchRequested(const std::string& app_id,
                                     int64_t display_id) = 0;
 
  protected:
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc
index 4ae257a..08fc4c0 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.cc
+++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -108,7 +108,7 @@
   CrostiniAppLaunchObserver* observer =
       chrome_launcher_controller->crostini_app_window_shelf_controller();
   DCHECK_NE(observer, nullptr);
-  observer->OnAppLaunchRequested(registration.DesktopFileId(), display_id);
+  observer->OnAppLaunchRequested(app_id, display_id);
   crostini::CrostiniManager::GetInstance()->LaunchContainerApplication(
       profile, registration.VmName(), registration.ContainerName(),
       registration.DesktopFileId(), files,
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc
index ee042dc..b595c56 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h"
 
+#include "base/files/file_path.h"
 #include "chrome/common/extensions/api/file_manager_private.h"
 #include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
 
@@ -105,11 +106,25 @@
   status.processed = total_bytes_transferred;
   status.total = total_bytes_to_transfer;
 
+  auto extension_ids = GetFileTransfersUpdateEventListenerExtensionIds();
+
   for (const auto& item : syncing_status.item_events) {
     status.transfer_state = ConvertItemEventState(item->state);
-    status.file_url = item->file_title;
 
-    DispatchOnFileTransfersUpdatedEvent(status);
+    base::FilePath path(item->path);
+    for (const auto& extension_id : extension_ids) {
+      status.file_url =
+          ConvertDrivePathToFileSystemUrl(path, extension_id).spec();
+      DispatchOnFileTransfersUpdatedEventToExtension(extension_id, status);
+    }
+  }
+}
+
+void DriveFsEventRouter::DispatchOnFileTransfersUpdatedEvent(
+    const extensions::api::file_manager_private::FileTransferStatus& status) {
+  for (const auto& extension_id :
+       GetFileTransfersUpdateEventListenerExtensionIds()) {
+    DispatchOnFileTransfersUpdatedEventToExtension(extension_id, status);
   }
 }
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
index be0a5b8..2a2851e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
@@ -6,9 +6,16 @@
 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_DRIVEFS_EVENT_ROUTER_H_
 
 #include <map>
+#include <set>
+#include <string>
 
 #include "base/macros.h"
 #include "chromeos/components/drivefs/drivefs_host_observer.h"
+#include "url/gurl.h"
+
+namespace base {
+class FilePath;
+}
 
 namespace extensions {
 namespace api {
@@ -32,7 +39,19 @@
   void OnSyncingStatusUpdate(
       const drivefs::mojom::SyncingStatus& status) override;
 
-  virtual void DispatchOnFileTransfersUpdatedEvent(
+  void DispatchOnFileTransfersUpdatedEvent(
+      const extensions::api::file_manager_private::FileTransferStatus& status);
+
+  virtual std::set<std::string>
+  GetFileTransfersUpdateEventListenerExtensionIds() = 0;
+
+  virtual GURL ConvertDrivePathToFileSystemUrl(
+      const base::FilePath& file_path,
+      const std::string& extension_id) = 0;
+
+  // Helper method for dispatching an event to an extension.
+  virtual void DispatchOnFileTransfersUpdatedEventToExtension(
+      const std::string& extension_id,
       const extensions::api::file_manager_private::FileTransferStatus&
           status) = 0;
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
index 6fd032268..192f0e1 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/macros.h"
+#include "base/strings/strcat.h"
 #include "chrome/common/extensions/api/file_manager_private.h"
 #include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -62,8 +63,20 @@
  public:
   TestDriveFsEventRouter() = default;
 
-  MOCK_METHOD1(DispatchOnFileTransfersUpdatedEvent,
-               void(const FileTransferStatus& status));
+  MOCK_METHOD2(DispatchOnFileTransfersUpdatedEventToExtension,
+               void(const std::string& extension_id,
+                    const FileTransferStatus& status));
+
+  GURL ConvertDrivePathToFileSystemUrl(
+      const base::FilePath& file_path,
+      const std::string& extension_id) override {
+    return GURL(base::StrCat({extension_id, ":", file_path.value()}));
+  }
+
+  std::set<std::string> GetFileTransfersUpdateEventListenerExtensionIds()
+      override {
+    return std::set<std::string>{"ext"};
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestDriveFsEventRouter);
@@ -85,12 +98,16 @@
 TEST_F(DriveFsEventRouterTest, Basic) {
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "a", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 50, 200, 2)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:a", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                     50, 200, 2)));
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 50, 200, 2)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                     50, 200, 2)));
 
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
@@ -103,10 +120,11 @@
 }
 
 TEST_F(DriveFsEventRouterTest, EmptyStatus) {
-  EXPECT_CALL(
-      mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
+  EXPECT_CALL(mock(),
+              DispatchOnFileTransfersUpdatedEventToExtension(
+                  "ext", MatchFileTransferStatus(
+                             "", file_manager_private::TRANSFER_STATE_COMPLETED,
+                             0, 0, 0)));
 
   drivefs::mojom::SyncingStatus syncing_status;
   observer().OnSyncingStatusUpdate(syncing_status);
@@ -120,7 +138,8 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(4);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(4);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   syncing_status.item_events.clear();
@@ -133,10 +152,11 @@
   observer().OnSyncingStatusUpdate(syncing_status);
   testing::Mock::VerifyAndClear(&observer());
 
-  EXPECT_CALL(
-      mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
+  EXPECT_CALL(mock(),
+              DispatchOnFileTransfersUpdatedEventToExtension(
+                  "ext", MatchFileTransferStatus(
+                             "", file_manager_private::TRANSFER_STATE_COMPLETED,
+                             0, 0, 0)));
 
   syncing_status.item_events.clear();
   observer().OnSyncingStatusUpdate(syncing_status);
@@ -145,8 +165,10 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "c", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 60, 70, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:c", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                     60, 70, 1)));
 
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "c", drivefs::mojom::ItemEvent::State::kInProgress,
@@ -159,7 +181,8 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(2);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(2);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   syncing_status.item_events.clear();
@@ -172,8 +195,10 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "a", file_manager_private::TRANSFER_STATE_FAILED, 100, 100, 0)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:a", file_manager_private::TRANSFER_STATE_FAILED, 100,
+                     100, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kFailed, -1,
@@ -186,7 +211,8 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(2);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(2);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   syncing_status.item_events.clear();
@@ -199,8 +225,10 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "a", file_manager_private::TRANSFER_STATE_COMPLETED, 100, 100, 0)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                     100, 100, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
@@ -216,19 +244,24 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(2);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(2);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClear(&observer());
 
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "a", file_manager_private::TRANSFER_STATE_COMPLETED, 110, 200, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                     110, 200, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 110, 200, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                     110, 200, 1)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
@@ -247,19 +280,24 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(2);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(2);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClear(&observer());
 
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "a", file_manager_private::TRANSFER_STATE_COMPLETED, 110, 200, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                     110, 200, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 110, 200, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                     110, 200, 1)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
@@ -275,19 +313,24 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(1);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(1);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClear(&observer());
 
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "a", file_manager_private::TRANSFER_STATE_COMPLETED, 110, 200, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                     110, 200, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 110, 200, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                     110, 200, 1)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
@@ -303,7 +346,8 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(2);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(2);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   syncing_status.item_events.clear();
@@ -314,10 +358,11 @@
 
   testing::Mock::VerifyAndClear(&observer());
 
-  EXPECT_CALL(
-      mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
+  EXPECT_CALL(mock(),
+              DispatchOnFileTransfersUpdatedEventToExtension(
+                  "ext", MatchFileTransferStatus(
+                             "", file_manager_private::TRANSFER_STATE_COMPLETED,
+                             0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
@@ -330,12 +375,13 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100);
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_)).Times(1);
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _))
+      .Times(1);
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClear(&observer());
 
-  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEvent(_));
+  EXPECT_CALL(mock(), DispatchOnFileTransfersUpdatedEventToExtension("ext", _));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
@@ -346,8 +392,10 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 10, 500, 1)));
+      DispatchOnFileTransfersUpdatedEventToExtension(
+          "ext", MatchFileTransferStatus(
+                     "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                     10, 500, 1)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kInProgress,
@@ -363,10 +411,11 @@
 
   testing::Mock::VerifyAndClear(&observer());
 
-  EXPECT_CALL(
-      mock(),
-      DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-          "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
+  EXPECT_CALL(mock(),
+              DispatchOnFileTransfersUpdatedEventToExtension(
+                  "ext", MatchFileTransferStatus(
+                             "", file_manager_private::TRANSFER_STATE_COMPLETED,
+                             0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
@@ -376,8 +425,10 @@
 
 TEST_F(DriveFsEventRouterTest, OnUnmounted) {
   EXPECT_CALL(mock(),
-              DispatchOnFileTransfersUpdatedEvent(MatchFileTransferStatus(
-                  "", file_manager_private::TRANSFER_STATE_FAILED, 0, 0, 0)));
+              DispatchOnFileTransfersUpdatedEventToExtension(
+                  "ext", MatchFileTransferStatus(
+                             "", file_manager_private::TRANSFER_STATE_FAILED, 0,
+                             0, 0)));
 
   observer().OnUnmounted();
 }
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
index 717ec65..c5daec5 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -390,9 +390,42 @@
   explicit DriveFsEventRouterImpl(Profile* profile) : profile_(profile) {}
 
  private:
-  void DispatchOnFileTransfersUpdatedEvent(
+  std::set<std::string> GetFileTransfersUpdateEventListenerExtensionIds()
+      override {
+    const extensions::EventListenerMap::ListenerList& listeners =
+        extensions::EventRouter::Get(profile_)
+            ->listeners()
+            .GetEventListenersByName(
+                file_manager_private::OnFileTransfersUpdated::kEventName);
+
+    std::set<std::string> extension_ids;
+
+    for (const auto& listener : listeners) {
+      extension_ids.insert(listener->extension_id());
+    }
+
+    return extension_ids;
+  }
+
+  GURL ConvertDrivePathToFileSystemUrl(
+      const base::FilePath& file_path,
+      const std::string& extension_id) override {
+    GURL url;
+    file_manager::util::ConvertAbsoluteFilePathToFileSystemUrl(
+        profile_,
+        base::FilePath(DriveIntegrationServiceFactory::FindForProfile(profile_)
+                           ->GetMountPointPath()
+                           .value() +
+                       file_path.value()),
+        extension_id, &url);
+    return url;
+  }
+
+  void DispatchOnFileTransfersUpdatedEventToExtension(
+      const std::string& extension_id,
       const file_manager_private::FileTransferStatus& status) override {
-    extensions::EventRouter::Get(profile_)->BroadcastEvent(
+    extensions::EventRouter::Get(profile_)->DispatchEventToExtension(
+        extension_id,
         std::make_unique<extensions::Event>(
             extensions::events::FILE_MANAGER_PRIVATE_ON_FILE_TRANSFERS_UPDATED,
             file_manager_private::OnFileTransfersUpdated::kEventName,
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index eb7d4fd3..ec164bfe 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -168,11 +168,8 @@
     ::testing::Values(TestCase("audioOpenCloseDownloads"),
                       TestCase("audioOpenCloseDownloads").InGuestMode(),
                       TestCase("audioOpenCloseDrive"),
-// Flaky on Linux ChromiumOS MSan. http://crbug.com/859008.
-#if !(defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER))
                       TestCase("audioOpenDownloads").InGuestMode(),
                       TestCase("audioOpenDownloads"),
-#endif
                       TestCase("audioOpenDrive"),
                       TestCase("audioOpenDrive").EnableDriveFs(),
                       TestCase("audioAutoAdvanceDrive"),
@@ -252,6 +249,8 @@
                       TestCase("checkPasteIntoFolderEnabledForReadWriteFolder"),
                       TestCase("checkPasteIntoFolderDisabledForReadOnlyFolder"),
                       TestCase("checkContextMenusForInputElements"),
+                      TestCase("checkNewFolderEnabledInsideReadWriteFolder"),
+                      TestCase("checkNewFolderDisabledInsideReadOnlyFolder"),
                       TestCase("checkPasteEnabledInsideReadWriteFolder"),
                       TestCase("checkPasteDisabledInsideReadOnlyFolder"),
                       TestCase("checkCopyEnabledForReadWriteFolderInTree"),
@@ -331,7 +330,13 @@
                       TestCase("transferFromSharedToDownloads"),
                       TestCase("transferFromSharedToDrive"),
                       TestCase("transferFromOfflineToDownloads"),
-                      TestCase("transferFromOfflineToDrive")));
+                      TestCase("transferFromOfflineToDrive"),
+                      TestCase("transferFromTeamDriveToDrive"),
+                      TestCase("transferFromDriveToTeamDrive"),
+                      TestCase("transferFromTeamDriveToDownloads"),
+                      TestCase("transferHostedFileFromTeamDriveToDownloads"),
+                      TestCase("transferFromDownloadsToTeamDrive"),
+                      TestCase("transferBetweenTeamDrives")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
     RestorePrefs, /* restore_prefs.js */
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
index 17bd562c..a283449 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -579,12 +579,22 @@
     ASSERT_TRUE(parent_entry);
 
     // Create the capabilities object.
-    google_apis::FileResourceCapabilities capabilities;
-    capabilities.set_can_copy(entry.capabilities.can_copy);
-    capabilities.set_can_delete(entry.capabilities.can_delete);
-    capabilities.set_can_rename(entry.capabilities.can_rename);
-    capabilities.set_can_add_children(entry.capabilities.can_add_children);
-    capabilities.set_can_share(entry.capabilities.can_share);
+    google_apis::FileResourceCapabilities file_capabilities;
+    file_capabilities.set_can_copy(entry.capabilities.can_copy);
+    file_capabilities.set_can_delete(entry.capabilities.can_delete);
+    file_capabilities.set_can_rename(entry.capabilities.can_rename);
+    file_capabilities.set_can_add_children(entry.capabilities.can_add_children);
+    file_capabilities.set_can_share(entry.capabilities.can_share);
+
+    google_apis::TeamDriveCapabilities team_drive_capabilities;
+    team_drive_capabilities.set_can_copy(entry.capabilities.can_copy);
+    team_drive_capabilities.set_can_delete_team_drive(
+        entry.capabilities.can_delete);
+    team_drive_capabilities.set_can_rename_team_drive(
+        entry.capabilities.can_rename);
+    team_drive_capabilities.set_can_add_children(
+        entry.capabilities.can_add_children);
+    team_drive_capabilities.set_can_share(entry.capabilities.can_share);
 
     // Add the file or directory entry.
     switch (entry.type) {
@@ -592,14 +602,14 @@
         CreateFile(entry.source_file_name, parent_entry->resource_id(),
                    target_name, entry.mime_type,
                    entry.shared_option == AddEntriesMessage::SHARED,
-                   entry.last_modified_time, capabilities);
+                   entry.last_modified_time, file_capabilities);
         break;
       case AddEntriesMessage::DIRECTORY:
         CreateDirectory(parent_entry->resource_id(), target_name,
-                        entry.last_modified_time, capabilities);
+                        entry.last_modified_time, file_capabilities);
         break;
       case AddEntriesMessage::TEAM_DRIVE:
-        CreateTeamDrive(entry.team_drive_name);
+        CreateTeamDrive(entry.team_drive_name, team_drive_capabilities);
         break;
     }
 
@@ -609,9 +619,12 @@
     content::RunAllTasksUntilIdle();
   }
 
-  // Creates a new Team Drive with ID |name| and name |name|.
-  void CreateTeamDrive(const std::string& name) {
+  // Creates a new Team Drive with ID |name| and name |name|, and sets the
+  // capabilities to |capabilities|.
+  void CreateTeamDrive(const std::string& name,
+                       google_apis::TeamDriveCapabilities capabilities) {
     fake_drive_service_->AddTeamDrive(name, name);
+    fake_drive_service_->SetTeamDriveCapabilities(name, capabilities);
   }
 
   // Creates an empty directory with the given |name| and |modification_time|.
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 3eeead6a..781da8e 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -1298,33 +1298,31 @@
       GrantPermissions(extension);
   }
 
+  // TODO(crbug.com/860198): Before M48, extensions that came to us from sync in
+  // a disabled state got assigned disable_reason::DISABLE_UNKNOWN_FROM_SYNC.
+  // That reason isn't used anymore since the actual disable reason(s) are now
+  // synced. This code is here to migrate any existing old state.
+  if (disable_reasons & disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC) {
+    // Remove the disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC
+    // reason.
+    disable_reasons &= ~disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC;
+    extension_prefs_->RemoveDisableReason(
+        extension->id(), disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC);
+    // If there was no privilege increase, it was likely disabled by the user.
+    // (If there *was* a privilege increase, we'll add an appropriate reason
+    // later on, so nothing needs to be done here.)
+    if (!is_privilege_increase)
+      disable_reasons |= disable_reason::DISABLE_USER_ACTION;
+  }
+
   bool previously_disabled =
       extension_prefs_->IsExtensionDisabled(extension->id());
-  // TODO(treib): Is the |is_extension_loaded| check needed here?
+  // TODO(devlin): Is the |is_extension_loaded| check needed here?
   if (is_extension_loaded && previously_disabled) {
     // Legacy disabled extensions do not have a disable reason. Infer that it
     // was likely disabled by the user.
     if (disable_reasons == disable_reason::DISABLE_NONE)
       disable_reasons |= disable_reason::DISABLE_USER_ACTION;
-
-    // Extensions that came to us disabled from sync need a similar inference,
-    // except based on the new version's permissions.
-    // TODO(treib,devlin): Since M48,
-    // disable_reason::DISABLE_UNKNOWN_FROM_SYNC isn't used anymore;
-    // this code is still here to migrate any existing old state. Remove it
-    // after some grace period.
-    if (disable_reasons &
-        disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC) {
-      // Remove the disable_reason::DISABLE_UNKNOWN_FROM_SYNC
-      // reason.
-      disable_reasons &= ~disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC;
-      extension_prefs_->RemoveDisableReason(
-          extension->id(),
-          disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC);
-      // If there was no privilege increase, it was likely disabled by the user.
-      if (!is_privilege_increase)
-        disable_reasons |= disable_reason::DISABLE_USER_ACTION;
-    }
   }
 
   // If the extension is disabled due to a permissions increase, but does in
diff --git a/chrome/browser/extensions/external_pref_loader_unittest.cc b/chrome/browser/extensions/external_pref_loader_unittest.cc
index 8f0cc3caf..20aa6b7 100644
--- a/chrome/browser/extensions/external_pref_loader_unittest.cc
+++ b/chrome/browser/extensions/external_pref_loader_unittest.cc
@@ -29,8 +29,8 @@
   ~TestSyncService() override {}
 
   // FakeSyncService:
+  int GetDisableReasons() const override { return disable_reasons_; }
   bool IsFirstSetupComplete() const override { return true; }
-  bool IsSyncAllowed() const override { return true; }
   bool IsSyncActive() const override { return true; }
   syncer::ModelTypeSet GetActiveDataTypes() const override {
     switch (synced_types_) {
@@ -42,7 +42,6 @@
     NOTREACHED();
     return syncer::ModelTypeSet();
   }
-  bool CanSyncStart() const override { return can_sync_start_; }
   void AddObserver(syncer::SyncServiceObserver* observer) override {
     ASSERT_FALSE(observer_);
     observer_ = observer;
@@ -51,7 +50,9 @@
     EXPECT_EQ(observer_, observer);
   }
 
-  void set_can_sync_start(bool value) { can_sync_start_ = value; }
+  void SetDisableReasons(int disable_reasons) {
+    disable_reasons_ = disable_reasons;
+  }
 
   void FireOnStateChanged(browser_sync::ProfileSyncService* service) {
     ASSERT_TRUE(observer_);
@@ -60,7 +61,7 @@
 
  private:
   syncer::SyncServiceObserver* observer_ = nullptr;
-  bool can_sync_start_ = true;
+  int disable_reasons_ = DISABLE_REASON_NONE;
 
   SyncedTypes synced_types_;
   DISALLOW_COPY_AND_ASSIGN(TestSyncService);
@@ -135,7 +136,9 @@
 
   // Initially CanSyncStart() returns true, returning false will let |loader|
   // proceed.
-  test_service->set_can_sync_start(false);
+  test_service->SetDisableReasons(
+      syncer::SyncService::DISABLE_REASON_USER_CHOICE);
+  ASSERT_FALSE(test_service->CanSyncStart());
   test_service->FireOnStateChanged(test_service);
   run_loop.Run();
 }
diff --git a/chrome/browser/media/media_engagement_browsertest.cc b/chrome/browser/media/media_engagement_browsertest.cc
index 824a94d..db452a6c 100644
--- a/chrome/browser/media/media_engagement_browsertest.cc
+++ b/chrome/browser/media/media_engagement_browsertest.cc
@@ -58,14 +58,13 @@
   // |web_contents| must be non-NULL and needs to stay alive for the
   // entire lifetime of |this|.
   explicit WasRecentlyAudibleWatcher(content::WebContents* web_contents)
-      : audible_helper_(RecentlyAudibleHelper::FromWebContents(web_contents)),
-        timer_(new base::Timer(true, true)) {}
+      : audible_helper_(RecentlyAudibleHelper::FromWebContents(web_contents)) {}
   ~WasRecentlyAudibleWatcher() = default;
 
   // Waits until WasRecentlyAudible is true.
   void WaitForWasRecentlyAudible() {
     if (!audible_helper_->WasRecentlyAudible()) {
-      timer_->Start(
+      timer_.Start(
           FROM_HERE, base::TimeDelta::FromMicroseconds(100),
           base::Bind(&WasRecentlyAudibleWatcher::TestWasRecentlyAudible,
                      base::Unretained(this)));
@@ -78,13 +77,13 @@
   void TestWasRecentlyAudible() {
     if (audible_helper_->WasRecentlyAudible()) {
       run_loop_->Quit();
-      timer_->Stop();
+      timer_.Stop();
     }
   }
 
   RecentlyAudibleHelper* const audible_helper_;
 
-  std::unique_ptr<base::Timer> timer_;
+  base::RepeatingTimer timer_;
   std::unique_ptr<base::RunLoop> run_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(WasRecentlyAudibleWatcher);
diff --git a/chrome/browser/media/media_engagement_contents_observer.cc b/chrome/browser/media/media_engagement_contents_observer.cc
index 312680e5..af6453da 100644
--- a/chrome/browser/media/media_engagement_contents_observer.cc
+++ b/chrome/browser/media/media_engagement_contents_observer.cc
@@ -76,7 +76,6 @@
     MediaEngagementService* service)
     : WebContentsObserver(web_contents),
       service_(service),
-      playback_timer_(new base::Timer(true, false)),
       task_runner_(nullptr) {}
 
 MediaEngagementContentsObserver::~MediaEngagementContentsObserver() = default;
@@ -120,7 +119,7 @@
 }
 
 void MediaEngagementContentsObserver::ClearPlayerStates() {
-  playback_timer_->Stop();
+  playback_timer_.Stop();
   player_states_.clear();
   significant_players_.clear();
 }
@@ -398,8 +397,7 @@
   if (state.muted == false && state.playing == true &&
       state.has_audio == true &&
       audible_players_.find(id) == audible_players_.end()) {
-    audible_players_[id] =
-        std::make_pair(false, base::WrapUnique<base::Timer>(nullptr));
+    audible_players_[id] = std::make_pair(false, nullptr);
   }
 
   bool is_currently_significant =
@@ -450,8 +448,7 @@
     if (audible_row->second.second)
       return;
 
-    std::unique_ptr<base::Timer> new_timer =
-        std::make_unique<base::Timer>(true, false);
+    auto new_timer = std::make_unique<base::OneShotTimer>();
     if (task_runner_)
       new_timer->SetTaskRunner(task_runner_);
 
@@ -481,22 +478,22 @@
     return;
 
   if (AreConditionsMet()) {
-    if (playback_timer_->IsRunning())
+    if (playback_timer_.IsRunning())
       return;
 
     if (task_runner_)
-      playback_timer_->SetTaskRunner(task_runner_);
+      playback_timer_.SetTaskRunner(task_runner_);
 
-    playback_timer_->Start(
+    playback_timer_.Start(
         FROM_HERE,
         MediaEngagementContentsObserver::kSignificantMediaPlaybackTime,
         base::Bind(&MediaEngagementContentsObserver::
                        OnSignificantMediaPlaybackTimeForPage,
                    base::Unretained(this)));
   } else {
-    if (!playback_timer_->IsRunning())
+    if (!playback_timer_.IsRunning())
       return;
-    playback_timer_->Stop();
+    playback_timer_.Stop();
   }
 }
 
diff --git a/chrome/browser/media/media_engagement_contents_observer.h b/chrome/browser/media/media_engagement_contents_observer.h
index 03d25641..d529ce5 100644
--- a/chrome/browser/media/media_engagement_contents_observer.h
+++ b/chrome/browser/media/media_engagement_contents_observer.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_CONTENTS_OBSERVER_H_
 #define CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_CONTENTS_OBSERVER_H_
 
+#include "base/timer/timer.h"
 #include "content/public/browser/web_contents_observer.h"
 
 namespace base {
@@ -106,7 +107,7 @@
 
   // Timer that will fire when the playback time reaches the minimum for
   // significant media playback.
-  std::unique_ptr<base::Timer> playback_timer_;
+  base::OneShotTimer playback_timer_;
 
   // Set of active players that can produce a significant playback. In other
   // words, whether this set is empty can be used to know if there is a
@@ -216,7 +217,7 @@
 
   // Stores the ids of the players that were audible. The boolean will be true
   // if the player was significant.
-  using AudiblePlayerRow = std::pair<bool, std::unique_ptr<base::Timer>>;
+  using AudiblePlayerRow = std::pair<bool, std::unique_ptr<base::OneShotTimer>>;
   std::map<MediaPlayerId, AudiblePlayerRow> audible_players_;
 
   // The task runner to use when creating timers. It is used only for testing.
diff --git a/chrome/browser/media/media_engagement_contents_observer_unittest.cc b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
index bb22a41..e8c6511 100644
--- a/chrome/browser/media/media_engagement_contents_observer_unittest.cc
+++ b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
@@ -78,7 +78,7 @@
   }
 
   bool IsTimerRunning() const {
-    return contents_observer_->playback_timer_->IsRunning();
+    return contents_observer_->playback_timer_.IsRunning();
   }
 
   bool IsTimerRunningForPlayer(int id) const {
diff --git a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
index 5fea5ca..8ea3b51 100644
--- a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
+++ b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
@@ -47,6 +47,7 @@
           WebFeature::kCSSEnvironmentVariable_SafeAreaInsetRight,
           WebFeature::kCSSEnvironmentVariable_SafeAreaInsetBottom,
           WebFeature::kMediaControlsDisplayCutoutGesture,
+          WebFeature::kPolymerV1Detected, WebFeature::kPolymerV2Detected,
       }));
   return opt_in_features.count(feature);
 }
diff --git a/chrome/browser/resources/chromeos/drive_internals.html b/chrome/browser/resources/chromeos/drive_internals.html
index ee0b852..d0e0ae0 100644
--- a/chrome/browser/resources/chromeos/drive_internals.html
+++ b/chrome/browser/resources/chromeos/drive_internals.html
@@ -58,6 +58,7 @@
       <tbody id="delta-update-status">
         <tr>
           <th>Source</th>
+          <th>Virtual Path</th>
           <th>Start Page Token</th>
           <th>Last Update Check Time</th>
           <th>Last Update Check Result</th>
diff --git a/chrome/browser/resources/chromeos/drive_internals.js b/chrome/browser/resources/chromeos/drive_internals.js
index b606fab..b49c598a 100644
--- a/chrome/browser/resources/chromeos/drive_internals.js
+++ b/chrome/browser/resources/chromeos/drive_internals.js
@@ -199,6 +199,7 @@
     var tr = document.createElement('tr');
     tr.className = 'delta-update';
     tr.appendChild(createElementFromText('td', update.id));
+    tr.appendChild(createElementFromText('td', update.root_entry_path));
     var startPageToken = update.start_page_token;
     tr.appendChild(createElementFromText(
         'td',
diff --git a/chrome/browser/resources/settings/reset_page/reset_page.js b/chrome/browser/resources/settings/reset_page/reset_page.js
index 538830d8..8bf342f 100644
--- a/chrome/browser/resources/settings/reset_page/reset_page.js
+++ b/chrome/browser/resources/settings/reset_page/reset_page.js
@@ -21,8 +21,8 @@
   behaviors: [settings.RouteObserverBehavior],
 
   properties: {
-    /** Preferences state. */

-    prefs: Object,

+    /** Preferences state. */
+    prefs: Object,
 
     // <if expr="chromeos">
     /** @private */
diff --git a/chrome/browser/safe_browsing/download_protection/DEPS b/chrome/browser/safe_browsing/download_protection/DEPS
index 504a3d3..0c3c5ceb 100644
--- a/chrome/browser/safe_browsing/download_protection/DEPS
+++ b/chrome/browser/safe_browsing/download_protection/DEPS
@@ -1,5 +1,5 @@
-specific_include_rules = {

-  ".*test\.cc": [

-    "+services/network/network_context.h",

-  ]

-}

+specific_include_rules = {
+  ".*test\.cc": [
+    "+services/network/network_context.h",
+  ]
+}
diff --git a/chrome/browser/safe_browsing/incident_reporting/DEPS b/chrome/browser/safe_browsing/incident_reporting/DEPS
index 1c366cbb..058d172 100644
--- a/chrome/browser/safe_browsing/incident_reporting/DEPS
+++ b/chrome/browser/safe_browsing/incident_reporting/DEPS
@@ -1,5 +1,5 @@
-specific_include_rules = {

-  ".*test\.cc": [

-    "+services/network/test",

-  ]

-}

+specific_include_rules = {
+  ".*test\.cc": [
+    "+services/network/test",
+  ]
+}
diff --git a/chrome/browser/sync/sync_startup_tracker_unittest.cc b/chrome/browser/sync/sync_startup_tracker_unittest.cc
index c1b53d5..d60026f 100644
--- a/chrome/browser/sync/sync_startup_tracker_unittest.cc
+++ b/chrome/browser/sync/sync_startup_tracker_unittest.cc
@@ -56,9 +56,8 @@
         .WillRepeatedly(ReturnRef(no_error_));
     EXPECT_CALL(*mock_pss_, IsEngineInitialized())
         .WillRepeatedly(Return(false));
-    EXPECT_CALL(*mock_pss_, HasUnrecoverableError())
-        .WillRepeatedly(Return(false));
-    EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_pss_, GetDisableReasons())
+        .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   }
 
   content::TestBrowserThreadBundle thread_bundle_;
@@ -70,7 +69,8 @@
 
 TEST_F(SyncStartupTrackerTest, SyncAlreadyInitialized) {
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   EXPECT_CALL(observer_, SyncStartupCompleted());
   SyncStartupTracker tracker(profile_.get(), &observer_);
 }
@@ -79,7 +79,9 @@
   // Make sure that we get a SyncStartupFailed() callback if sync is not logged
   // in.
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN));
   EXPECT_CALL(observer_, SyncStartupFailed());
   SyncStartupTracker tracker(profile_.get(), &observer_);
 }
@@ -88,7 +90,8 @@
   // Make sure that we get a SyncStartupFailed() callback if sync gets an auth
   // error.
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error));
@@ -120,7 +123,8 @@
 
   // Now, mark the PSS as having an auth error.
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error));
@@ -139,7 +143,8 @@
 
   // Now, mark the PSS as having an unrecoverable error.
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   GoogleServiceAuthError error(
       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
   EXPECT_CALL(*mock_pss_, GetAuthError()).WillRepeatedly(ReturnRef(error));
diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc
index dd7e0d8a..ee9e068 100644
--- a/chrome/browser/sync/sync_ui_util_unittest.cc
+++ b/chrome/browser/sync/sync_ui_util_unittest.cc
@@ -123,8 +123,9 @@
           .WillRepeatedly(Return(false));
       EXPECT_CALL(*service, IsFirstSetupInProgress())
           .WillRepeatedly(Return(false));
-      EXPECT_CALL(*service, HasUnrecoverableError())
-          .WillRepeatedly(Return(true));
+      EXPECT_CALL(*service, GetDisableReasons())
+          .WillRepeatedly(
+              Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));
       syncer::SyncEngine::Status status;
       EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
           .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
@@ -139,8 +140,8 @@
       syncer::SyncEngine::Status status;
       EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
           .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
-      EXPECT_CALL(*service, HasUnrecoverableError())
-          .WillRepeatedly(Return(false));
+      EXPECT_CALL(*service, GetDisableReasons())
+          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
       signin->set_auth_in_progress();
       return;
     }
@@ -160,8 +161,8 @@
       token_service->GetDelegate()->UpdateAuthError(
           account_id,
           GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
-      EXPECT_CALL(*service, HasUnrecoverableError())
-          .WillRepeatedly(Return(false));
+      EXPECT_CALL(*service, GetDisableReasons())
+          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
       return;
     }
     case STATUS_CASE_PROTOCOL_ERROR: {
@@ -176,8 +177,8 @@
       status.sync_protocol_error = protocolError;
       EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
           .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
-      EXPECT_CALL(*service, HasUnrecoverableError())
-          .WillRepeatedly(Return(false));
+      EXPECT_CALL(*service, GetDisableReasons())
+          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
       return;
     }
     case STATUS_CASE_CONFIRM_SYNC_SETTINGS: {
@@ -197,8 +198,8 @@
       syncer::SyncEngine::Status status;
       EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
           .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
-      EXPECT_CALL(*service, HasUnrecoverableError())
-          .WillRepeatedly(Return(false));
+      EXPECT_CALL(*service, GetDisableReasons())
+          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
       EXPECT_CALL(*service, IsPassphraseRequired())
           .WillRepeatedly(Return(true));
       EXPECT_CALL(*service, IsPassphraseRequiredForDecryption())
@@ -214,14 +215,16 @@
       syncer::SyncEngine::Status status;
       EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
           .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
-      EXPECT_CALL(*service, HasUnrecoverableError())
-          .WillRepeatedly(Return(false));
+      EXPECT_CALL(*service, GetDisableReasons())
+          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
       EXPECT_CALL(*service, IsPassphraseRequired())
           .WillRepeatedly(Return(false));
       return;
     }
     case STATUS_CASE_SYNC_DISABLED_BY_POLICY: {
-      EXPECT_CALL(*service, IsManaged()).WillRepeatedly(Return(true));
+      EXPECT_CALL(*service, GetDisableReasons())
+          .WillRepeatedly(
+              Return(syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY));
       EXPECT_CALL(*service, IsFirstSetupComplete())
           .WillRepeatedly(Return(false));
       EXPECT_CALL(*service, IsSyncActive()).WillRepeatedly(Return(false));
@@ -230,8 +233,6 @@
       syncer::SyncEngine::Status status;
       EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
           .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
-      EXPECT_CALL(*service, HasUnrecoverableError())
-          .WillRepeatedly(Return(false));
       return;
     }
     default:
@@ -353,7 +354,9 @@
   ProfileSyncServiceMock service(
       CreateProfileSyncServiceParamsForTest(profile.get()));
   EXPECT_CALL(service, IsFirstSetupComplete()).WillRepeatedly(Return(true));
-  EXPECT_CALL(service, HasUnrecoverableError()).WillRepeatedly(Return(true));
+  EXPECT_CALL(service, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));
 
   // First time action is not set. We should get unrecoverable error.
   syncer::SyncStatus status;
@@ -395,7 +398,9 @@
   ProfileSyncServiceMock service(
       CreateProfileSyncServiceParamsForTest(profile.get()));
   EXPECT_CALL(service, IsFirstSetupComplete()).WillRepeatedly(Return(true));
-  EXPECT_CALL(service, HasUnrecoverableError()).WillRepeatedly(Return(true));
+  EXPECT_CALL(service, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));
 
   // Set action to UPGRADE_CLIENT.
   syncer::SyncStatus status;
diff --git a/chrome/browser/sync/test/integration/performance/autofill_sync_perf_test.cc b/chrome/browser/sync/test/integration/performance/autofill_sync_perf_test.cc
index 9776f25..bb7dbec 100644
--- a/chrome/browser/sync/test/integration/performance/autofill_sync_perf_test.cc
+++ b/chrome/browser/sync/test/integration/performance/autofill_sync_perf_test.cc
@@ -15,6 +15,9 @@
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/webdata/autofill_entry.h"
+#include "components/sync/driver/sync_driver_switches.h"
+
+namespace {
 
 using autofill::ServerFieldType;
 using autofill::AutofillKey;
@@ -36,13 +39,40 @@
 static const int kNumKeys = 163;
 static const int kNumProfiles = 163;
 
-class AutofillSyncPerfTest : public SyncTest {
+std::string IntToName(int n) {
+  return base::StringPrintf("Name%d", n);
+}
+
+void ForceSync(int profile) {
+  static int id = 0;
+  ++id;
+  EXPECT_TRUE(bookmarks_helper::AddURL(
+                  profile, 0, bookmarks_helper::IndexedURLTitle(id),
+                  GURL(bookmarks_helper::IndexedURL(id))) != nullptr);
+}
+
+// Class that enables or disables USS based on test parameter. Must be the first
+// base class of the test fixture.
+class UssSwitchToggler : public testing::WithParamInterface<bool> {
  public:
-  AutofillSyncPerfTest()
-      : SyncTest(TWO_CLIENT),
-        guid_number_(0),
-        name_number_(0),
-        value_number_(0) {}
+  UssSwitchToggler() {
+    if (GetParam()) {
+      override_features_.InitAndEnableFeature(
+          switches::kSyncUSSAutofillProfile);
+    } else {
+      override_features_.InitAndDisableFeature(
+          switches::kSyncUSSAutofillProfile);
+    }
+  }
+
+ private:
+  base::test::ScopedFeatureList override_features_;
+};
+
+class AutofillProfileSyncPerfTest : public UssSwitchToggler, public SyncTest {
+ public:
+  AutofillProfileSyncPerfTest()
+      : SyncTest(TWO_CLIENT), guid_number_(0), name_number_(0) {}
 
   // Adds |num_profiles| new autofill profiles to the sync profile |profile|.
   void AddProfiles(int profile, int num_profiles);
@@ -53,16 +83,10 @@
   // Removes all autofill profiles from |profile|.
   void RemoveProfiles(int profile);
 
-  // Adds |num_keys| new autofill keys to the sync profile |profile|.
-  void AddKeys(int profile, int num_keys);
-
  private:
   // Returns a new unique autofill profile.
   const AutofillProfile NextAutofillProfile();
 
-  // Returns a new unique autofill key.
-  const AutofillKey NextAutofillKey();
-
   // Returns an unused unique guid.
   const std::string NextGUID();
 
@@ -72,22 +96,12 @@
   // Returns a new unused unique name.
   const std::string NextName();
 
-  // Returns a unique name based on the input integer |n|.
-  const std::string IntToName(int n);
-
-  // Returns a new unused unique value for autofill entries.
-  const std::string NextValue();
-
-  // Returnes a unique value based on the input integer |n|.
-  const std::string IntToValue(int n);
-
   int guid_number_;
   int name_number_;
-  int value_number_;
-  DISALLOW_COPY_AND_ASSIGN(AutofillSyncPerfTest);
+  DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncPerfTest);
 };
 
-void AutofillSyncPerfTest::AddProfiles(int profile, int num_profiles) {
+void AutofillProfileSyncPerfTest::AddProfiles(int profile, int num_profiles) {
   const std::vector<AutofillProfile*>& all_profiles =
       GetAllAutoFillProfiles(profile);
   std::vector<AutofillProfile> autofill_profiles;
@@ -100,7 +114,7 @@
   SetProfiles(profile, &autofill_profiles);
 }
 
-void AutofillSyncPerfTest::UpdateProfiles(int profile) {
+void AutofillProfileSyncPerfTest::UpdateProfiles(int profile) {
   const std::vector<AutofillProfile*>& all_profiles =
       GetAllAutoFillProfiles(profile);
   std::vector<AutofillProfile> autofill_profiles;
@@ -112,20 +126,12 @@
   SetProfiles(profile, &autofill_profiles);
 }
 
-void AutofillSyncPerfTest::RemoveProfiles(int profile) {
+void AutofillProfileSyncPerfTest::RemoveProfiles(int profile) {
   std::vector<AutofillProfile> empty;
   SetProfiles(profile, &empty);
 }
 
-void AutofillSyncPerfTest::AddKeys(int profile, int num_keys) {
-  std::set<AutofillKey> keys;
-  for (int i = 0; i < num_keys; ++i) {
-    keys.insert(NextAutofillKey());
-  }
-  autofill_helper::AddKeys(profile, keys);
-}
-
-const AutofillProfile AutofillSyncPerfTest::NextAutofillProfile() {
+const AutofillProfile AutofillProfileSyncPerfTest::NextAutofillProfile() {
   AutofillProfile profile;
   autofill::test::SetProfileInfoWithGuid(&profile, NextGUID().c_str(),
                                          NextName().c_str(), "", "", "", "", "",
@@ -133,43 +139,19 @@
   return profile;
 }
 
-const AutofillKey AutofillSyncPerfTest::NextAutofillKey() {
-  return AutofillKey(NextName().c_str(), NextName().c_str());
-}
-
-const std::string AutofillSyncPerfTest::NextGUID() {
+const std::string AutofillProfileSyncPerfTest::NextGUID() {
   return IntToGUID(guid_number_++);
 }
 
-const std::string AutofillSyncPerfTest::IntToGUID(int n) {
+const std::string AutofillProfileSyncPerfTest::IntToGUID(int n) {
   return base::StringPrintf("00000000-0000-0000-0000-%012X", n);
 }
 
-const std::string AutofillSyncPerfTest::NextName() {
+const std::string AutofillProfileSyncPerfTest::NextName() {
   return IntToName(name_number_++);
 }
 
-const std::string AutofillSyncPerfTest::IntToName(int n) {
-  return base::StringPrintf("Name%d", n);
-}
-
-const std::string AutofillSyncPerfTest::NextValue() {
-  return IntToValue(value_number_++);
-}
-
-const std::string AutofillSyncPerfTest::IntToValue(int n) {
-  return base::StringPrintf("Value%d", n);
-}
-
-void ForceSync(int profile) {
-  static int id = 0;
-  ++id;
-  EXPECT_TRUE(bookmarks_helper::AddURL(
-                  profile, 0, bookmarks_helper::IndexedURLTitle(id),
-                  GURL(bookmarks_helper::IndexedURL(id))) != nullptr);
-}
-
-IN_PROC_BROWSER_TEST_F(AutofillSyncPerfTest, AutofillProfiles_P0) {
+IN_PROC_BROWSER_TEST_P(AutofillProfileSyncPerfTest, P0) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfiles(0, kNumProfiles);
@@ -188,7 +170,47 @@
   PrintResult("autofill", "delete_autofill_profiles", dt);
 }
 
-IN_PROC_BROWSER_TEST_F(AutofillSyncPerfTest, Autofill_P0) {
+// Only parametrize the test above that tests autofill_profile, the test below
+// addresses autocomplete and thus does not need parametrizing.
+INSTANTIATE_TEST_CASE_P(USS,
+                        AutofillProfileSyncPerfTest,
+                        ::testing::Values(false, true));
+
+class AutocompleteSyncPerfTest : public SyncTest {
+ public:
+  AutocompleteSyncPerfTest() : SyncTest(TWO_CLIENT), name_number_(0) {}
+
+  // Adds |num_keys| new autofill keys to the sync profile |profile|.
+  void AddKeys(int profile, int num_keys);
+
+ private:
+  // Returns a new unique autofill key.
+  const AutofillKey NextAutofillKey();
+
+  // Returns a new unused unique name.
+  const std::string NextName();
+
+  int name_number_;
+  DISALLOW_COPY_AND_ASSIGN(AutocompleteSyncPerfTest);
+};
+
+void AutocompleteSyncPerfTest::AddKeys(int profile, int num_keys) {
+  std::set<AutofillKey> keys;
+  for (int i = 0; i < num_keys; ++i) {
+    keys.insert(NextAutofillKey());
+  }
+  autofill_helper::AddKeys(profile, keys);
+}
+
+const AutofillKey AutocompleteSyncPerfTest::NextAutofillKey() {
+  return AutofillKey(NextName().c_str(), NextName().c_str());
+}
+
+const std::string AutocompleteSyncPerfTest::NextName() {
+  return IntToName(name_number_++);
+}
+
+IN_PROC_BROWSER_TEST_F(AutocompleteSyncPerfTest, P0) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddKeys(0, kNumKeys);
@@ -205,3 +227,5 @@
   ASSERT_EQ(0, GetKeyCount(1));
   PrintResult("autofill", "delete_autofill_keys", dt);
 }
+
+}  // namespace
diff --git a/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc b/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc
index f2213c4..7e07a34 100644
--- a/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_autofill_sync_test.cc
@@ -5,6 +5,7 @@
 
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/sync/test/integration/autofill_helper.h"
 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
@@ -14,6 +15,10 @@
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/webdata/autofill_entry.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/sync/driver/sync_driver_switches.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
 
 using autofill::AutofillKey;
 using autofill::AutofillTable;
@@ -44,18 +49,18 @@
 using bookmarks_helper::IndexedURL;
 using bookmarks_helper::IndexedURLTitle;
 
-class TwoClientAutofillSyncTest : public SyncTest {
+class TwoClientAutocompleteSyncTest : public SyncTest {
  public:
-  TwoClientAutofillSyncTest() : SyncTest(TWO_CLIENT) {}
-  ~TwoClientAutofillSyncTest() override {}
+  TwoClientAutocompleteSyncTest() : SyncTest(TWO_CLIENT) {}
+  ~TwoClientAutocompleteSyncTest() override {}
 
   bool TestUsesSelfNotifications() override { return false; }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(TwoClientAutofillSyncTest);
+  DISALLOW_COPY_AND_ASSIGN(TwoClientAutocompleteSyncTest);
 };
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, WebDataServiceSanity) {
+IN_PROC_BROWSER_TEST_F(TwoClientAutocompleteSyncTest, WebDataServiceSanity) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   // Client0 adds a key.
@@ -91,7 +96,7 @@
   ASSERT_EQ(0U, GetAllKeys(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, AddUnicodeProfile) {
+IN_PROC_BROWSER_TEST_F(TwoClientAutocompleteSyncTest, AddUnicodeProfile) {
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
   std::set<AutofillKey> keys;
@@ -102,7 +107,7 @@
   ASSERT_TRUE(AutofillKeysChecker(0, 1).Wait());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest,
+IN_PROC_BROWSER_TEST_F(TwoClientAutocompleteSyncTest,
                        AddDuplicateNamesToSameProfile) {
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
@@ -116,7 +121,7 @@
   ASSERT_EQ(2U, GetAllKeys(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest,
+IN_PROC_BROWSER_TEST_F(TwoClientAutocompleteSyncTest,
                        AddDuplicateNamesToDifferentProfiles) {
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
@@ -136,7 +141,39 @@
   ASSERT_EQ(5U, GetAllKeys(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest,
+// Class that enables or disables USS based on test parameter. Must be the first
+// base class of the test fixture.
+// TODO(jkrcal): When the new implementation fully launches, remove this class,
+// convert all tests from *_P back to *_F and remove the instance at the end.
+class UssSwitchToggler : public testing::WithParamInterface<bool> {
+ public:
+  UssSwitchToggler() {
+    if (GetParam()) {
+      override_features_.InitAndEnableFeature(
+          switches::kSyncUSSAutofillProfile);
+    } else {
+      override_features_.InitAndDisableFeature(
+          switches::kSyncUSSAutofillProfile);
+    }
+  }
+
+ private:
+  base::test::ScopedFeatureList override_features_;
+};
+
+class TwoClientAutofillProfileSyncTest : public UssSwitchToggler,
+                                         public SyncTest {
+ public:
+  TwoClientAutofillProfileSyncTest() : SyncTest(TWO_CLIENT) {}
+  ~TwoClientAutofillProfileSyncTest() override {}
+
+  bool TestUsesSelfNotifications() override { return false; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TwoClientAutofillProfileSyncTest);
+};
+
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest,
                        PersonalDataManagerSanity) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
@@ -174,7 +211,7 @@
   ASSERT_EQ(0U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, AddDuplicateProfiles) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, AddDuplicateProfiles) {
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -184,7 +221,8 @@
   ASSERT_EQ(1U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, SameProfileWithConflict) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest,
+                       SameProfileWithConflict) {
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
   AutofillProfile profile0 = CreateAutofillProfile(PROFILE_HOMER);
@@ -199,7 +237,7 @@
   ASSERT_EQ(1U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, AddEmptyProfile) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, AddEmptyProfile) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_NULL));
@@ -207,7 +245,7 @@
   ASSERT_EQ(0U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, AddProfile) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, AddProfile) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -215,7 +253,7 @@
   ASSERT_EQ(1U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, AddMultipleProfiles) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, AddMultipleProfiles) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -225,7 +263,7 @@
   ASSERT_EQ(3U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, DeleteProfile) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, DeleteProfile) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -237,7 +275,7 @@
   ASSERT_EQ(0U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, MergeProfiles) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, MergeProfiles) {
   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -248,7 +286,7 @@
   ASSERT_EQ(3U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, UpdateFields) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, UpdateFields) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -267,7 +305,7 @@
   ASSERT_EQ(1U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, ConflictingFields) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, ConflictingFields) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -288,7 +326,7 @@
   ASSERT_EQ(1U, GetAllAutoFillProfiles(0).size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, MaxLength) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, MaxLength) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -312,7 +350,7 @@
   ASSERT_TRUE(AutofillProfileChecker(0, 1).Wait());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, ExceedsMaxLength) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, ExceedsMaxLength) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   AddProfile(0, CreateAutofillProfile(PROFILE_HOMER));
@@ -343,7 +381,7 @@
 }
 
 // Test credit cards don't sync.
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest, NoCreditCardSync) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest, NoCreditCardSync) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   CreditCard card;
@@ -365,8 +403,8 @@
   ASSERT_EQ(0U, pdm->GetCreditCards().size());
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientAutofillSyncTest,
-    E2E_ONLY(TwoClientsAddAutofillProfiles)) {
+IN_PROC_BROWSER_TEST_P(TwoClientAutofillProfileSyncTest,
+                       E2E_ONLY(TwoClientsAddAutofillProfiles)) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   // All profiles should sync same autofill profiles.
@@ -389,3 +427,11 @@
         "Total autofill profile count is wrong.";
   }
 }
+
+// Only parametrize the tests above that test autofill_profile, the tests below
+// address autocomplete and thus do not need parametrizing.
+INSTANTIATE_TEST_CASE_P(USS,
+                        TwoClientAutofillProfileSyncTest,
+                        ::testing::Values(false, true));
+
+}  // namespace
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_display.cc b/chrome/browser/ui/ash/launcher/crostini_app_display.cc
index 890595f7..18f321b 100644
--- a/chrome/browser/ui/ash/launcher/crostini_app_display.cc
+++ b/chrome/browser/ui/ash/launcher/crostini_app_display.cc
@@ -3,33 +3,31 @@
 // found in the LICENSE file.
 #include "chrome/browser/ui/ash/launcher/crostini_app_display.h"
 
+#include "chrome/browser/ui/ash/shell_state_client.h"
 #include "ui/display/types/display_constants.h"
 
 CrostiniAppDisplay::CrostiniAppDisplay() = default;
 
 CrostiniAppDisplay::~CrostiniAppDisplay() = default;
 
-void CrostiniAppDisplay::Register(const std::string& startup_id,
+void CrostiniAppDisplay::Register(const std::string& app_id,
                                   int64_t display_id) {
-  while (startup_ids_.size() >= kMaxStartupIdSize) {
-    startup_id_to_display_id_.erase(startup_ids_.front());
-    startup_ids_.pop_front();
+  while (app_ids_.size() >= kMaxAppIdSize) {
+    app_id_to_display_id_.erase(app_ids_.front());
+    app_ids_.pop_front();
   }
-  auto it = startup_id_to_display_id_.find(startup_id);
-  if (it == startup_id_to_display_id_.end()) {
-    startup_id_to_display_id_.emplace(std::make_pair(startup_id, display_id));
-    startup_ids_.push_back(startup_id);
+  auto it = app_id_to_display_id_.find(app_id);
+  if (it == app_id_to_display_id_.end()) {
+    app_id_to_display_id_.emplace(std::make_pair(app_id, display_id));
+    app_ids_.push_back(app_id);
   } else {
     it->second = display_id;
   }
 }
 
-int64_t CrostiniAppDisplay::GetDisplayIdForStartupId(
-    const std::string& startup_id) {
-  auto it = startup_id_to_display_id_.find(startup_id);
-  if (it == startup_id_to_display_id_.end()) {
-    return display::kInvalidDisplayId;
-  } else {
-    return it->second;
-  }
+int64_t CrostiniAppDisplay::GetDisplayIdForAppId(const std::string& app_id) {
+  auto it = app_id_to_display_id_.find(app_id);
+  if (it == app_id_to_display_id_.end())
+    return ShellStateClient::Get()->display_id_for_new_windows();
+  return it->second;
 }
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_display.h b/chrome/browser/ui/ash/launcher/crostini_app_display.h
index 75760b14..9f12152 100644
--- a/chrome/browser/ui/ash/launcher/crostini_app_display.h
+++ b/chrome/browser/ui/ash/launcher/crostini_app_display.h
@@ -11,24 +11,24 @@
 
 #include <base/macros.h>
 
-// Manages mapping from a Crostini startup ID to a display ID.
+// Manages mapping from a Crostini app ID to a display ID.
 class CrostiniAppDisplay {
  public:
   CrostiniAppDisplay();
   ~CrostiniAppDisplay();
 
-  // Register that |startup_id| app should be shown in |display_id| monitor.
-  void Register(const std::string& startup_id, int64_t display_id);
-  // Returns the display ID that the |startup_id| app should be shown in.
-  int64_t GetDisplayIdForStartupId(const std::string& startup_id);
+  // Register that |app_id| app should be shown in |display_id| monitor.
+  void Register(const std::string& app_id, int64_t display_id);
+  // Returns the display ID that the |app_id| app should be shown in.
+  int64_t GetDisplayIdForAppId(const std::string& app_id);
 
  private:
   // Since there is no message when an app quits, maintain a maximum number so
   // that older ones are deleted.
-  const uint kMaxStartupIdSize = 32;
+  const uint kMaxAppIdSize = 32;
 
-  std::map<std::string, int64_t> startup_id_to_display_id_;
-  std::deque<std::string> startup_ids_;
+  std::map<std::string, int64_t> app_id_to_display_id_;
+  std::deque<std::string> app_ids_;
 
   DISALLOW_COPY_AND_ASSIGN(CrostiniAppDisplay);
 };
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
index 3caf19e0..4a9d0376 100644
--- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
+++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
@@ -33,6 +33,32 @@
 #include "ui/views/widget/widget.h"
 #include "ui/wm/core/window_util.h"
 
+namespace {
+
+void MoveWindowFromOldDisplayToNewDisplay(aura::Window* window,
+                                          display::Display& old_display,
+                                          display::Display& new_display) {
+  // Adjust the window size and origin in proportion to the relative size of the
+  // display.
+  int old_width = old_display.bounds().width();
+  int new_width = new_display.bounds().width();
+  int old_height = old_display.bounds().height();
+  int new_height = new_display.bounds().height();
+  gfx::Rect old_bounds = window->bounds();
+  gfx::Rect new_bounds(old_bounds.x() * new_width / old_width,
+                       old_bounds.y() * new_height / old_height,
+                       old_bounds.width() * new_width / old_width,
+                       old_bounds.height() * new_height / old_height);
+
+  // Transform the bounds in display to that in screen.
+  gfx::Point new_origin = new_display.bounds().origin();
+  new_origin.Offset(new_bounds.x(), new_bounds.y());
+  new_bounds.set_origin(new_origin);
+  window->SetBoundsInScreen(new_bounds, new_display);
+}
+
+}  // namespace
+
 CrostiniAppWindowShelfController::CrostiniAppWindowShelfController(
     ChromeLauncherController* owner)
     : AppWindowLauncherController(owner) {
@@ -42,8 +68,8 @@
 }
 
 CrostiniAppWindowShelfController::~CrostiniAppWindowShelfController() {
-  for (auto window : observed_window_to_startup_id_)
-    window.first->RemoveObserver(this);
+  for (auto* window : observed_windows_)
+    window->RemoveObserver(this);
   aura::Env* env = aura::Env::GetInstanceDontCreate();
   if (env)
     env->RemoveObserver(this);
@@ -116,58 +142,11 @@
   if (!widget->CanActivate())
     return;
 
-  const std::string* startup_id = exo::ShellSurface::GetStartupId(window);
-  if (startup_id == nullptr) {
-    observed_window_to_startup_id_.emplace(window, std::string());
-  } else {
-    observed_window_to_startup_id_.emplace(window, *startup_id);
-  }
-
+  observed_windows_.emplace(window);
   window->AddObserver(this);
 }
 
-void CrostiniAppWindowShelfController::OnWindowPropertyChanged(
-    aura::Window* window,
-    const void* key,
-    intptr_t old) {
-  const std::string* startup_id = exo::ShellSurface::GetStartupId(window);
-  if (startup_id == nullptr || startup_id->empty())
-    return;
-  if (*startup_id == observed_window_to_startup_id_.at(window))
-    return;
-  observed_window_to_startup_id_[window] = *startup_id;
-  int64_t display_id =
-      crostini_app_display_.GetDisplayIdForStartupId(*startup_id);
-  if (display_id == display::kInvalidDisplayId)
-    return;
-
-  display::Display new_display;
-  if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(display_id,
-                                                             &new_display))
-    return;
-  display::Display old_display =
-      display::Screen::GetScreen()->GetDisplayNearestWindow(window);
-
-  // Adjust the window size and origin in proportion to the relative size of the
-  // display.
-  int old_width = old_display.bounds().width();
-  int new_width = new_display.bounds().width();
-  int old_height = old_display.bounds().height();
-  int new_height = new_display.bounds().height();
-  gfx::Rect old_bounds = window->bounds();
-  gfx::Rect new_bounds(old_bounds.x() * new_width / old_width,
-                       old_bounds.y() * new_height / old_height,
-                       old_bounds.width() * new_width / old_width,
-                       old_bounds.height() * new_height / old_height);
-
-  // Transform the bounds in display to that in screen.
-  gfx::Point new_origin = new_display.bounds().origin();
-  new_origin.Offset(new_bounds.x(), new_bounds.y());
-  new_bounds.set_origin(new_origin);
-  window->SetBoundsInScreen(new_bounds, new_display);
-}
-
-void CrostiniAppWindowShelfController::OnWindowVisibilityChanged(
+void CrostiniAppWindowShelfController::OnWindowVisibilityChanging(
     aura::Window* window,
     bool visible) {
   if (!visible)
@@ -203,11 +182,27 @@
   if (shelf_app_id.empty())
     return;
 
+  RegisterAppWindow(window, shelf_app_id);
+
   // Prevent Crostini window from showing up after user switch.
   MultiUserWindowManager::GetInstance()->SetWindowOwner(
       window,
       user_manager::UserManager::Get()->GetActiveUser()->GetAccountId());
-  RegisterAppWindow(window, shelf_app_id);
+
+  // Move the Crostini app window to the right display if necessary.
+  int64_t display_id = crostini_app_display_.GetDisplayIdForAppId(shelf_app_id);
+  if (display_id == display::kInvalidDisplayId)
+    return;
+
+  display::Display new_display;
+  if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(display_id,
+                                                             &new_display))
+    return;
+  display::Display old_display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(window);
+
+  if (new_display != old_display)
+    MoveWindowFromOldDisplayToNewDisplay(window, old_display, new_display);
 }
 
 void CrostiniAppWindowShelfController::RegisterAppWindow(
@@ -223,9 +218,9 @@
 
 void CrostiniAppWindowShelfController::OnWindowDestroying(
     aura::Window* window) {
-  auto it = observed_window_to_startup_id_.find(window);
-  DCHECK(it != observed_window_to_startup_id_.end());
-  observed_window_to_startup_id_.erase(it);
+  auto it = observed_windows_.find(window);
+  DCHECK(it != observed_windows_.end());
+  observed_windows_.erase(it);
   window->RemoveObserver(this);
 
   auto app_window_it = aura_window_to_app_window_.find(window);
@@ -280,7 +275,7 @@
 }
 
 void CrostiniAppWindowShelfController::OnAppLaunchRequested(
-    const std::string& startup_id,
+    const std::string& app_id,
     int64_t display_id) {
-  crostini_app_display_.Register(startup_id, display_id);
+  crostini_app_display_.Register(app_id, display_id);
 }
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h
index 4a4b7793..5a2ef8f19 100644
--- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h
+++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <set>
 #include <vector>
 
 #include "base/macros.h"
@@ -45,15 +46,12 @@
   void OnWindowInitialized(aura::Window* window) override;
 
   // aura::WindowObserver:
-  void OnWindowPropertyChanged(aura::Window* window,
-                               const void* key,
-                               intptr_t old) override;
-  void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
+  void OnWindowVisibilityChanging(aura::Window* window, bool visible) override;
   void OnWindowDestroying(aura::Window* window) override;
 
-  // A Crostini app with |startup_id| is requested to launch on display with
+  // A Crostini app with |app_id| is requested to launch on display with
   // |display_id|.
-  void OnAppLaunchRequested(const std::string& startup_id,
+  void OnAppLaunchRequested(const std::string& app_id,
                             int64_t display_id) override;
 
  private:
@@ -71,7 +69,7 @@
   void OnItemDelegateDiscarded(ash::ShelfItemDelegate* delegate) override;
 
   AuraWindowToAppWindow aura_window_to_app_window_;
-  std::map<aura::Window*, std::string> observed_window_to_startup_id_;
+  std::set<aura::Window*> observed_windows_;
   CrostiniAppDisplay crostini_app_display_;
 
   DISALLOW_COPY_AND_ASSIGN(CrostiniAppWindowShelfController);
diff --git a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc
index 4a27b9b..b15707bd8 100644
--- a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc
+++ b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc
@@ -37,12 +37,14 @@
       : browser_sync::TestProfileSyncService(
             CreateProfileSyncServiceParamsForTest(profile)) {}
 
-  bool IsSyncAllowed() const override { return is_sync_allowed_; }
+  int GetDisableReasons() const override { return disable_reasons_; }
 
-  void set_sync_allowed(bool sync_allowed) { is_sync_allowed_ = sync_allowed; }
+  void SetDisableReasons(int disable_reasons) {
+    disable_reasons_ = disable_reasons;
+  }
 
  private:
-  bool is_sync_allowed_ = true;
+  int disable_reasons_ = DISABLE_REASON_NONE;
   DISALLOW_COPY_AND_ASSIGN(TestSyncService);
 };
 
@@ -176,7 +178,10 @@
 
   for (const auto& test_case : kTestData) {
     SCOPED_TRACE(testing::Message("#test_case = ") << (&test_case - kTestData));
-    sync_service()->set_sync_allowed(test_case.is_sync_allowed);
+    sync_service()->SetDisableReasons(
+        test_case.is_sync_allowed
+            ? syncer::SyncService::DISABLE_REASON_NONE
+            : syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE);
     const GoogleServiceAuthError error(
         test_case.signin_error
             ? GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc b/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc
index 8672a077..76bf37e 100644
--- a/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc
+++ b/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc
@@ -39,10 +39,10 @@
   UpdateWithoutTabRestore();
 }
 
-content::WebContents* ChromeOmniboxEditController::GetWebContents() {

-  return nullptr;

-}

-

+content::WebContents* ChromeOmniboxEditController::GetWebContents() {
+  return nullptr;
+}
+
 void ChromeOmniboxEditController::UpdateWithoutTabRestore() {}
 
 ChromeOmniboxEditController::ChromeOmniboxEditController(
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
index 1fc70fc2..3a16903 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -82,8 +82,8 @@
   ~TestSyncService() override {}
 
   // FakeSyncService:
+  int GetDisableReasons() const override { return DISABLE_REASON_NONE; }
   bool IsFirstSetupComplete() const override { return true; }
-  bool IsSyncAllowed() const override { return true; }
   bool IsSyncActive() const override { return true; }
   syncer::ModelTypeSet GetActiveDataTypes() const override {
     switch (synced_types_) {
@@ -95,7 +95,6 @@
     NOTREACHED();
     return syncer::ModelTypeSet();
   }
-  bool CanSyncStart() const override { return true; }
   syncer::ModelTypeSet GetPreferredDataTypes() const override {
     return GetActiveDataTypes();
   }
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model.cc b/chrome/browser/ui/toolbar/back_forward_menu_model.cc
index d82276b..da4cd84 100644
--- a/chrome/browser/ui/toolbar/back_forward_menu_model.cc
+++ b/chrome/browser/ui/toolbar/back_forward_menu_model.cc
@@ -9,6 +9,8 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/metrics/user_metrics.h"
+#include "base/numerics/ranges.h"
+#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
@@ -52,22 +54,21 @@
 
 int BackForwardMenuModel::GetItemCount() const {
   int items = GetHistoryItemCount();
+  if (items <= 0)
+    return items;
 
-  if (items > 0) {
-    int chapter_stops = 0;
+  int chapter_stops = 0;
 
-    // Next, we count ChapterStops, if any.
-    if (items == kMaxHistoryItems)
-      chapter_stops = GetChapterStopCount(items);
+  // Next, we count ChapterStops, if any.
+  if (items == kMaxHistoryItems)
+    chapter_stops = GetChapterStopCount(items);
 
-    if (chapter_stops)
-      items += chapter_stops + 1;  // Chapter stops also need a separator.
+  if (chapter_stops)
+    items += chapter_stops + 1;  // Chapter stops also need a separator.
 
-    // If the menu is not empty, add two positions in the end
-    // for a separator and a "Show Full History" item.
-    items += 2;
-  }
-
+  // If the menu is not empty, add two positions in the end
+  // for a separator and a "Show Full History" item.
+  items += 2;
   return items;
 }
 
@@ -180,11 +181,12 @@
   }
 
   // Log whether it was a history or chapter click.
-  if (index < GetHistoryItemCount()) {
+  int items = GetHistoryItemCount();
+  if (index < items) {
     base::RecordComputedAction(BuildActionName("HistoryClick", index));
   } else {
-    base::RecordComputedAction(
-        BuildActionName("ChapterClick", index - GetHistoryItemCount() - 1));
+    const int chapter_index = index - items - 1;
+    base::RecordComputedAction(BuildActionName("ChapterClick", chapter_index));
   }
 
   int controller_index = MenuIndexToNavEntryIndex(index);
@@ -234,10 +236,9 @@
 void BackForwardMenuModel::FetchFavicon(NavigationEntry* entry) {
   // If the favicon has already been requested for this menu, don't do
   // anything.
-  if (requested_favicons_.find(entry->GetUniqueID()) !=
-      requested_favicons_.end()) {
+  if (base::ContainsKey(requested_favicons_, entry->GetUniqueID()))
     return;
-  }
+
   requested_favicons_.insert(entry->GetUniqueID());
   favicon::FaviconService* favicon_service =
       FaviconServiceFactory::GetForProfile(browser_->profile(),
@@ -256,127 +257,119 @@
 void BackForwardMenuModel::OnFavIconDataAvailable(
     int navigation_entry_unique_id,
     const favicon_base::FaviconImageResult& image_result) {
-  if (!image_result.image.IsEmpty()) {
-    // Find the current model_index for the unique id.
-    NavigationEntry* entry = nullptr;
-    int model_index = -1;
-    for (int i = 0; i < GetItemCount() - 1; i++) {
-      if (IsSeparator(i))
-        continue;
-      if (GetNavigationEntry(i)->GetUniqueID() == navigation_entry_unique_id) {
-        model_index = i;
-        entry = GetNavigationEntry(i);
-        break;
-      }
-    }
+  if (image_result.image.IsEmpty())
+    return;
 
-    if (!entry)
-      // The NavigationEntry wasn't found, this can happen if the user
-      // navigates to another page and a NavigatationEntry falls out of the
-      // range of kMaxHistoryItems.
-      return;
-
-    // Now that we have a valid NavigationEntry, decode the favicon and assign
-    // it to the NavigationEntry.
-    entry->GetFavicon().valid = true;
-    entry->GetFavicon().url = image_result.icon_url;
-    entry->GetFavicon().image = image_result.image;
-    if (menu_model_delegate()) {
-      menu_model_delegate()->OnIconChanged(model_index);
+  // Find the current model_index for the unique id.
+  NavigationEntry* entry = nullptr;
+  int model_index = -1;
+  for (int i = 0; i < GetItemCount() - 1; i++) {
+    if (IsSeparator(i))
+      continue;
+    if (GetNavigationEntry(i)->GetUniqueID() == navigation_entry_unique_id) {
+      model_index = i;
+      entry = GetNavigationEntry(i);
+      break;
     }
   }
+
+  if (!entry) {
+    // The NavigationEntry wasn't found, this can happen if the user
+    // navigates to another page and a NavigatationEntry falls out of the
+    // range of kMaxHistoryItems.
+    return;
+  }
+
+  // Now that we have a valid NavigationEntry, decode the favicon and assign
+  // it to the NavigationEntry.
+  entry->GetFavicon().valid = true;
+  entry->GetFavicon().url = image_result.icon_url;
+  entry->GetFavicon().image = image_result.image;
+  if (menu_model_delegate()) {
+    menu_model_delegate()->OnIconChanged(model_index);
+  }
 }
 
 int BackForwardMenuModel::GetHistoryItemCount() const {
   WebContents* contents = GetWebContents();
-  int items = 0;
 
+  int items = contents->GetController().GetCurrentEntryIndex();
   if (model_type_ == ModelType::kForward) {
     // Only count items from n+1 to end (if n is current entry)
-    items = contents->GetController().GetEntryCount() -
-            contents->GetController().GetCurrentEntryIndex() - 1;
-  } else {
-    items = contents->GetController().GetCurrentEntryIndex();
+    items = contents->GetController().GetEntryCount() - items - 1;
   }
 
-  if (items > kMaxHistoryItems)
-    items = kMaxHistoryItems;
-  else if (items < 0)
-    items = 0;
-
-  return items;
+  return base::ClampToRange(items, 0, kMaxHistoryItems);
 }
 
 int BackForwardMenuModel::GetChapterStopCount(int history_items) const {
-  WebContents* contents = GetWebContents();
+  if (history_items != kMaxHistoryItems)
+    return 0;
 
-  int chapter_stops = 0;
+  WebContents* contents = GetWebContents();
   int current_entry = contents->GetController().GetCurrentEntryIndex();
 
-  if (history_items == kMaxHistoryItems) {
-    int chapter_id = current_entry;
-    if (model_type_ == ModelType::kForward) {
-      chapter_id += history_items;
-    } else {
-      chapter_id -= history_items;
-    }
+  const bool forward = model_type_ == ModelType::kForward;
+  int chapter_id = current_entry;
+  if (forward)
+    chapter_id += history_items;
+  else
+    chapter_id -= history_items;
 
-    do {
-      chapter_id = GetIndexOfNextChapterStop(
-          chapter_id, model_type_ == ModelType::kForward);
-      if (chapter_id != -1)
-        ++chapter_stops;
-    } while (chapter_id != -1 && chapter_stops < kMaxChapterStops);
-  }
+  int chapter_stops = 0;
+  do {
+    chapter_id = GetIndexOfNextChapterStop(chapter_id, forward);
+    if (chapter_id == -1)
+      break;
+    ++chapter_stops;
+  } while (chapter_stops < kMaxChapterStops);
 
   return chapter_stops;
 }
 
 int BackForwardMenuModel::GetIndexOfNextChapterStop(int start_from,
                                                     bool forward) const {
-  WebContents* contents = GetWebContents();
-  NavigationController& controller = contents->GetController();
-
-  int max_count = controller.GetEntryCount();
-  if (start_from < 0 || start_from >= max_count)
+  if (start_from < 0)
     return -1;  // Out of bounds.
 
-  if (forward) {
-    if (start_from < max_count - 1) {
-      // We want to advance over the current chapter stop, so we add one.
-      // We don't need to do this when direction is backwards.
-      start_from++;
-    } else {
-      return -1;
-    }
-  }
+  // We want to advance over the current chapter stop, so we add one.
+  // We don't need to do this when direction is backwards.
+  if (forward)
+    start_from++;
+
+  NavigationController& controller = GetWebContents()->GetController();
+  const int max_count = controller.GetEntryCount();
+  if (start_from >= max_count)
+    return -1;  // Out of bounds.
 
   NavigationEntry* start_entry = controller.GetEntryAtIndex(start_from);
   const GURL& url = start_entry->GetURL();
 
-  if (!forward) {
-    // When going backwards we return the first entry we find that has a
-    // different domain.
-    for (int i = start_from - 1; i >= 0; --i) {
-      if (!net::registry_controlled_domains::SameDomainOrHost(url,
-              controller.GetEntryAtIndex(i)->GetURL(),
-              net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES))
-        return i;
-    }
-    // We have reached the beginning without finding a chapter stop.
-    return -1;
-  } else {
+  auto same_domain_func = [&controller, &url](int i) {
+    return net::registry_controlled_domains::SameDomainOrHost(
+        url, controller.GetEntryAtIndex(i)->GetURL(),
+        net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
+  };
+
+  if (forward) {
     // When going forwards we return the entry before the entry that has a
     // different domain.
     for (int i = start_from + 1; i < max_count; ++i) {
-      if (!net::registry_controlled_domains::SameDomainOrHost(url,
-              controller.GetEntryAtIndex(i)->GetURL(),
-              net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES))
+      if (!same_domain_func(i))
         return i - 1;
     }
     // Last entry is always considered a chapter stop.
     return max_count - 1;
   }
+
+  // When going backwards we return the first entry we find that has a
+  // different domain.
+  for (int i = start_from - 1; i >= 0; --i) {
+    if (!same_domain_func(i))
+      return i;
+  }
+  // We have reached the beginning without finding a chapter stop.
+  return -1;
 }
 
 int BackForwardMenuModel::FindChapterStop(int offset,
@@ -438,10 +431,8 @@
     return -1;  // This is beyond the last chapter stop so we abort.
 
   // This menu item is a chapter stop located between the two separators.
-  index = FindChapterStop(history_items, model_type_ == ModelType::kForward,
-                          index - history_items - 1);
-
-  return index;
+  return FindChapterStop(history_items, model_type_ == ModelType::kForward,
+                         index - history_items - 1);
 }
 
 NavigationEntry* BackForwardMenuModel::GetNavigationEntry(int index) const {
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model.h b/chrome/browser/ui/toolbar/back_forward_menu_model.h
index 4eb50e9..48fd16ac 100644
--- a/chrome/browser/ui/toolbar/back_forward_menu_model.h
+++ b/chrome/browser/ui/toolbar/back_forward_menu_model.h
@@ -191,7 +191,7 @@
 
   // Represents whether this is the delegate for the forward button or the
   // back button.
-  ModelType model_type_;
+  const ModelType model_type_;
 
   // Keeps track of which favicons have already been requested from the history
   // to prevent duplicate requests, identified by
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index b339dc8..a9f99d3 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -385,7 +385,7 @@
 void OverlayWindowViews::UpdateVideoSize(const gfx::Size& natural_size) {
   DCHECK(!natural_size.IsEmpty());
   natural_size_ = natural_size;
-  SetAspectRatio(natural_size_);
+  SetAspectRatio(gfx::SizeF(natural_size_));
 
   if (IsVisible())
     return;
diff --git a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
index a6ddb03..af67afa5 100644
--- a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
@@ -617,6 +617,7 @@
   // Users default corpus first.
   auto app_data = std::make_unique<base::DictionaryValue>();
   app_data->SetString("id", "default corpus");
+  app_data->SetString("root_entry_path", metadata.path);
   app_data->SetString("start_page_token", metadata.start_page_token);
   app_data->SetString("last_check_time",
                       google_apis::util::FormatTimeAsStringLocaltime(
@@ -631,6 +632,7 @@
   for (const auto& team_drive : team_drive_metadata) {
     app_data = std::make_unique<base::DictionaryValue>();
     app_data->SetString("id", team_drive.first);
+    app_data->SetString("root_entry_path", team_drive.second.path);
     app_data->SetString("start_page_token", team_drive.second.start_page_token);
     app_data->SetString("last_check_time",
                         google_apis::util::FormatTimeAsStringLocaltime(
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
index 8964c907..b892dd3e 100644
--- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -233,7 +233,8 @@
 
   // Setup the expectations for calls made when displaying the config page.
   void SetDefaultExpectationsForConfigPage() {
-    EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*mock_pss_, GetDisableReasons())
+        .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
     EXPECT_CALL(*mock_pss_, GetRegisteredDataTypes())
         .WillRepeatedly(Return(GetAllTypes()));
     EXPECT_CALL(*mock_pss_, GetPreferredDataTypes())
@@ -333,7 +334,9 @@
   // Test that the HandleStartSignin call enables JavaScript.
   handler_->DisallowJavascript();
 
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
   // Ensure that the user is not signed in before calling |HandleStartSignin()|.
   SigninManager* manager = SigninManager::FromSigninManagerBase(mock_signin_);
@@ -356,7 +359,9 @@
 }
 
 TEST_F(PeopleHandlerTest, ShowSyncSetupWhenNotSignedIn) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
   handler_->HandleShowSetupUI(nullptr);
 
@@ -372,7 +377,9 @@
 // Verifies that the sync setup is terminated correctly when the
 // sync is disabled.
 TEST_F(PeopleHandlerTest, HandleSetupUIWhenSyncDisabled) {
-  EXPECT_CALL(*mock_pss_, IsManaged()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY));
   handler_->HandleShowSetupUI(nullptr);
 
   // Sync setup is closed when sync is disabled.
@@ -385,7 +392,8 @@
 // Verifies that the handler correctly handles a cancellation when
 // it is displaying the spinner to the user.
 TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
   error_ = GoogleServiceAuthError::AuthErrorNone();
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false));
@@ -409,8 +417,9 @@
 // to showing a configuration page when sync setup completes successfully.
 TEST_F(PeopleHandlerTest,
        DisplayConfigureWithEngineDisabledAndSyncStartupCompleted) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   error_ = GoogleServiceAuthError::AuthErrorNone();
   // Sync engine is stopped initially, and will start up.
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false));
@@ -446,7 +455,8 @@
 // user has continued on.
 TEST_F(PeopleHandlerTest,
        DisplayConfigureWithEngineDisabledAndCancelAfterSigninSuccess) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
   error_ = GoogleServiceAuthError::AuthErrorNone();
   EXPECT_CALL(*mock_pss_, IsEngineInitialized())
@@ -469,7 +479,8 @@
 }
 
 TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndSigninFailed) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
   error_ = GoogleServiceAuthError::AuthErrorNone();
   EXPECT_CALL(*mock_pss_, IsEngineInitialized()).WillRepeatedly(Return(false));
@@ -526,20 +537,11 @@
   PeopleHandlerNonCrosTest() {}
 };
 
-TEST_F(PeopleHandlerNonCrosTest, HandleGaiaAuthFailure) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false));
-  EXPECT_CALL(*mock_pss_, HasUnrecoverableError())
-      .WillRepeatedly(Return(false));
-  EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
-  // Open the web UI.
-  handler_->HandleShowSetupUI(nullptr);
-
-  ASSERT_FALSE(handler_->is_configuring_sync());
-}
-
 // TODO(kochi): We need equivalent tests for ChromeOS.
 TEST_F(PeopleHandlerNonCrosTest, UnrecoverableErrorInitializingSync) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
   // Open the web UI.
   handler_->HandleShowSetupUI(nullptr);
@@ -548,7 +550,9 @@
 }
 
 TEST_F(PeopleHandlerNonCrosTest, GaiaErrorInitializingSync) {
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(
+          Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN));
   EXPECT_CALL(*mock_pss_, IsFirstSetupComplete()).WillRepeatedly(Return(false));
   // Open the web UI.
   handler_->HandleShowSetupUI(nullptr);
@@ -767,7 +771,8 @@
   FakeAuthStatusProvider provider(
       SigninErrorControllerFactory::GetForProfile(profile()));
   provider.SetAuthError(kTestUser, error_);
-  EXPECT_CALL(*mock_pss_, CanSyncStart()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*mock_pss_, GetDisableReasons())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
   EXPECT_CALL(*mock_pss_, IsPassphraseRequired())
       .WillRepeatedly(Return(false));
   EXPECT_CALL(*mock_pss_, IsUsingSecondaryPassphrase())
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
index 8ee5c5b0..256ec273 100644
--- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
+++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
@@ -250,7 +250,8 @@
     browser_sync::ProfileSyncServiceMock* sync_service_mock =
         GetProfileSyncServiceMock();
     EXPECT_CALL(*sync_service_mock, GetSetupInProgressHandle()).Times(1);
-    ON_CALL(*sync_service_mock, CanSyncStart()).WillByDefault(Return(true));
+    ON_CALL(*sync_service_mock, GetDisableReasons())
+        .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
     ON_CALL(*sync_service_mock, IsEngineInitialized())
         .WillByDefault(Return(true));
   }
@@ -259,7 +260,8 @@
     browser_sync::ProfileSyncServiceMock* sync_service_mock =
         GetProfileSyncServiceMock();
     EXPECT_CALL(*sync_service_mock, GetSetupInProgressHandle()).Times(1);
-    ON_CALL(*sync_service_mock, CanSyncStart()).WillByDefault(Return(true));
+    ON_CALL(*sync_service_mock, GetDisableReasons())
+        .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
     ON_CALL(*sync_service_mock, IsEngineInitialized())
         .WillByDefault(Return(false));
     ON_CALL(*sync_service_mock, GetAuthError())
diff --git a/chrome/browser/vr/elements/controller.h b/chrome/browser/vr/elements/controller.h
index c1467a3..95d7439 100644
--- a/chrome/browser/vr/elements/controller.h
+++ b/chrome/browser/vr/elements/controller.h
@@ -20,8 +20,10 @@
   ~Controller() override;
 
   void set_local_transform(const gfx::Transform& transform) {
-    local_transform_ = transform;
-    set_world_space_transform_dirty();
+    if (transform != local_transform_) {
+      set_world_space_transform_dirty();
+      local_transform_ = transform;
+    }
   }
 
   class Renderer : public BaseRenderer {
diff --git a/chrome/renderer/net/net_error_helper_core.cc b/chrome/renderer/net/net_error_helper_core.cc
index adc4691..11ccdad 100644
--- a/chrome/renderer/net/net_error_helper_core.cc
+++ b/chrome/renderer/net/net_error_helper_core.cc
@@ -510,7 +510,7 @@
       can_show_network_diagnostics_dialog_(false),
       auto_reload_enabled_(auto_reload_enabled),
       auto_reload_visible_only_(auto_reload_visible_only),
-      auto_reload_timer_(new base::Timer(false, false)),
+      auto_reload_timer_(new base::OneShotTimer()),
       auto_reload_paused_(false),
       auto_reload_in_flight_(false),
       uncommitted_load_started_(false),
diff --git a/chrome/renderer/net/net_error_helper_core.h b/chrome/renderer/net/net_error_helper_core.h
index d0d4e73..0d5da35 100644
--- a/chrome/renderer/net/net_error_helper_core.h
+++ b/chrome/renderer/net/net_error_helper_core.h
@@ -192,7 +192,7 @@
 
   bool ShouldSuppressErrorPage(FrameType frame_type, const GURL& url);
 
-  void set_timer_for_testing(std::unique_ptr<base::Timer> timer) {
+  void set_timer_for_testing(std::unique_ptr<base::OneShotTimer> timer) {
     auto_reload_timer_ = std::move(timer);
   }
 
@@ -257,7 +257,7 @@
   const bool auto_reload_visible_only_;
 
   // Timer used to wait for auto-reload attempts.
-  std::unique_ptr<base::Timer> auto_reload_timer_;
+  std::unique_ptr<base::OneShotTimer> auto_reload_timer_;
 
   // True if the auto-reload timer would be running but is waiting for an
   // offline->online network transition.
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/index.js b/chrome/test/data/extensions/api_test/mime_handler_view/index.js
index 565be10..e2e2e03 100644
--- a/chrome/test/data/extensions/api_test/mime_handler_view/index.js
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/index.js
@@ -236,6 +236,16 @@
       }, 100);
     });
   },
+
+  function testTargetBlankAnchor() {
+    checkStreamDetails('testTargetBlankAnchor.csv', false);
+    var anchor = document.createElement('a');
+    anchor.href = 'about:blank';
+    anchor.target = '_blank';
+    document.body.appendChild(anchor);
+    anchor.click();
+    chrome.test.succeed();
+  },
 ];
 
 var testsByName = {};
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/testTargetBlankAnchor.csv b/chrome/test/data/extensions/api_test/mime_handler_view/testTargetBlankAnchor.csv
new file mode 100644
index 0000000..1e30f4ad
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/testTargetBlankAnchor.csv
@@ -0,0 +1 @@
+content to read
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/testTargetBlankAnchor.csv.mock-http-headers b/chrome/test/data/extensions/api_test/mime_handler_view/testTargetBlankAnchor.csv.mock-http-headers
new file mode 100644
index 0000000..2eef2e8
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/mime_handler_view/testTargetBlankAnchor.csv.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.0 200 OK
+Content-Type: text/csv
diff --git a/chrome/test/data/extensions/good2_unpacked/manifest.json b/chrome/test/data/extensions/good2_unpacked/manifest.json
index 33f5c34..24b28fa4 100644
--- a/chrome/test/data/extensions/good2_unpacked/manifest.json
+++ b/chrome/test/data/extensions/good2_unpacked/manifest.json
@@ -1,16 +1,16 @@
-{

-  "content_scripts": [{

-    "js": [ "script1.js" ],

-    "matches": [ "http://*.google.com/*", "https://*.google.com/*" ]

-  }, {

-    "js": [ "script2.js" ],

-    "matches": [ "http://*.example.com/*" ]

-  }],

-  "background": {

-    "page": "background.html"

-  },

-  "description": "The first extension that I made.",

-  "manifest_version": 2,

-  "name": "My updated extension 1",

-  "version": "1.0.0.1"

-}

+{
+  "content_scripts": [{
+    "js": [ "script1.js" ],
+    "matches": [ "http://*.google.com/*", "https://*.google.com/*" ]
+  }, {
+    "js": [ "script2.js" ],
+    "matches": [ "http://*.example.com/*" ]
+  }],
+  "background": {
+    "page": "background.html"
+  },
+  "description": "The first extension that I made.",
+  "manifest_version": 2,
+  "name": "My updated extension 1",
+  "version": "1.0.0.1"
+}
diff --git a/chrome/test/data/extensions/good_unpacked/manifest.json b/chrome/test/data/extensions/good_unpacked/manifest.json
index dbc2b60..73cbd98 100644
--- a/chrome/test/data/extensions/good_unpacked/manifest.json
+++ b/chrome/test/data/extensions/good_unpacked/manifest.json
@@ -1,13 +1,13 @@
-{

-  "content_scripts": [{

-    "js": [ "script1.js" ],

-    "matches": [ "http://*.google.com/*", "https://*.google.com/*" ]

-  }, {

-    "js": [ "script2.js" ],

-    "matches": [ "http://*.example.com/*" ]

-  }],

-  "description": "The first extension that I made.",

-  "manifest_version": 2,

-  "name": "My extension 1",

-  "version": "1.0.0.0"

-}

+{
+  "content_scripts": [{
+    "js": [ "script1.js" ],
+    "matches": [ "http://*.google.com/*", "https://*.google.com/*" ]
+  }, {
+    "js": [ "script2.js" ],
+    "matches": [ "http://*.example.com/*" ]
+  }],
+  "description": "The first extension that I made.",
+  "manifest_version": 2,
+  "name": "My extension 1",
+  "version": "1.0.0.0"
+}
diff --git a/chrome/test/data/extensions/good_v1/manifest.json b/chrome/test/data/extensions/good_v1/manifest.json
index 3c887226..26663b9 100644
--- a/chrome/test/data/extensions/good_v1/manifest.json
+++ b/chrome/test/data/extensions/good_v1/manifest.json
@@ -1,16 +1,16 @@
-{

-   "content_scripts": [ {

-      "js": [ "script1.js" ],

-      "matches": [ "http://*.google.com/*", "https://*.google.com/*" ]

-   }, {

-      "js": [ "script2.js" ],

-      "matches": [ "http://*.example.com/*" ]

-   } ],

-   "description": "The first extension that I made.",

-   "manifest_version": 2,

-   "name": "My extension 1",

-   "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294jkDuI7caxEGUucpP7GJRRHnm8Sx+y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB",

-   "version": "1.0.0.0",

-   "update_url": "http://update.extension/good_update_manifest.xml"

-}

-

+{
+   "content_scripts": [ {
+      "js": [ "script1.js" ],
+      "matches": [ "http://*.google.com/*", "https://*.google.com/*" ]
+   }, {
+      "js": [ "script2.js" ],
+      "matches": [ "http://*.example.com/*" ]
+   } ],
+   "description": "The first extension that I made.",
+   "manifest_version": 2,
+   "name": "My extension 1",
+   "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294jkDuI7caxEGUucpP7GJRRHnm8Sx+y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB",
+   "version": "1.0.0.0",
+   "update_url": "http://update.extension/good_update_manifest.xml"
+}
+
diff --git a/chrome/test/data/vr/e2e_test_files/html/test_webvr_pixels.html b/chrome/test/data/vr/e2e_test_files/html/test_webvr_pixels.html
index 1820d49..3a20a8f6 100644
--- a/chrome/test/data/vr/e2e_test_files/html/test_webvr_pixels.html
+++ b/chrome/test/data/vr/e2e_test_files/html/test_webvr_pixels.html
@@ -1,21 +1,21 @@
-<!doctype html>

-<!--

-Tests WebVR pixel data is submitted correctly.

--->

-<html>

-  <head>

-    <link rel="stylesheet" type="text/css" href="../resources/webvr_e2e.css">

-  </head>

-  <body>

-    <canvas id="webgl-canvas"></canvas>

-    <script src="../../../../../../third_party/WebKit/LayoutTests/resources/testharness.js"></script>

-    <script src="../resources/webvr_e2e.js"></script>

-    <script src="../resources/webvr_boilerplate.js"></script>

-    <script>

-      var t = async_test("Pixel data is correct");

-      function finishTest() {

-        t.done();

-      }

-    </script>

-  </body>

-</html>

+<!doctype html>
+<!--
+Tests WebVR pixel data is submitted correctly.
+-->
+<html>
+  <head>
+    <link rel="stylesheet" type="text/css" href="../resources/webvr_e2e.css">
+  </head>
+  <body>
+    <canvas id="webgl-canvas"></canvas>
+    <script src="../../../../../../third_party/WebKit/LayoutTests/resources/testharness.js"></script>
+    <script src="../resources/webvr_e2e.js"></script>
+    <script src="../resources/webvr_boilerplate.js"></script>
+    <script>
+      var t = async_test("Pixel data is correct");
+      function finishTest() {
+        t.done();
+      }
+    </script>
+  </body>
+</html>
diff --git a/chrome/test/mini_installer/ZIP_README.txt b/chrome/test/mini_installer/ZIP_README.txt
index 759ac869..20af3410 100644
--- a/chrome/test/mini_installer/ZIP_README.txt
+++ b/chrome/test/mini_installer/ZIP_README.txt
@@ -1,52 +1,52 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.

-# Use of this source code is governed by a BSD-style license that can be

-# found in the LICENSE file.

-

-This zip file can be retrieved in one of 3 ways:

-1) Download from cloud storage

-2) Build zip_mini_installer_tests

-3) Create one from an existing zip file

-

-Running create_zip.py to distribute is the recommended way to distribute and

-run the tests. This method creates a batch file that will automatically

-set the paths.

-

-python chrome\test\mini_installer\create_zip.py ^

-  --output-path <ZIP_FILE_OUTPUT_PATH> ^

-  --installer-path <CURRENT_INSTALLER_PATH> ^

-  --previous-version-installer-path <PREVIOUS_INSTALLER_PATH> ^

-  --chromedriver-path <CHROMEDRIVER_PATH>

-

-create_zip.py is included in the zip files, so they are able to create new

-zip files themselves. The drawback to this is the test cases aren't up to date

-and chromedriver may be out of date.

-

-The build target includes the chromedriver but no installers. There are

-testers that do not have access to the source code, simply the installers.

-Automatically adding 2 installers on build could cause confusion.

-

-If you do build or download a fresh zip file its recommended to unzip,

-put your installers in the directory, then use the command above to

-create the final zip. These can be easily distributed to testers and easy

-to maintain. When this method is used the --installer-path and

---previous-version-installer-path args must be passed to the batch file

-since the default may be wrong.

-

-To run:

-

-1) Ensure the latest python 2.7 is installed and in your path

-2) Unzip zip file

-3) Open a command window in administrator mode

-4) Navigate to the unzip folder

-5) Run test_runner.bat file

-

-Info:

-The installer's filename is not changed during the zipping process so there is

-no change to the way these are being identified now. Any args passed to the

-batch file will be passed on to the test runner. -i, -p, and -c are

-automatically set, but they can be overridden and all other flags can be set

-if desired.

-

-The batch script will use Python's pip module to install pywin32 and psutil

-to reduce the amount of setup time is needed.

-

+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+This zip file can be retrieved in one of 3 ways:
+1) Download from cloud storage
+2) Build zip_mini_installer_tests
+3) Create one from an existing zip file
+
+Running create_zip.py to distribute is the recommended way to distribute and
+run the tests. This method creates a batch file that will automatically
+set the paths.
+
+python chrome\test\mini_installer\create_zip.py ^
+  --output-path <ZIP_FILE_OUTPUT_PATH> ^
+  --installer-path <CURRENT_INSTALLER_PATH> ^
+  --previous-version-installer-path <PREVIOUS_INSTALLER_PATH> ^
+  --chromedriver-path <CHROMEDRIVER_PATH>
+
+create_zip.py is included in the zip files, so they are able to create new
+zip files themselves. The drawback to this is the test cases aren't up to date
+and chromedriver may be out of date.
+
+The build target includes the chromedriver but no installers. There are
+testers that do not have access to the source code, simply the installers.
+Automatically adding 2 installers on build could cause confusion.
+
+If you do build or download a fresh zip file its recommended to unzip,
+put your installers in the directory, then use the command above to
+create the final zip. These can be easily distributed to testers and easy
+to maintain. When this method is used the --installer-path and
+--previous-version-installer-path args must be passed to the batch file
+since the default may be wrong.
+
+To run:
+
+1) Ensure the latest python 2.7 is installed and in your path
+2) Unzip zip file
+3) Open a command window in administrator mode
+4) Navigate to the unzip folder
+5) Run test_runner.bat file
+
+Info:
+The installer's filename is not changed during the zipping process so there is
+no change to the way these are being identified now. Any args passed to the
+batch file will be passed on to the test runner. -i, -p, and -c are
+automatically set, but they can be overridden and all other flags can be set
+if desired.
+
+The batch script will use Python's pip module to install pywin32 and psutil
+to reduce the amount of setup time is needed.
+
diff --git a/chrome/test/mini_installer/test_page.html b/chrome/test/mini_installer/test_page.html
index 84b11683..cd99028 100644
--- a/chrome/test/mini_installer/test_page.html
+++ b/chrome/test/mini_installer/test_page.html
@@ -1,9 +1,9 @@
-<!DOCTYPE html>

-<html>

-

-<head>

-  <title>Chromedriver Test Page</title>

-</head>

-<body>This is the test page</body>

-

+<!DOCTYPE html>
+<html>
+
+<head>
+  <title>Chromedriver Test Page</title>
+</head>
+<body>This is the test page</body>
+
 </html>
\ No newline at end of file
diff --git a/chromeos/components/drivefs/mojom/drivefs.mojom b/chromeos/components/drivefs/mojom/drivefs.mojom
index ca400b80..ab88714 100644
--- a/chromeos/components/drivefs/mojom/drivefs.mojom
+++ b/chromeos/components/drivefs/mojom/drivefs.mojom
@@ -160,7 +160,7 @@
   // A unique ID corresponding to a particular sync action.
   int64 group_id;
 
-  string file_title;
+  string path;
 
   State state;
 
diff --git a/chromeos/components/tether/ble_connection_manager.cc b/chromeos/components/tether/ble_connection_manager.cc
index f91c13a9..63d9918 100644
--- a/chromeos/components/tether/ble_connection_manager.cc
+++ b/chromeos/components/tether/ble_connection_manager.cc
@@ -51,7 +51,7 @@
 
 BleConnectionManager::ConnectionMetadata::ConnectionMetadata(
     const std::string& device_id,
-    std::unique_ptr<base::Timer> timer,
+    std::unique_ptr<base::OneShotTimer> timer,
     base::WeakPtr<BleConnectionManager> manager)
     : device_id_(device_id),
       connection_attempt_timeout_timer_(std::move(timer)),
diff --git a/chromeos/components/tether/ble_connection_manager.h b/chromeos/components/tether/ble_connection_manager.h
index 12c2ec6..9bd71b6 100644
--- a/chromeos/components/tether/ble_connection_manager.h
+++ b/chromeos/components/tether/ble_connection_manager.h
@@ -173,7 +173,7 @@
   class ConnectionMetadata final : public cryptauth::SecureChannel::Observer {
    public:
     ConnectionMetadata(const std::string& device_id,
-                       std::unique_ptr<base::Timer> timer,
+                       std::unique_ptr<base::OneShotTimer> timer,
                        base::WeakPtr<BleConnectionManager> manager);
     ~ConnectionMetadata();
 
@@ -217,7 +217,7 @@
                        base::UnguessableTokenHash>
         request_id_to_priority_map_;
     std::unique_ptr<cryptauth::SecureChannel> secure_channel_;
-    std::unique_ptr<base::Timer> connection_attempt_timeout_timer_;
+    std::unique_ptr<base::OneShotTimer> connection_attempt_timeout_timer_;
     base::WeakPtr<BleConnectionManager> manager_;
 
     base::WeakPtrFactory<ConnectionMetadata> weak_ptr_factory_;
diff --git a/chromeos/components/tether/ble_connection_manager_unittest.cc b/chromeos/components/tether/ble_connection_manager_unittest.cc
index 2c6744b7..9a9216ea 100644
--- a/chromeos/components/tether/ble_connection_manager_unittest.cc
+++ b/chromeos/components/tether/ble_connection_manager_unittest.cc
@@ -65,7 +65,7 @@
 
 class MockTimerFactory : public TimerFactory {
  public:
-  std::unique_ptr<base::Timer> CreateOneShotTimer() override {
+  std::unique_ptr<base::OneShotTimer> CreateOneShotTimer() override {
     return std::make_unique<base::MockOneShotTimer>();
   }
 };
diff --git a/chromeos/components/tether/connection_preserver_impl.cc b/chromeos/components/tether/connection_preserver_impl.cc
index c205dc398..a49903e 100644
--- a/chromeos/components/tether/connection_preserver_impl.cc
+++ b/chromeos/components/tether/connection_preserver_impl.cc
@@ -229,7 +229,7 @@
 }
 
 void ConnectionPreserverImpl::SetTimerForTesting(
-    std::unique_ptr<base::Timer> timer_for_test) {
+    std::unique_ptr<base::OneShotTimer> timer_for_test) {
   preserved_connection_timer_ = std::move(timer_for_test);
 }
 
diff --git a/chromeos/components/tether/connection_preserver_impl.h b/chromeos/components/tether/connection_preserver_impl.h
index 9c4e01c..d8ac8a1 100644
--- a/chromeos/components/tether/connection_preserver_impl.h
+++ b/chromeos/components/tether/connection_preserver_impl.h
@@ -82,7 +82,7 @@
   base::Optional<cryptauth::RemoteDeviceRef> GetRemoteDevice(
       const std::string device_id);
 
-  void SetTimerForTesting(std::unique_ptr<base::Timer> timer_for_test);
+  void SetTimerForTesting(std::unique_ptr<base::OneShotTimer> timer_for_test);
 
   device_sync::DeviceSyncClient* device_sync_client_;
   secure_channel::SecureChannelClient* secure_channel_client_;
@@ -92,7 +92,7 @@
   TetherHostResponseRecorder* tether_host_response_recorder_;
   const base::UnguessableToken request_id_;
 
-  std::unique_ptr<base::Timer> preserved_connection_timer_;
+  std::unique_ptr<base::OneShotTimer> preserved_connection_timer_;
 
   std::string preserved_connection_device_id_;
 
diff --git a/chromeos/components/tether/host_scan_scheduler_impl.cc b/chromeos/components/tether/host_scan_scheduler_impl.cc
index 3f34552..108347e3 100644
--- a/chromeos/components/tether/host_scan_scheduler_impl.cc
+++ b/chromeos/components/tether/host_scan_scheduler_impl.cc
@@ -155,8 +155,8 @@
 }
 
 void HostScanSchedulerImpl::SetTestDoubles(
-    std::unique_ptr<base::Timer> test_host_scan_batch_timer,
-    std::unique_ptr<base::Timer> test_delay_scan_after_unlock_timer,
+    std::unique_ptr<base::OneShotTimer> test_host_scan_batch_timer,
+    std::unique_ptr<base::OneShotTimer> test_delay_scan_after_unlock_timer,
     base::Clock* test_clock,
     scoped_refptr<base::TaskRunner> test_task_runner) {
   host_scan_batch_timer_ = std::move(test_host_scan_batch_timer);
diff --git a/chromeos/components/tether/host_scan_scheduler_impl.h b/chromeos/components/tether/host_scan_scheduler_impl.h
index 3e5ab26..e9ad939 100644
--- a/chromeos/components/tether/host_scan_scheduler_impl.h
+++ b/chromeos/components/tether/host_scan_scheduler_impl.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_SCHEDULER_IMPL_H
-#define CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_SCHEDULER_IMPL_H
+#ifndef CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_SCHEDULER_IMPL_H_
+#define CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_SCHEDULER_IMPL_H_
 
 #include <memory>
 
@@ -68,8 +68,8 @@
   void LogHostScanBatchMetric();
 
   void SetTestDoubles(
-      std::unique_ptr<base::Timer> test_host_scan_batch_timer,
-      std::unique_ptr<base::Timer> test_delay_scan_after_unlock_timer,
+      std::unique_ptr<base::OneShotTimer> test_host_scan_batch_timer,
+      std::unique_ptr<base::OneShotTimer> test_delay_scan_after_unlock_timer,
       base::Clock* test_clock,
       scoped_refptr<base::TaskRunner> test_task_runner);
 
@@ -77,8 +77,8 @@
   HostScanner* host_scanner_;
   session_manager::SessionManager* session_manager_;
 
-  std::unique_ptr<base::Timer> host_scan_batch_timer_;
-  std::unique_ptr<base::Timer> delay_scan_after_unlock_timer_;
+  std::unique_ptr<base::OneShotTimer> host_scan_batch_timer_;
+  std::unique_ptr<base::OneShotTimer> delay_scan_after_unlock_timer_;
   base::Clock* clock_;
   scoped_refptr<base::TaskRunner> task_runner_;
 
@@ -96,4 +96,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_SCHEDULER_IMPL_H
+#endif  // CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_SCHEDULER_IMPL_H_
diff --git a/chromeos/components/tether/keep_alive_scheduler.cc b/chromeos/components/tether/keep_alive_scheduler.cc
index afd9e2b..ef781bf0 100644
--- a/chromeos/components/tether/keep_alive_scheduler.cc
+++ b/chromeos/components/tether/keep_alive_scheduler.cc
@@ -38,7 +38,7 @@
     BleConnectionManager* connection_manager,
     HostScanCache* host_scan_cache,
     DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map,
-    std::unique_ptr<base::Timer> timer)
+    std::unique_ptr<base::RepeatingTimer> timer)
     : device_sync_client_(device_sync_client),
       secure_channel_client_(secure_channel_client),
       active_host_(active_host),
diff --git a/chromeos/components/tether/keep_alive_scheduler.h b/chromeos/components/tether/keep_alive_scheduler.h
index 20c0965..fd36e0e 100644
--- a/chromeos/components/tether/keep_alive_scheduler.h
+++ b/chromeos/components/tether/keep_alive_scheduler.h
@@ -65,7 +65,7 @@
       BleConnectionManager* connection_manager,
       HostScanCache* host_scan_cache,
       DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map,
-      std::unique_ptr<base::Timer> timer);
+      std::unique_ptr<base::RepeatingTimer> timer);
 
   void SendKeepAliveTickle();
 
@@ -78,7 +78,7 @@
   HostScanCache* host_scan_cache_;
   DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map_;
 
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::RepeatingTimer> timer_;
   base::Optional<cryptauth::RemoteDeviceRef> active_host_device_;
   std::unique_ptr<KeepAliveOperation> keep_alive_operation_;
 
diff --git a/chromeos/components/tether/master_host_scan_cache.h b/chromeos/components/tether/master_host_scan_cache.h
index fe6ccee4..a2e9c7e 100644
--- a/chromeos/components/tether/master_host_scan_cache.h
+++ b/chromeos/components/tether/master_host_scan_cache.h
@@ -76,7 +76,7 @@
   // active in the cache, the corresponding Timer object starts running; if the
   // timer fires, the result is removed (unless it corresponds to the active
   // host).
-  std::unordered_map<std::string, std::unique_ptr<base::Timer>>
+  std::unordered_map<std::string, std::unique_ptr<base::OneShotTimer>>
       tether_guid_to_timer_map_;
   base::WeakPtrFactory<MasterHostScanCache> weak_ptr_factory_;
 
diff --git a/chromeos/components/tether/master_host_scan_cache_unittest.cc b/chromeos/components/tether/master_host_scan_cache_unittest.cc
index 7241e64..ab01735c 100644
--- a/chromeos/components/tether/master_host_scan_cache_unittest.cc
+++ b/chromeos/components/tether/master_host_scan_cache_unittest.cc
@@ -69,7 +69,7 @@
   }
 
   // TimerFactory:
-  std::unique_ptr<base::Timer> CreateOneShotTimer() override {
+  std::unique_ptr<base::OneShotTimer> CreateOneShotTimer() override {
     EXPECT_TRUE(!tether_network_guids_for_upcoming_timers_.empty());
 
     // Pop the first GUID off the list of upcoming GUIDs.
diff --git a/chromeos/components/tether/message_transfer_operation.h b/chromeos/components/tether/message_transfer_operation.h
index 5966079..d111b62 100644
--- a/chromeos/components/tether/message_transfer_operation.h
+++ b/chromeos/components/tether/message_transfer_operation.h
@@ -226,7 +226,8 @@
 
   base::flat_map<cryptauth::RemoteDeviceRef, ConnectAttemptCounts>
       remote_device_to_attempts_map_;
-  base::flat_map<cryptauth::RemoteDeviceRef, std::unique_ptr<base::Timer>>
+  base::flat_map<cryptauth::RemoteDeviceRef,
+                 std::unique_ptr<base::OneShotTimer>>
       remote_device_to_timer_map_;
   base::WeakPtrFactory<MessageTransferOperation> weak_ptr_factory_;
 
diff --git a/chromeos/components/tether/message_transfer_operation_unittest.cc b/chromeos/components/tether/message_transfer_operation_unittest.cc
index dd05ab66..295e1a1 100644
--- a/chromeos/components/tether/message_transfer_operation_unittest.cc
+++ b/chromeos/components/tether/message_transfer_operation_unittest.cc
@@ -137,7 +137,7 @@
   ~TestTimerFactory() override = default;
 
   // TimerFactory:
-  std::unique_ptr<base::Timer> CreateOneShotTimer() override {
+  std::unique_ptr<base::OneShotTimer> CreateOneShotTimer() override {
     EXPECT_FALSE(device_id_for_next_timer_.empty());
     base::MockOneShotTimer* mock_timer = new base::MockOneShotTimer();
     device_id_to_timer_map_[device_id_for_next_timer_] = mock_timer;
diff --git a/chromeos/components/tether/timer_factory.cc b/chromeos/components/tether/timer_factory.cc
index 2f4d3d4..b4bc0ab 100644
--- a/chromeos/components/tether/timer_factory.cc
+++ b/chromeos/components/tether/timer_factory.cc
@@ -12,7 +12,7 @@
 
 TimerFactory::~TimerFactory() = default;
 
-std::unique_ptr<base::Timer> TimerFactory::CreateOneShotTimer() {
+std::unique_ptr<base::OneShotTimer> TimerFactory::CreateOneShotTimer() {
   return std::make_unique<base::OneShotTimer>();
 }
 
diff --git a/chromeos/components/tether/timer_factory.h b/chromeos/components/tether/timer_factory.h
index 74d5f68..82a1ef9 100644
--- a/chromeos/components/tether/timer_factory.h
+++ b/chromeos/components/tether/timer_factory.h
@@ -22,7 +22,7 @@
  public:
   virtual ~TimerFactory();
 
-  virtual std::unique_ptr<base::Timer> CreateOneShotTimer();
+  virtual std::unique_ptr<base::OneShotTimer> CreateOneShotTimer();
 };
 
 }  // namespace tether
diff --git a/chromeos/components/tether/wifi_hotspot_connector.cc b/chromeos/components/tether/wifi_hotspot_connector.cc
index fad62e1..92d4a0e 100644
--- a/chromeos/components/tether/wifi_hotspot_connector.cc
+++ b/chromeos/components/tether/wifi_hotspot_connector.cc
@@ -294,7 +294,7 @@
 }
 
 void WifiHotspotConnector::SetTestDoubles(
-    std::unique_ptr<base::Timer> test_timer,
+    std::unique_ptr<base::OneShotTimer> test_timer,
     base::Clock* test_clock,
     scoped_refptr<base::TaskRunner> test_task_runner) {
   timer_ = std::move(test_timer);
diff --git a/chromeos/components/tether/wifi_hotspot_connector.h b/chromeos/components/tether/wifi_hotspot_connector.h
index a7e3f9e..9e3317c 100644
--- a/chromeos/components/tether/wifi_hotspot_connector.h
+++ b/chromeos/components/tether/wifi_hotspot_connector.h
@@ -71,13 +71,13 @@
       const std::string& password);
   void OnConnectionTimeout();
 
-  void SetTestDoubles(std::unique_ptr<base::Timer> test_timer,
+  void SetTestDoubles(std::unique_ptr<base::OneShotTimer> test_timer,
                       base::Clock* test_clock,
                       scoped_refptr<base::TaskRunner> test_task_runner);
 
   NetworkStateHandler* network_state_handler_;
   NetworkConnect* network_connect_;
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
   base::Clock* clock_;
 
   std::string ssid_;
diff --git a/chromeos/services/secure_channel/ble_advertiser_impl.cc b/chromeos/services/secure_channel/ble_advertiser_impl.cc
index bb12dc7..f62e29f 100644
--- a/chromeos/services/secure_channel/ble_advertiser_impl.cc
+++ b/chromeos/services/secure_channel/ble_advertiser_impl.cc
@@ -23,7 +23,7 @@
 BleAdvertiserImpl::ActiveAdvertisementRequest::ActiveAdvertisementRequest(
     DeviceIdPair device_id_pair,
     ConnectionPriority connection_priority,
-    std::unique_ptr<base::Timer> timer)
+    std::unique_ptr<base::OneShotTimer> timer)
     : device_id_pair(device_id_pair),
       connection_priority(connection_priority),
       timer(std::move(timer)) {}
@@ -253,7 +253,8 @@
 
   // Create a timer, and have it go off in kNumSecondsPerAdvertisementTimeslot
   // seconds.
-  std::unique_ptr<base::Timer> timer = timer_factory_->CreateOneShotTimer();
+  std::unique_ptr<base::OneShotTimer> timer =
+      timer_factory_->CreateOneShotTimer();
   timer->Start(
       FROM_HERE,
       base::TimeDelta::FromSeconds(kNumSecondsPerAdvertisementTimeslot),
diff --git a/chromeos/services/secure_channel/ble_advertiser_impl.h b/chromeos/services/secure_channel/ble_advertiser_impl.h
index 2a32cb6..9be3ddb 100644
--- a/chromeos/services/secure_channel/ble_advertiser_impl.h
+++ b/chromeos/services/secure_channel/ble_advertiser_impl.h
@@ -17,7 +17,7 @@
 #include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h"
 
 namespace base {
-class Timer;
+class OneShotTimer;
 }  // namespace base
 
 namespace chromeos {
@@ -71,12 +71,12 @@
   struct ActiveAdvertisementRequest {
     ActiveAdvertisementRequest(DeviceIdPair device_id_pair,
                                ConnectionPriority connection_priority,
-                               std::unique_ptr<base::Timer> timer);
+                               std::unique_ptr<base::OneShotTimer> timer);
     virtual ~ActiveAdvertisementRequest();
 
     DeviceIdPair device_id_pair;
     ConnectionPriority connection_priority;
-    std::unique_ptr<base::Timer> timer;
+    std::unique_ptr<base::OneShotTimer> timer;
 
     DISALLOW_COPY_AND_ASSIGN(ActiveAdvertisementRequest);
   };
diff --git a/chromeos/services/secure_channel/fake_one_shot_timer.h b/chromeos/services/secure_channel/fake_one_shot_timer.h
index e486a21e..d22d13e 100644
--- a/chromeos/services/secure_channel/fake_one_shot_timer.h
+++ b/chromeos/services/secure_channel/fake_one_shot_timer.h
@@ -16,8 +16,8 @@
 
 namespace secure_channel {
 
-// Fake base::Timer implementation, which extends MockTimer and provides a
-// mechanism for alerting its creator when it is destroyed.
+// Fake base::OneShotTimer implementation, which extends MockTimer and provides
+// a mechanism for alerting its creator when it is destroyed.
 class FakeOneShotTimer : public base::MockOneShotTimer {
  public:
   FakeOneShotTimer(base::OnceCallback<void(const base::UnguessableToken&)>
diff --git a/chromeos/services/secure_channel/fake_timer_factory.cc b/chromeos/services/secure_channel/fake_timer_factory.cc
index c221468..ed58219f 100644
--- a/chromeos/services/secure_channel/fake_timer_factory.cc
+++ b/chromeos/services/secure_channel/fake_timer_factory.cc
@@ -16,7 +16,7 @@
 
 FakeTimerFactory::~FakeTimerFactory() = default;
 
-std::unique_ptr<base::Timer> FakeTimerFactory::CreateOneShotTimer() {
+std::unique_ptr<base::OneShotTimer> FakeTimerFactory::CreateOneShotTimer() {
   ++num_instances_created_;
 
   auto fake_one_shot_timer = std::make_unique<FakeOneShotTimer>(
diff --git a/chromeos/services/secure_channel/fake_timer_factory.h b/chromeos/services/secure_channel/fake_timer_factory.h
index 41e3b37..c4a2692 100644
--- a/chromeos/services/secure_channel/fake_timer_factory.h
+++ b/chromeos/services/secure_channel/fake_timer_factory.h
@@ -38,7 +38,7 @@
 
  private:
   // TimerFactory:
-  std::unique_ptr<base::Timer> CreateOneShotTimer() override;
+  std::unique_ptr<base::OneShotTimer> CreateOneShotTimer() override;
 
   void OnOneShotTimerDeleted(const base::UnguessableToken& deleted_timer_id);
 
diff --git a/chromeos/services/secure_channel/timer_factory.h b/chromeos/services/secure_channel/timer_factory.h
index 02a7c074..fc53a23 100644
--- a/chromeos/services/secure_channel/timer_factory.h
+++ b/chromeos/services/secure_channel/timer_factory.h
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 
 namespace base {
-class Timer;
+class OneShotTimer;
 }  // namespace base
 
 namespace chromeos {
@@ -22,7 +22,7 @@
 class TimerFactory {
  public:
   virtual ~TimerFactory() = default;
-  virtual std::unique_ptr<base::Timer> CreateOneShotTimer() = 0;
+  virtual std::unique_ptr<base::OneShotTimer> CreateOneShotTimer() = 0;
 
  protected:
   TimerFactory() = default;
diff --git a/chromeos/services/secure_channel/timer_factory_impl.cc b/chromeos/services/secure_channel/timer_factory_impl.cc
index fe2666b..faa8ec46 100644
--- a/chromeos/services/secure_channel/timer_factory_impl.cc
+++ b/chromeos/services/secure_channel/timer_factory_impl.cc
@@ -36,11 +36,10 @@
 }
 
 TimerFactoryImpl::TimerFactoryImpl() = default;
-;
 
 TimerFactoryImpl::~TimerFactoryImpl() = default;
 
-std::unique_ptr<base::Timer> TimerFactoryImpl::CreateOneShotTimer() {
+std::unique_ptr<base::OneShotTimer> TimerFactoryImpl::CreateOneShotTimer() {
   return std::make_unique<base::OneShotTimer>();
 }
 
diff --git a/chromeos/services/secure_channel/timer_factory_impl.h b/chromeos/services/secure_channel/timer_factory_impl.h
index 9cf7a4c..433ca63 100644
--- a/chromeos/services/secure_channel/timer_factory_impl.h
+++ b/chromeos/services/secure_channel/timer_factory_impl.h
@@ -11,7 +11,7 @@
 #include "chromeos/services/secure_channel/timer_factory.h"
 
 namespace base {
-class Timer;
+class OneShotTimer;
 }  // namespace base
 
 namespace chromeos {
@@ -39,7 +39,7 @@
   TimerFactoryImpl();
 
   // TimerFactory:
-  std::unique_ptr<base::Timer> CreateOneShotTimer() override;
+  std::unique_ptr<base::OneShotTimer> CreateOneShotTimer() override;
 
   DISALLOW_COPY_AND_ASSIGN(TimerFactoryImpl);
 };
diff --git a/components/BUILD.gn b/components/BUILD.gn
index c62e34c..3573d61c 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -180,7 +180,7 @@
   if (is_ios) {
     deps += [
       "//components/autofill/ios/browser:unit_tests",
-      "//components/autofill/ios/fill:unit_tests",
+      "//components/autofill/ios/form_util:unit_tests",
       "//components/image_fetcher/ios:unit_tests",
       "//components/signin/ios/browser:unit_tests",
       "//components/translate/ios/browser:unit_tests",
diff --git a/components/autofill/core/browser/autofill_experiments_unittest.cc b/components/autofill/core/browser/autofill_experiments_unittest.cc
index 94a54cb3..7c8b01d 100644
--- a/components/autofill/core/browser/autofill_experiments_unittest.cc
+++ b/components/autofill/core/browser/autofill_experiments_unittest.cc
@@ -49,7 +49,8 @@
 
 TEST_F(AutofillExperimentsTest, DenyUpload_SyncServiceCannotStart) {
   scoped_feature_list_.InitAndEnableFeature(kAutofillUpstream);
-  sync_service_.SetCanSyncStart(false);
+  sync_service_.SetDisableReasons(
+      syncer::SyncService::DISABLE_REASON_USER_CHOICE);
   EXPECT_FALSE(IsCreditCardUploadEnabled());
 }
 
diff --git a/components/autofill/core/browser/test_sync_service.cc b/components/autofill/core/browser/test_sync_service.cc
index ec294237..8fc0ada 100644
--- a/components/autofill/core/browser/test_sync_service.cc
+++ b/components/autofill/core/browser/test_sync_service.cc
@@ -18,8 +18,8 @@
 
 TestSyncService::~TestSyncService() {}
 
-bool TestSyncService::CanSyncStart() const {
-  return can_sync_start_;
+int TestSyncService::GetDisableReasons() const {
+  return disable_reasons_;
 }
 
 syncer::ModelTypeSet TestSyncService::GetPreferredDataTypes() const {
diff --git a/components/autofill/core/browser/test_sync_service.h b/components/autofill/core/browser/test_sync_service.h
index f90b97a..df67fb2 100644
--- a/components/autofill/core/browser/test_sync_service.h
+++ b/components/autofill/core/browser/test_sync_service.h
@@ -16,7 +16,7 @@
   ~TestSyncService() override;
 
   // FakeSyncService:
-  bool CanSyncStart() const override;
+  int GetDisableReasons() const override;
   syncer::ModelTypeSet GetPreferredDataTypes() const override;
   syncer::ModelTypeSet GetActiveDataTypes() const override;
   bool IsEngineInitialized() const override;
@@ -27,8 +27,8 @@
   const GoogleServiceAuthError& GetAuthError() const override;
   syncer::SyncTokenStatus GetSyncTokenStatus() const override;
 
-  void SetCanSyncStart(bool can_sync_start) {
-    can_sync_start_ = can_sync_start;
+  void SetDisableReasons(int disable_reasons) {
+    disable_reasons_ = disable_reasons;
   }
 
   void SetDataTypes(syncer::ModelTypeSet data_types) {
@@ -56,7 +56,7 @@
   void SetInAuthError(bool is_in_auth_error);
 
  private:
-  bool can_sync_start_ = true;
+  int disable_reasons_ = DISABLE_REASON_NONE;
   // Used as both "preferred" and "active" data types.
   syncer::ModelTypeSet data_types_;
   bool is_engine_initialized_ = true;
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
index f7c032c1..361c8f1 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
@@ -590,6 +590,38 @@
                                    CreateAutofillProfile(merged2)));
 }
 
+TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_NonSimilarProfiles) {
+  AutofillProfile local = ConstructCompleteProfile();
+  local.set_guid(kGuidA);
+  local.SetRawInfo(NAME_FULL, ASCIIToUTF16("John K. Doe, Jr."));
+  local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
+  local.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("K."));
+  local.SetRawInfo(NAME_LAST, ASCIIToUTF16("Doe"));
+  AddAutofillProfilesToTable({local});
+
+  // The remote profile are not similar as the names are different (all other
+  // fields except for guids are identical).
+  AutofillProfileSpecifics remote = ConstructCompleteSpecifics();
+  remote.set_guid(kGuidB);
+  remote.set_name_full(0, "Jane T. Roe, Sr.");
+  remote.set_name_first(0, "Jane");
+  remote.set_name_middle(0, "T.");
+  remote.set_name_last(0, "Roe");
+
+  // The profiles are not similar enough and thus do not get merged.
+  // Expect the local one being synced up and the remote one being added to the
+  // local database.
+  EXPECT_CALL(
+      mock_processor(),
+      Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
+  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+
+  StartSyncing({remote});
+
+  EXPECT_THAT(GetAllLocalData(),
+              UnorderedElementsAre(local, CreateAutofillProfile(remote)));
+}
+
 TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_SimilarProfiles) {
   AutofillProfile local1 = AutofillProfile(kGuidA, kHttpOrigin);
   local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
diff --git a/components/autofill/ios/fill/BUILD.gn b/components/autofill/ios/form_util/BUILD.gn
similarity index 72%
rename from components/autofill/ios/fill/BUILD.gn
rename to components/autofill/ios/form_util/BUILD.gn
index 8797ef1d..9d3ffd52 100644
--- a/components/autofill/ios/fill/BUILD.gn
+++ b/components/autofill/ios/form_util/BUILD.gn
@@ -5,6 +5,21 @@
 import("//ios/web/js_compile.gni")
 import("//testing/test.gni")
 
+source_set("form_util") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "form_activity_observer.h",
+    "form_activity_observer_bridge.h",
+    "form_activity_observer_bridge.mm",
+    "form_activity_tab_helper.h",
+    "form_activity_tab_helper.mm",
+  ]
+  deps = [
+    "//base",
+    "//ios/web/public",
+  ]
+}
+
 source_set("unit_tests") {
   testonly = true
   configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/components/autofill/ios/fill/DEPS b/components/autofill/ios/form_util/DEPS
similarity index 100%
rename from components/autofill/ios/fill/DEPS
rename to components/autofill/ios/form_util/DEPS
diff --git a/components/autofill/ios/fill/fill_js_unittest.mm b/components/autofill/ios/form_util/fill_js_unittest.mm
similarity index 96%
rename from components/autofill/ios/fill/fill_js_unittest.mm
rename to components/autofill/ios/form_util/fill_js_unittest.mm
index c3d22a6..7381bce3 100644
--- a/components/autofill/ios/fill/fill_js_unittest.mm
+++ b/components/autofill/ios/form_util/fill_js_unittest.mm
@@ -6,6 +6,7 @@
 #include <stddef.h>
 
 #include "base/macros.h"
+#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #import "ios/web/public/test/web_js_test.h"
 #import "ios/web/public/test/web_test_with_web_state.h"
@@ -43,7 +44,7 @@
       {@"javascript:login()", @"javascript:login()"},
   };
 
-  for (size_t i = 0; i < arraysize(test_data); i++) {
+  for (size_t i = 0; i < base::size(test_data); i++) {
     TestData& data = test_data[i];
     NSString* html_action =
         data.html_action == nil
diff --git a/components/autofill/ios/form_util/form_activity_observer.h b/components/autofill/ios/form_util/form_activity_observer.h
new file mode 100644
index 0000000..538d616
--- /dev/null
+++ b/components/autofill/ios/form_util/form_activity_observer.h
@@ -0,0 +1,58 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_OBSERVER_H_
+#define COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_OBSERVER_H_
+
+#include <string>
+
+#include "base/macros.h"
+
+namespace web {
+class WebState;
+struct FormActivityParams;
+}  // namespace web
+
+namespace autofill {
+
+// Interface for observing form activity.
+// It is the responsibility of the observer to unregister if the web_state
+// becomes invalid.
+class FormActivityObserver {
+ public:
+  FormActivityObserver() {}
+  virtual ~FormActivityObserver() {}
+
+  // Called when the user is typing on a form field in the main frame or in a
+  // same-origin iframe. |params.input_missing| is indicating if there is any
+  // error when parsing the form field information.
+  // TODO(crbug.com/823285): during the transition from WebStateObserver
+  // to FormActivityObserver, some class will inherit from both interface
+  // so the method need to use a different name. Once the transition is
+  // complete and the methods removed from WebStateObserver, this method
+  // will be renamed to FormActivityRegistered.
+  virtual void OnFormActivity(web::WebState* web_state,
+                              const web::FormActivityParams& params) {}
+
+  // Called on form submission in the main frame or in a same-origin iframe.
+  // |has_user_gesture| is true if the user interacted with the page.
+  // |form_in_main_frame| is true if the submitted form is hosted in the main
+  // frame.
+  // TODO(crbug.com/823285): during the transition from WebStateObserver
+  // to FormActivityObserver, some class will inherit from both interface
+  // so the method need to use a different name. Once the transition is
+  // complete and the methods removed from WebStateObserver, this method
+  // will be renamed to DocumentSubmitted.
+  virtual void DidSubmitDocument(web::WebState* web_state,
+                                 const std::string& form_name,
+                                 bool has_user_gesture,
+                                 bool form_in_main_frame) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FormActivityObserver);
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_OBSERVER_H_
diff --git a/components/autofill/ios/form_util/form_activity_observer_bridge.h b/components/autofill/ios/form_util/form_activity_observer_bridge.h
new file mode 100644
index 0000000..382788f
--- /dev/null
+++ b/components/autofill/ios/form_util/form_activity_observer_bridge.h
@@ -0,0 +1,71 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_OBSERVER_BRIDGE_H_
+#define COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_OBSERVER_BRIDGE_H_
+
+#import <Foundation/Foundation.h>
+
+#include "base/macros.h"
+#include "components/autofill/ios/form_util/form_activity_observer.h"
+
+@protocol FormActivityObserver<NSObject>
+@optional
+// Invoked by WebStateObserverBridge::FormActivity.
+// TODO(crbug.com/823285): during the transition from CRWWebStateObserver
+// to FormActivityObserver, some class will implement from both protocols
+// so the method need to use a different name. Once the transition is
+// complete and the methods removed from CRWWebStateObserver, this method
+// will be renamed to didRegisterFormActivity.
+- (void)webState:(web::WebState*)webState
+    registeredFormActivity:(const web::FormActivityParams&)params;
+
+// Invoked by WebStateObserverBridge::DidSubmitDocument.
+// TODO(crbug.com/823285): during the transition from CRWWebStateObserver
+// to FormActivityObserver, some class will implement from both protocols
+// so the method need to use a different name. Once the transition is
+// complete and the methods removed from CRWWebStateObserver, this method
+// will be renamed to didSubmitDocumentWithFormNamed.
+- (void)webState:(web::WebState*)webState
+    submittedDocumentWithFormNamed:(const std::string&)formName
+                    hasUserGesture:(BOOL)hasUserGesture
+                   formInMainFrame:(BOOL)formInMainFrame;
+
+@end
+
+namespace autofill {
+
+// Use this class to be notified of the form activity in an Objective-C class.
+// Implement the |FormActivityObserver| activity protocol and create a strong
+// member FormActivityObserverBridge
+// form_activity_obserber_bridge_ =
+//     std::make_unique<FormActivityObserverBridge>(web_state, self);
+// It is the responsibility of the owner class to delete this bridge if the
+// web_state becomes invalid.
+class FormActivityObserverBridge : public FormActivityObserver {
+ public:
+  // |owner| will not be retained.
+  FormActivityObserverBridge(web::WebState* web_state,
+                             id<FormActivityObserver> owner);
+  ~FormActivityObserverBridge() override;
+
+  // FormActivityObserver overrides:
+  void OnFormActivity(web::WebState* web_state,
+                      const web::FormActivityParams& params) override;
+
+  void DidSubmitDocument(web::WebState* web_state,
+                         const std::string& form_name,
+                         bool has_user_gesture,
+                         bool form_in_main_frame) override;
+
+ private:
+  web::WebState* web_state_ = nullptr;
+  __weak id<FormActivityObserver> owner_ = nil;
+
+  DISALLOW_COPY_AND_ASSIGN(FormActivityObserverBridge);
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_OBSERVER_BRIDGE_H_
diff --git a/components/autofill/ios/form_util/form_activity_observer_bridge.mm b/components/autofill/ios/form_util/form_activity_observer_bridge.mm
new file mode 100644
index 0000000..0e8bb73
--- /dev/null
+++ b/components/autofill/ios/form_util/form_activity_observer_bridge.mm
@@ -0,0 +1,50 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/ios/form_util/form_activity_observer_bridge.h"
+
+#include "base/logging.h"
+#include "components/autofill/ios/form_util/form_activity_tab_helper.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace autofill {
+FormActivityObserverBridge::FormActivityObserverBridge(
+    web::WebState* web_state,
+    id<FormActivityObserver> owner)
+    : web_state_(web_state), owner_(owner) {
+  FormActivityTabHelper::GetOrCreateForWebState(web_state)->AddObserver(this);
+}
+
+FormActivityObserverBridge::~FormActivityObserverBridge() {
+  FormActivityTabHelper::GetOrCreateForWebState(web_state_)
+      ->RemoveObserver(this);
+}
+
+void FormActivityObserverBridge::OnFormActivity(
+    web::WebState* web_state,
+    const web::FormActivityParams& params) {
+  DCHECK_EQ(web_state, web_state_);
+  if ([owner_ respondsToSelector:@selector(webState:registeredFormActivity:)]) {
+    [owner_ webState:web_state registeredFormActivity:params];
+  }
+}
+
+void FormActivityObserverBridge::DidSubmitDocument(web::WebState* web_state,
+                                                   const std::string& form_name,
+                                                   bool has_user_gesture,
+                                                   bool form_in_main_frame) {
+  DCHECK_EQ(web_state, web_state_);
+  if ([owner_ respondsToSelector:@selector
+              (webState:submittedDocumentWithFormNamed:hasUserGesture
+                          :formInMainFrame:)]) {
+    [owner_ webState:web_state
+        submittedDocumentWithFormNamed:form_name
+                        hasUserGesture:has_user_gesture
+                       formInMainFrame:form_in_main_frame];
+  }
+}
+}  // namespace autofill
diff --git a/components/autofill/ios/form_util/form_activity_tab_helper.h b/components/autofill/ios/form_util/form_activity_tab_helper.h
new file mode 100644
index 0000000..4e65344
--- /dev/null
+++ b/components/autofill/ios/form_util/form_activity_tab_helper.h
@@ -0,0 +1,58 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_TAB_HELPER_H_
+#define COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_TAB_HELPER_H_
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "ios/web/public/web_state/web_state_observer.h"
+#import "ios/web/public/web_state/web_state_user_data.h"
+
+namespace autofill {
+
+class FormActivityObserver;
+
+// Observes user activity on web page forms and forwards form activity event to
+// FormActivityObserver.
+class FormActivityTabHelper
+    : public web::WebStateObserver,
+      public web::WebStateUserData<FormActivityTabHelper> {
+ public:
+  ~FormActivityTabHelper() override;
+
+  static FormActivityTabHelper* GetOrCreateForWebState(
+      web::WebState* web_state);
+
+  // Observer registration methods.
+  void AddObserver(FormActivityObserver* observer);
+  void RemoveObserver(FormActivityObserver* observer);
+
+ private:
+  friend class web::WebStateUserData<FormActivityTabHelper>;
+  explicit FormActivityTabHelper(web::WebState* web_state);
+
+  // WebStateObserver implementation.
+  void WebStateDestroyed(web::WebState* web_state) override;
+
+  void DocumentSubmitted(web::WebState* web_state,
+                         const std::string& form_name,
+                         bool user_initiated,
+                         bool is_main_frame) override;
+  void FormActivityRegistered(web::WebState* web_state,
+                              const web::FormActivityParams& params) override;
+
+  // The WebState this instance is observing. Will be null after
+  // WebStateDestroyed has been called.
+  web::WebState* web_state_ = nullptr;
+
+  // The observers.
+  base::ObserverList<FormActivityObserver> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(FormActivityTabHelper);
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_IOS_FORM_UTIL_FORM_ACTIVITY_TAB_HELPER_H_
diff --git a/components/autofill/ios/form_util/form_activity_tab_helper.mm b/components/autofill/ios/form_util/form_activity_tab_helper.mm
new file mode 100644
index 0000000..f535fcae
--- /dev/null
+++ b/components/autofill/ios/form_util/form_activity_tab_helper.mm
@@ -0,0 +1,70 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/ios/form_util/form_activity_tab_helper.h"
+
+#import <Foundation/Foundation.h>
+
+#include "base/values.h"
+#include "components/autofill/ios/form_util/form_activity_observer.h"
+#include "ios/web/public/web_state/form_activity_params.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+DEFINE_WEB_STATE_USER_DATA_KEY(autofill::FormActivityTabHelper);
+
+namespace autofill {
+
+FormActivityTabHelper::~FormActivityTabHelper() = default;
+
+// static
+FormActivityTabHelper* FormActivityTabHelper::GetOrCreateForWebState(
+    web::WebState* web_state) {
+  FormActivityTabHelper* helper = FromWebState(web_state);
+  if (!helper) {
+    CreateForWebState(web_state);
+    helper = FromWebState(web_state);
+    DCHECK(helper);
+  }
+  return helper;
+}
+
+FormActivityTabHelper::FormActivityTabHelper(web::WebState* web_state)
+    : web_state_(web_state) {
+  web_state_->AddObserver(this);
+}
+
+void FormActivityTabHelper::AddObserver(FormActivityObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void FormActivityTabHelper::RemoveObserver(FormActivityObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void FormActivityTabHelper::FormActivityRegistered(
+    web::WebState* web_state,
+    const web::FormActivityParams& params) {
+  for (auto& observer : observers_)
+    observer.OnFormActivity(web_state, params);
+}
+
+void FormActivityTabHelper::DocumentSubmitted(web::WebState* web_state,
+                                              const std::string& form_name,
+                                              bool user_initiated,
+                                              bool is_main_frame) {
+  for (auto& observer : observers_)
+    observer.DidSubmitDocument(web_state, form_name, user_initiated,
+                               is_main_frame);
+}
+
+void FormActivityTabHelper::WebStateDestroyed(web::WebState* web_state) {
+  DCHECK_EQ(web_state_, web_state);
+  web_state_->RemoveObserver(this);
+  web_state_ = nullptr;
+}
+
+}  // namespace autofill
diff --git a/components/autofill/ios/fill/form_unittest.mm b/components/autofill/ios/form_util/form_unittest.mm
similarity index 100%
rename from components/autofill/ios/fill/form_unittest.mm
rename to components/autofill/ios/form_util/form_unittest.mm
diff --git a/components/autofill/ios/fill/resources/fill.js b/components/autofill/ios/form_util/resources/fill.js
similarity index 100%
rename from components/autofill/ios/fill/resources/fill.js
rename to components/autofill/ios/form_util/resources/fill.js
diff --git a/components/autofill/ios/fill/resources/form.js b/components/autofill/ios/form_util/resources/form.js
similarity index 100%
rename from components/autofill/ios/fill/resources/form.js
rename to components/autofill/ios/form_util/resources/form.js
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index b72b5b9..80e6e45 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -247,17 +247,6 @@
   DCHECK(!engine_initialized_);
 }
 
-bool ProfileSyncService::CanSyncStart() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  int disable_reasons = GetDisableReasons();
-  // An unrecoverable error is currently *not* considered a start-preventing
-  // disable reason, because it occurs after Sync has already started.
-  // TODO(crbug.com/839834): Consider changing this, since Sync shuts down and
-  // won't start up again after an unrecoverable error.
-  disable_reasons = disable_reasons & ~DISABLE_REASON_UNRECOVERABLE_ERROR;
-  return disable_reasons == DISABLE_REASON_NONE;
-}
-
 void ProfileSyncService::Initialize() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   sync_client_->Initialize();
@@ -1337,12 +1326,6 @@
                           weak_factory_.GetWeakPtr()));
 }
 
-bool ProfileSyncService::IsSyncAllowed() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return !HasDisableReason(DISABLE_REASON_PLATFORM_OVERRIDE) &&
-         !HasDisableReason(DISABLE_REASON_ENTERPRISE_POLICY);
-}
-
 bool ProfileSyncService::IsSyncActive() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return engine_initialized_ && data_type_manager_ &&
@@ -1376,11 +1359,6 @@
          data_type_manager_->state() == DataTypeManager::CONFIGURED;
 }
 
-bool ProfileSyncService::HasUnrecoverableError() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return HasDisableReason(DISABLE_REASON_UNRECOVERABLE_ERROR);
-}
-
 bool ProfileSyncService::IsPassphraseRequired() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return crypto_->passphrase_required_reason() !=
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h
index 57c4209..e98a538 100644
--- a/components/browser_sync/profile_sync_service.h
+++ b/components/browser_sync/profile_sync_service.h
@@ -236,12 +236,10 @@
   int GetDisableReasons() const override;
   State GetState() const override;
   bool IsFirstSetupComplete() const override;
-  bool IsSyncAllowed() const override;
   bool IsSyncActive() const override;
   bool IsLocalSyncEnabled() const override;
   void TriggerRefresh(const syncer::ModelTypeSet& types) override;
   void OnDataTypeRequestsSyncStartup(syncer::ModelType type) override;
-  bool CanSyncStart() const override;
   void RequestStop(SyncStopDataFate data_fate) override;
   void RequestStart() override;
   syncer::ModelTypeSet GetActiveDataTypes() const override;
@@ -259,7 +257,6 @@
   bool IsSetupInProgress() const override;
   bool ConfigurationDone() const override;
   const GoogleServiceAuthError& GetAuthError() const override;
-  bool HasUnrecoverableError() const override;
   bool IsEngineInitialized() const override;
   sync_sessions::OpenTabsUIDelegate* GetOpenTabsUIDelegate() override;
   bool IsPassphraseRequiredForDecryption() const override;
diff --git a/components/browser_sync/profile_sync_service_mock.h b/components/browser_sync/profile_sync_service_mock.h
index 1e27cc94..b252e6096 100644
--- a/components/browser_sync/profile_sync_service_mock.h
+++ b/components/browser_sync/profile_sync_service_mock.h
@@ -69,12 +69,12 @@
   MOCK_CONST_METHOD0(GetRegisteredDataTypes, syncer::ModelTypeSet());
   MOCK_CONST_METHOD0(GetLastCycleSnapshot, syncer::SyncCycleSnapshot());
 
+  MOCK_CONST_METHOD0(GetDisableReasons, int());
   MOCK_METHOD1(QueryDetailedSyncStatus,
                bool(syncer::SyncEngine::Status* result));
   MOCK_CONST_METHOD0(GetAuthError, const GoogleServiceAuthError&());
   MOCK_CONST_METHOD0(IsFirstSetupInProgress, bool());
   MOCK_CONST_METHOD0(GetLastSyncedTime, base::Time());
-  MOCK_CONST_METHOD0(HasUnrecoverableError, bool());
   MOCK_CONST_METHOD0(IsSyncActive, bool());
   MOCK_CONST_METHOD0(IsEngineInitialized, bool());
   MOCK_CONST_METHOD0(IsSyncConfirmationNeeded, bool());
@@ -91,9 +91,6 @@
                void(const syncer::DataTypeManager::ConfigureResult&));
   MOCK_METHOD0(OnConfigureStart, void());
 
-  MOCK_CONST_METHOD0(CanSyncStart, bool());
-  MOCK_CONST_METHOD0(IsManaged, bool());
-
   MOCK_CONST_METHOD0(IsPassphraseRequired, bool());
   MOCK_CONST_METHOD0(IsPassphraseRequiredForDecryption, bool());
   MOCK_CONST_METHOD0(IsUsingSecondaryPassphrase, bool());
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
index 1ac0cb8d..d060e23 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
@@ -360,7 +360,7 @@
 
 void BluetoothLowEnergyWeaveClientConnection::SetupTestDoubles(
     scoped_refptr<base::TaskRunner> test_task_runner,
-    std::unique_ptr<base::Timer> test_timer,
+    std::unique_ptr<base::OneShotTimer> test_timer,
     std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> test_generator,
     std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver> test_receiver) {
   task_runner_ = test_task_runner;
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
index 01124aa..716a5384 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
@@ -137,7 +137,7 @@
 
   void SetupTestDoubles(
       scoped_refptr<base::TaskRunner> test_task_runner,
-      std::unique_ptr<base::Timer> test_timer,
+      std::unique_ptr<base::OneShotTimer> test_timer,
       std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator> test_generator,
       std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver> test_receiver);
 
@@ -381,7 +381,7 @@
   RemoteAttribute tx_characteristic_;
   RemoteAttribute rx_characteristic_;
   scoped_refptr<base::TaskRunner> task_runner_;
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
 
   // These pointers start out null and are created during the connection
   // process.
diff --git a/components/cryptauth/device_to_device_authenticator.cc b/components/cryptauth/device_to_device_authenticator.cc
index e723cf18..3e7b038 100644
--- a/components/cryptauth/device_to_device_authenticator.cc
+++ b/components/cryptauth/device_to_device_authenticator.cc
@@ -122,7 +122,7 @@
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
-std::unique_ptr<base::Timer> DeviceToDeviceAuthenticator::CreateTimer() {
+std::unique_ptr<base::OneShotTimer> DeviceToDeviceAuthenticator::CreateTimer() {
   return std::make_unique<base::OneShotTimer>();
 }
 
diff --git a/components/cryptauth/device_to_device_authenticator.h b/components/cryptauth/device_to_device_authenticator.h
index ac34a9c..79ba037 100644
--- a/components/cryptauth/device_to_device_authenticator.h
+++ b/components/cryptauth/device_to_device_authenticator.h
@@ -17,7 +17,7 @@
 #include "components/cryptauth/session_keys.h"
 
 namespace base {
-class Timer;
+class OneShotTimer;
 };
 
 namespace cryptauth {
@@ -85,8 +85,8 @@
   void Authenticate(const AuthenticationCallback& callback) override;
 
  protected:
-  // Creates a base::Timer instance. Exposed for testing.
-  virtual std::unique_ptr<base::Timer> CreateTimer();
+  // Creates a base::OneShotTimer instance. Exposed for testing.
+  virtual std::unique_ptr<base::OneShotTimer> CreateTimer();
 
  private:
   // The current state of the authentication flow.
@@ -164,7 +164,7 @@
   AuthenticationCallback callback_;
 
   // Used for timing out when waiting for [Remote Auth] from the remote device.
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
 
   // The bytes of the [Hello] message sent to the remote device.
   std::string hello_message_;
diff --git a/components/cryptauth/device_to_device_authenticator_unittest.cc b/components/cryptauth/device_to_device_authenticator_unittest.cc
index 650aab3a..a6adc18c 100644
--- a/components/cryptauth/device_to_device_authenticator_unittest.cc
+++ b/components/cryptauth/device_to_device_authenticator_unittest.cc
@@ -126,7 +126,7 @@
 
  private:
   // DeviceToDeviceAuthenticator:
-  std::unique_ptr<base::Timer> CreateTimer() override {
+  std::unique_ptr<base::OneShotTimer> CreateTimer() override {
     auto timer = std::make_unique<base::MockOneShotTimer>();
     timer_ = timer.get();
     return std::move(timer);
diff --git a/components/cryptauth/sync_scheduler_impl.cc b/components/cryptauth/sync_scheduler_impl.cc
index 2fdd9d7..c5f5c31 100644
--- a/components/cryptauth/sync_scheduler_impl.cc
+++ b/components/cryptauth/sync_scheduler_impl.cc
@@ -116,10 +116,8 @@
       std::make_unique<SyncRequest>(weak_ptr_factory_.GetWeakPtr()));
 }
 
-std::unique_ptr<base::Timer> SyncSchedulerImpl::CreateTimer() {
-  bool retain_user_task = false;
-  bool is_repeating = false;
-  return std::make_unique<base::Timer>(retain_user_task, is_repeating);
+std::unique_ptr<base::OneShotTimer> SyncSchedulerImpl::CreateTimer() {
+  return std::make_unique<base::OneShotTimer>();
 }
 
 void SyncSchedulerImpl::ScheduleNextSync(const base::TimeDelta& sync_delta) {
diff --git a/components/cryptauth/sync_scheduler_impl.h b/components/cryptauth/sync_scheduler_impl.h
index 3d61bb00..77ffcd8d 100644
--- a/components/cryptauth/sync_scheduler_impl.h
+++ b/components/cryptauth/sync_scheduler_impl.h
@@ -42,8 +42,8 @@
   SyncState GetSyncState() const override;
 
  protected:
-  // Creates and returns a base::Timer object. Exposed for testing.
-  virtual std::unique_ptr<base::Timer> CreateTimer();
+  // Creates and returns a base::OneShotTimer object. Exposed for testing.
+  virtual std::unique_ptr<base::OneShotTimer> CreateTimer();
 
  private:
   // SyncScheduler:
@@ -92,7 +92,7 @@
   size_t failure_count_;
 
   // Timer firing for the next sync request.
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
 
   base::WeakPtrFactory<SyncSchedulerImpl> weak_ptr_factory_;
 
diff --git a/components/cryptauth/sync_scheduler_impl_unittest.cc b/components/cryptauth/sync_scheduler_impl_unittest.cc
index c16b833..cc3ae12 100644
--- a/components/cryptauth/sync_scheduler_impl_unittest.cc
+++ b/components/cryptauth/sync_scheduler_impl_unittest.cc
@@ -58,7 +58,7 @@
   base::MockOneShotTimer* timer() { return mock_timer_; }
 
  private:
-  std::unique_ptr<base::Timer> CreateTimer() override {
+  std::unique_ptr<base::OneShotTimer> CreateTimer() override {
     mock_timer_ = new base::MockOneShotTimer();
     return base::WrapUnique(mock_timer_);
   }
diff --git a/components/drive/chromeos/file_system.cc b/components/drive/chromeos/file_system.cc
index 1c71be08..0a51341 100644
--- a/components/drive/chromeos/file_system.cc
+++ b/components/drive/chromeos/file_system.cc
@@ -5,6 +5,9 @@
 #include "components/drive/chromeos/file_system.h"
 
 #include <stddef.h>
+#include <limits>
+#include <map>
+#include <set>
 #include <utility>
 
 #include "base/barrier_closure.h"
@@ -886,8 +889,10 @@
         // If we were tracking the update status we can remove that as well.
         last_update_metadata_.erase(change.team_drive_id());
       } else if (change.IsAddOrUpdate()) {
-        DCHECK(team_drive_change_list_loaders_.count(change.team_drive_id()) ==
-               0);
+        // If this is an update (e.g. a renamed team drive), then just erase the
+        // existing entry so we can re-add it with the new path.
+        team_drive_change_list_loaders_.erase(change.team_drive_id());
+
         auto loader = std::make_unique<internal::TeamDriveChangeListLoader>(
             change.team_drive_id(), entry.first, logger_,
             blocking_task_runner_.get(), resource_metadata_, scheduler_,
@@ -956,6 +961,7 @@
                      base::Owned(team_drive_metadata)));
 
   metadata->refreshing = default_corpus_change_list_loader_->IsRefreshing();
+  metadata->path = util::GetDriveGrandRootPath().value();
   metadata->last_update_check_time =
       last_update_metadata_[util::kTeamDriveIdDefaultCorpus]
           .last_update_check_time;
@@ -977,6 +983,7 @@
     FileSystemMetadata& md = (*team_drive_metadata)[team_drive.first];
 
     md.refreshing = team_drive.second->IsRefreshing();
+    md.path = team_drive.second->root_entry_path().value();
     md.last_update_check_time = last_update_metadata.last_update_check_time;
     md.last_update_check_error = last_update_metadata.last_update_check_error;
 
diff --git a/components/drive/file_system_metadata.h b/components/drive/file_system_metadata.h
index c4a514d..54156d2 100644
--- a/components/drive/file_system_metadata.h
+++ b/components/drive/file_system_metadata.h
@@ -30,6 +30,10 @@
 
   // Error code of the last update check.
   FileError last_update_check_error;
+
+  // For team drives, this is the virtual path that the team drive is mounted
+  // at.
+  std::string path;
 };
 
 }  // namespace drive
diff --git a/components/drive/file_system_unittest.cc b/components/drive/file_system_unittest.cc
index a3ec083..0f2ce34 100644
--- a/components/drive/file_system_unittest.cc
+++ b/components/drive/file_system_unittest.cc
@@ -1341,12 +1341,16 @@
 
   EXPECT_EQ(2UL, team_drive_metadata.size());
   EXPECT_FALSE(team_drive_metadata["td_id_1"].refreshing);
+  EXPECT_EQ(util::GetDriveTeamDrivesRootPath().Append("team_drive_1").value(),
+            team_drive_metadata["td_id_1"].path);
   EXPECT_LE(now, team_drive_metadata["td_id_1"].last_update_check_time);
   EXPECT_EQ("654344", team_drive_metadata["td_id_1"].start_page_token);
   EXPECT_EQ(FILE_ERROR_OK,
             team_drive_metadata["td_id_1"].last_update_check_error);
 
   EXPECT_FALSE(team_drive_metadata["td_id_2"].refreshing);
+  EXPECT_EQ(util::GetDriveTeamDrivesRootPath().Append("team_drive_2").value(),
+            team_drive_metadata["td_id_2"].path);
   EXPECT_LE(now, team_drive_metadata["td_id_1"].last_update_check_time);
   EXPECT_EQ("654345", team_drive_metadata["td_id_2"].start_page_token);
   EXPECT_EQ(FILE_ERROR_OK,
diff --git a/components/drive/service/fake_drive_service.cc b/components/drive/service/fake_drive_service.cc
index 9719d66..7707b5d9 100644
--- a/components/drive/service/fake_drive_service.cc
+++ b/components/drive/service/fake_drive_service.cc
@@ -461,6 +461,7 @@
     std::unique_ptr<TeamDriveResource> team_drive(new TeamDriveResource);
     team_drive->set_id(team_drive_value_[i]->id());
     team_drive->set_name(team_drive_value_[i]->name());
+    team_drive->set_capabilities(team_drive_value_[i]->capabilities());
     result->mutable_items()->push_back(std::move(team_drive));
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -1701,6 +1702,37 @@
                                 std::make_unique<FileResource>(*file)));
 }
 
+bool FakeDriveService::SetTeamDriveCapabilities(
+    const std::string& team_drive_id,
+    const google_apis::TeamDriveCapabilities& capabilities) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (offline_) {
+    return false;
+  }
+
+  EntryInfo* entry = FindEntryByResourceId(team_drive_id);
+  if (!entry) {
+    return false;
+  }
+
+  for (size_t i = 0; i < team_drive_value_.size(); ++i) {
+    std::unique_ptr<TeamDriveResource> team_drive(new TeamDriveResource);
+    if (team_drive_value_[i]->id() == team_drive_id) {
+      team_drive_value_[i]->set_capabilities(capabilities);
+    }
+  }
+
+  ChangeResource& change = entry->change_resource;
+  DCHECK_EQ(ChangeResource::TEAM_DRIVE, change.type());
+  TeamDriveResource* team_drive = change.mutable_team_drive();
+  team_drive->set_capabilities(capabilities);
+
+  // Changes to Team Drives are added to the default changelist.
+  AddNewChangestamp(&change, std::string());
+  return true;
+}
+
 google_apis::DriveApiErrorCode FakeDriveService::SetUserPermission(
     const std::string& resource_id,
     google_apis::drive::PermissionRole user_permission) {
@@ -1754,10 +1786,17 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   auto it = entries_.find(resource_id);
+  if (it == entries_.end()) {
+    return nullptr;
+  }
+
   // Deleted entries don't have FileResource.
-  return it != entries_.end() && it->second->change_resource.file()
-             ? it->second.get()
-             : nullptr;
+  if (it->second->change_resource.type() != ChangeResource::TEAM_DRIVE &&
+      !it->second->change_resource.file()) {
+    return nullptr;
+  }
+
+  return it->second.get();
 }
 
 std::string FakeDriveService::GetNewResourceId() {
diff --git a/components/drive/service/fake_drive_service.h b/components/drive/service/fake_drive_service.h
index aaf16e4..3b4c939 100644
--- a/components/drive/service/fake_drive_service.h
+++ b/components/drive/service/fake_drive_service.h
@@ -364,6 +364,12 @@
       const google_apis::FileResourceCapabilities& capabilities,
       const google_apis::FileResourceCallback& callback);
 
+  // Sets the capabilities for the team drive with ID |team_drive_id|.
+  // On success, returns true.
+  bool SetTeamDriveCapabilities(
+      const std::string& team_drive_id,
+      const google_apis::TeamDriveCapabilities& capabilities);
+
   // Sets the user's permission for an entry specified by |resource_id|.
   google_apis::DriveApiErrorCode SetUserPermission(
       const std::string& resource_id,
diff --git a/components/drive/service/fake_drive_service_unittest.cc b/components/drive/service/fake_drive_service_unittest.cc
index 067a4c9..9edf94a 100644
--- a/components/drive/service/fake_drive_service_unittest.cc
+++ b/components/drive/service/fake_drive_service_unittest.cc
@@ -70,7 +70,7 @@
 
 // Creates a new FileResourceCapabilities object with mixed (true/false)
 // capability settings.
-google_apis::FileResourceCapabilities CreateMixedCapabilities() {
+google_apis::FileResourceCapabilities CreateMixedFileCapabilities() {
   google_apis::FileResourceCapabilities capabilities;
   capabilities.set_can_add_children(true);
   capabilities.set_can_change_restricted_download(false);
@@ -92,8 +92,28 @@
   return capabilities;
 }
 
-// Compares two capabilities objects with EXPECT_EQ.
-void ExpectCapabilitiesEqual(
+// Creates a new TeamDriveCapabilities object with mixed (true/false)
+// capability settings.
+google_apis::TeamDriveCapabilities CreateMixedTeamDriveCapabilities() {
+  google_apis::TeamDriveCapabilities capabilities;
+  capabilities.set_can_add_children(true);
+  capabilities.set_can_comment(false);
+  capabilities.set_can_copy(true);
+  capabilities.set_can_delete_team_drive(false);
+  capabilities.set_can_download(true);
+  capabilities.set_can_edit(false);
+  capabilities.set_can_list_children(true);
+  capabilities.set_can_manage_members(false);
+  capabilities.set_can_read_revisions(true);
+  capabilities.set_can_remove_children(false);
+  capabilities.set_can_rename(true);
+  capabilities.set_can_rename_team_drive(false);
+  capabilities.set_can_share(true);
+  return capabilities;
+}
+
+// Compares two FileResourceCapabilities objects with EXPECT_EQ.
+void ExpectFileCapabilitiesEqual(
     const google_apis::FileResourceCapabilities& expectedCapabilities,
     const google_apis::FileResourceCapabilities& actualCapabilities) {
   EXPECT_EQ(expectedCapabilities.can_add_children(),
@@ -126,6 +146,34 @@
             actualCapabilities.can_untrash());
 }
 
+// Compares two FileResourceCapabilities objects with EXPECT_EQ.
+void ExpectTeamDriveCapabilitiesEqual(
+    const google_apis::TeamDriveCapabilities& expectedCapabilities,
+    const google_apis::TeamDriveCapabilities& actualCapabilities) {
+  EXPECT_EQ(expectedCapabilities.can_add_children(),
+            actualCapabilities.can_add_children());
+  EXPECT_EQ(expectedCapabilities.can_comment(),
+            actualCapabilities.can_comment());
+  EXPECT_EQ(expectedCapabilities.can_copy(), actualCapabilities.can_copy());
+  EXPECT_EQ(expectedCapabilities.can_delete_team_drive(),
+            actualCapabilities.can_delete_team_drive());
+  EXPECT_EQ(expectedCapabilities.can_download(),
+            actualCapabilities.can_download());
+  EXPECT_EQ(expectedCapabilities.can_edit(), actualCapabilities.can_edit());
+  EXPECT_EQ(expectedCapabilities.can_list_children(),
+            actualCapabilities.can_list_children());
+  EXPECT_EQ(expectedCapabilities.can_manage_members(),
+            actualCapabilities.can_manage_members());
+  EXPECT_EQ(expectedCapabilities.can_read_revisions(),
+            actualCapabilities.can_read_revisions());
+  EXPECT_EQ(expectedCapabilities.can_remove_children(),
+            actualCapabilities.can_remove_children());
+  EXPECT_EQ(expectedCapabilities.can_rename(), actualCapabilities.can_rename());
+  EXPECT_EQ(expectedCapabilities.can_rename_team_drive(),
+            actualCapabilities.can_rename_team_drive());
+  EXPECT_EQ(expectedCapabilities.can_share(), actualCapabilities.can_share());
+}
+
 class FakeDriveServiceTest : public testing::Test {
  protected:
   // Returns the resource entry that matches |resource_id|.
@@ -2375,7 +2423,7 @@
 
   const std::string kResourceId = "2_file_resource_id";
   const google_apis::FileResourceCapabilities& kCapabilities =
-      CreateMixedCapabilities();
+      CreateMixedFileCapabilities();
 
   DriveApiErrorCode error = DRIVE_OTHER_ERROR;
   std::unique_ptr<FileResource> entry;
@@ -2386,7 +2434,7 @@
 
   EXPECT_EQ(HTTP_SUCCESS, error);
   ASSERT_TRUE(entry);
-  ExpectCapabilitiesEqual(kCapabilities, entry->capabilities());
+  ExpectFileCapabilitiesEqual(kCapabilities, entry->capabilities());
 }
 
 TEST_F(FakeDriveServiceTest, SetFileCapabilities_NonexistingFile) {
@@ -2394,7 +2442,7 @@
 
   const std::string kResourceId = "nonexisting_resource_id";
   const google_apis::FileResourceCapabilities& kCapabilities =
-      CreateMixedCapabilities();
+      CreateMixedFileCapabilities();
 
   DriveApiErrorCode error = DRIVE_OTHER_ERROR;
   std::unique_ptr<FileResource> entry;
@@ -2413,7 +2461,7 @@
 
   const std::string kResourceId = "2_file_resource_id";
   const google_apis::FileResourceCapabilities& kCapabilities =
-      CreateMixedCapabilities();
+      CreateMixedFileCapabilities();
 
   DriveApiErrorCode error = DRIVE_OTHER_ERROR;
   std::unique_ptr<FileResource> entry;
@@ -2426,6 +2474,33 @@
   EXPECT_FALSE(entry);
 }
 
+TEST_F(FakeDriveServiceTest, SetTeamDriveCapabilities_ExistingTeamDrive) {
+  ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
+
+  // Add a new team drive.
+  fake_service_.AddTeamDrive(TEAM_DRIVE_ID_1, TEAM_DRIVE_NAME_1, "");
+
+  const google_apis::TeamDriveCapabilities& kCapabilities =
+      CreateMixedTeamDriveCapabilities();
+  bool result =
+      fake_service_.SetTeamDriveCapabilities(TEAM_DRIVE_ID_1, kCapabilities);
+  EXPECT_TRUE(result);
+  base::RunLoop().RunUntilIdle();
+
+  DriveApiErrorCode error = DRIVE_OTHER_ERROR;
+  std::unique_ptr<TeamDriveList> team_drive_list;
+  fake_service_.GetAllTeamDriveList(
+      test_util::CreateCopyResultCallback(&error, &team_drive_list));
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(HTTP_SUCCESS, error);
+  ASSERT_TRUE(team_drive_list);
+
+  EXPECT_EQ(1U, team_drive_list->items().size());
+  ExpectTeamDriveCapabilitiesEqual(kCapabilities,
+                                   team_drive_list->items()[0]->capabilities());
+}
+
 }  // namespace
 
 }  // namespace drive
diff --git a/components/ntp_snippets/remote/test_utils.cc b/components/ntp_snippets/remote/test_utils.cc
index ea48f1eea..47ec55d 100644
--- a/components/ntp_snippets/remote/test_utils.cc
+++ b/components/ntp_snippets/remote/test_utils.cc
@@ -14,16 +14,15 @@
 namespace test {
 
 FakeSyncService::FakeSyncService()
-    : can_sync_start_(true),
-      is_sync_active_(true),
+    : is_sync_active_(true),
       configuration_done_(true),
       is_encrypt_everything_enabled_(false),
       active_data_types_(syncer::HISTORY_DELETE_DIRECTIVES) {}
 
 FakeSyncService::~FakeSyncService() = default;
 
-bool FakeSyncService::CanSyncStart() const {
-  return can_sync_start_;
+int FakeSyncService::GetDisableReasons() const {
+  return DISABLE_REASON_NONE;
 }
 
 bool FakeSyncService::IsSyncActive() const {
diff --git a/components/ntp_snippets/remote/test_utils.h b/components/ntp_snippets/remote/test_utils.h
index f72f52c..c181cd1 100644
--- a/components/ntp_snippets/remote/test_utils.h
+++ b/components/ntp_snippets/remote/test_utils.h
@@ -24,13 +24,12 @@
   FakeSyncService();
   ~FakeSyncService() override;
 
-  bool CanSyncStart() const override;
+  int GetDisableReasons() const override;
   bool IsSyncActive() const override;
   bool ConfigurationDone() const override;
   bool IsEncryptEverythingEnabled() const override;
   syncer::ModelTypeSet GetActiveDataTypes() const override;
 
-  bool can_sync_start_;
   bool is_sync_active_;
   bool configuration_done_;
   bool is_encrypt_everything_enabled_;
diff --git a/components/password_manager/core/browser/password_bubble_experiment_unittest.cc b/components/password_manager/core/browser/password_bubble_experiment_unittest.cc
index 80dba82..08db7dc 100644
--- a/components/password_manager/core/browser/password_bubble_experiment_unittest.cc
+++ b/components/password_manager/core/browser/password_bubble_experiment_unittest.cc
@@ -25,14 +25,14 @@
 class TestSyncService : public syncer::FakeSyncService {
  public:
   // FakeSyncService overrides.
-  bool IsSyncAllowed() const override { return is_sync_allowed_; }
+  int GetDisableReasons() const override { return disable_reasons_; }
 
   bool IsFirstSetupComplete() const override {
     return is_first_setup_complete_;
   }
 
   bool IsSyncActive() const override {
-    return is_sync_allowed_ && is_first_setup_complete_;
+    return IsSyncAllowed() && is_first_setup_complete_;
   }
 
   syncer::ModelTypeSet GetActiveDataTypes() const override { return type_set_; }
@@ -53,7 +53,9 @@
     type_set_ = type_set;
   }
 
-  void set_sync_allowed(bool sync_allowed) { is_sync_allowed_ = sync_allowed; }
+  void set_disable_reasons(int disable_reasons) {
+    disable_reasons_ = disable_reasons;
+  }
 
   void set_first_setup_complete(bool setup_complete) {
     is_first_setup_complete_ = setup_complete;
@@ -61,12 +63,10 @@
 
   void ClearActiveDataTypes() { type_set_.Clear(); }
 
-  bool CanSyncStart() const override { return true; }
-
  private:
+  int disable_reasons_ = DISABLE_REASON_NONE;
   syncer::ModelTypeSet type_set_;
   bool is_using_secondary_passphrase_ = false;
-  bool is_sync_allowed_ = true;
   bool is_first_setup_complete_ = true;
 };
 
@@ -120,7 +120,10 @@
     prefs()->SetInteger(
         password_manager::prefs::kNumberSignInPasswordPromoShown,
         test_case.current_shown_count);
-    sync_service()->set_sync_allowed(test_case.is_sync_allowed);
+    sync_service()->set_disable_reasons(
+        test_case.is_sync_allowed
+            ? syncer::SyncService::DISABLE_REASON_NONE
+            : syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE);
     sync_service()->set_first_setup_complete(test_case.is_first_setup_complete);
 
     EXPECT_EQ(test_case.result,
diff --git a/components/safe_browsing/triggers/mock_trigger_manager.cc b/components/safe_browsing/triggers/mock_trigger_manager.cc
index 93c061ce..4443c26 100644
--- a/components/safe_browsing/triggers/mock_trigger_manager.cc
+++ b/components/safe_browsing/triggers/mock_trigger_manager.cc
@@ -1,14 +1,14 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style license that can be

-// found in the LICENSE file.

-

-#include "components/safe_browsing/triggers/mock_trigger_manager.h"

-

-namespace safe_browsing {

-

-MockTriggerManager::MockTriggerManager()

-    : TriggerManager(nullptr, nullptr, nullptr) {}

-

-MockTriggerManager::~MockTriggerManager() {}

-

+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/safe_browsing/triggers/mock_trigger_manager.h"
+
+namespace safe_browsing {
+
+MockTriggerManager::MockTriggerManager()
+    : TriggerManager(nullptr, nullptr, nullptr) {}
+
+MockTriggerManager::~MockTriggerManager() {}
+
 }  // namespace safe_browsing
\ No newline at end of file
diff --git a/components/suggestions/suggestions_service_impl_unittest.cc b/components/suggestions/suggestions_service_impl_unittest.cc
index 2c906e3..442f3fc 100644
--- a/components/suggestions/suggestions_service_impl_unittest.cc
+++ b/components/suggestions/suggestions_service_impl_unittest.cc
@@ -85,7 +85,7 @@
  public:
   MockSyncService() {}
   ~MockSyncService() override {}
-  MOCK_CONST_METHOD0(CanSyncStart, bool());
+  MOCK_CONST_METHOD0(GetDisableReasons, int());
   MOCK_CONST_METHOD0(IsSyncActive, bool());
   MOCK_CONST_METHOD0(ConfigurationDone, bool());
   MOCK_CONST_METHOD0(IsLocalSyncEnabled, bool());
@@ -153,9 +153,9 @@
   ~SuggestionsServiceTest() override {}
 
   void SetUp() override {
-    EXPECT_CALL(*sync_service(), CanSyncStart())
+    EXPECT_CALL(*sync_service(), GetDisableReasons())
         .Times(AnyNumber())
-        .WillRepeatedly(Return(true));
+        .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
     EXPECT_CALL(*sync_service(), IsSyncActive())
         .Times(AnyNumber())
         .WillRepeatedly(Return(true));
@@ -408,7 +408,9 @@
 }
 
 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncDisabled) {
-  EXPECT_CALL(*sync_service(), CanSyncStart()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*sync_service(), GetDisableReasons())
+      .Times(AnyNumber())
+      .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_USER_CHOICE));
 
   base::MockCallback<SuggestionsService::ResponseCallback> callback;
   auto subscription = suggestions_service()->AddCallback(callback.Get());
diff --git a/components/sync/driver/about_sync_util_unittest.cc b/components/sync/driver/about_sync_util_unittest.cc
index 7a7a7c65..2f42d68f1 100644
--- a/components/sync/driver/about_sync_util_unittest.cc
+++ b/components/sync/driver/about_sync_util_unittest.cc
@@ -16,9 +16,7 @@
 class SyncServiceMock : public FakeSyncService {
  public:
   bool IsFirstSetupComplete() const override { return true; }
-  bool CanSyncStart() const override { return true; }
 
-  bool HasUnrecoverableError() const override { return true; }
   int GetDisableReasons() const override {
     return DISABLE_REASON_UNRECOVERABLE_ERROR;
   }
diff --git a/components/sync/driver/fake_sync_service.cc b/components/sync/driver/fake_sync_service.cc
index e659d11..d80fd1c 100644
--- a/components/sync/driver/fake_sync_service.cc
+++ b/components/sync/driver/fake_sync_service.cc
@@ -31,7 +31,8 @@
 FakeSyncService::~FakeSyncService() {}
 
 int FakeSyncService::GetDisableReasons() const {
-  return DISABLE_REASON_NONE;
+  // Note: Most subclasses will want to override this.
+  return DISABLE_REASON_PLATFORM_OVERRIDE;
 }
 
 syncer::SyncService::State FakeSyncService::GetState() const {
@@ -68,10 +69,6 @@
   return false;
 }
 
-bool FakeSyncService::IsSyncAllowed() const {
-  return false;
-}
-
 bool FakeSyncService::IsSyncActive() const {
   return false;
 }
@@ -98,10 +95,6 @@
   return false;
 }
 
-bool FakeSyncService::CanSyncStart() const {
-  return false;
-}
-
 void FakeSyncService::OnDataTypeRequestsSyncStartup(ModelType type) {}
 
 void FakeSyncService::RequestStop(SyncService::SyncStopDataFate data_fate) {}
@@ -138,10 +131,6 @@
   return error_;
 }
 
-bool FakeSyncService::HasUnrecoverableError() const {
-  return false;
-}
-
 bool FakeSyncService::IsEngineInitialized() const {
   return false;
 }
diff --git a/components/sync/driver/fake_sync_service.h b/components/sync/driver/fake_sync_service.h
index 6e70844..026d468 100644
--- a/components/sync/driver/fake_sync_service.h
+++ b/components/sync/driver/fake_sync_service.h
@@ -38,7 +38,6 @@
   int GetDisableReasons() const override;
   State GetState() const override;
   bool IsFirstSetupComplete() const override;
-  bool IsSyncAllowed() const override;
   bool IsSyncActive() const override;
   bool IsLocalSyncEnabled() const override;
   void TriggerRefresh(const ModelTypeSet& types) override;
@@ -48,7 +47,6 @@
   void RemoveObserver(SyncServiceObserver* observer) override;
   bool HasObserver(const SyncServiceObserver* observer) const override;
   void OnDataTypeRequestsSyncStartup(ModelType type) override;
-  bool CanSyncStart() const override;
   void RequestStop(SyncService::SyncStopDataFate data_fate) override;
   void RequestStart() override;
   ModelTypeSet GetPreferredDataTypes() const override;
@@ -61,7 +59,6 @@
   bool IsSetupInProgress() const override;
   bool ConfigurationDone() const override;
   const GoogleServiceAuthError& GetAuthError() const override;
-  bool HasUnrecoverableError() const override;
   bool IsEngineInitialized() const override;
   sync_sessions::OpenTabsUIDelegate* GetOpenTabsUIDelegate() override;
   bool IsPassphraseRequiredForDecryption() const override;
diff --git a/components/sync/driver/resources/about.js b/components/sync/driver/resources/about.js
index b4b4769..6551e6fd 100644
--- a/components/sync/driver/resources/about.js
+++ b/components/sync/driver/resources/about.js
@@ -191,7 +191,16 @@
    * @param {MouseEvent} e the click event that triggered the toggle.
    */
   function expandListener(e) {
-    e.target.classList.toggle('traffic-event-entry-expanded');
+    if (e.target.classList.contains("proto")) {
+      // We ignore proto clicks to keep it copyable.
+      return;
+    }
+    var traffic_event_div = e.target;
+    // Click might be on div's child.
+    if (traffic_event_div.nodeName != "DIV") {
+      traffic_event_div = traffic_event_div.parentNode;
+    }
+    traffic_event_div.classList.toggle('traffic-event-entry-expanded');
   }
 
   /**
diff --git a/components/sync/driver/resources/traffic_log.js b/components/sync/driver/resources/traffic_log.js
index fae2ff9..03530944 100644
--- a/components/sync/driver/resources/traffic_log.js
+++ b/components/sync/driver/resources/traffic_log.js
@@ -53,11 +53,21 @@
 
   /**
    * Toggles the given traffic event entry div's "expanded" state.
-   * @param {MouseEvent} e
+   * @param {MouseEvent} e the click event that triggered the toggle.
    * @private
    */
   _expandListener(e) {
-    e.target.classList.toggle('traffic-event-entry-expanded-fullscreen');
+    if (e.target.classList.contains("proto")) {
+      // We ignore proto clicks to keep it copyable.
+      return;
+    }
+    var traffic_event_div = e.target;
+    // Click might be on div's child.
+    if (traffic_event_div.nodeName != "DIV") {
+      traffic_event_div = traffic_event_div.parentNode;
+    }
+    traffic_event_div.classList.toggle(
+      'traffic-event-entry-expanded-fullscreen');
   }
 
   /**
diff --git a/components/sync/driver/sync_service.cc b/components/sync/driver/sync_service.cc
index 262cf510..ee753cea 100644
--- a/components/sync/driver/sync_service.cc
+++ b/components/sync/driver/sync_service.cc
@@ -13,4 +13,23 @@
   on_destroy_.Run();
 }
 
+bool SyncService::CanSyncStart() const {
+  int disable_reasons = GetDisableReasons();
+  // An unrecoverable error is currently *not* considered a start-preventing
+  // disable reason, because it occurs after Sync has already started.
+  // TODO(crbug.com/839834): Consider changing this, since Sync shuts down and
+  // won't start up again after an unrecoverable error.
+  disable_reasons = disable_reasons & ~DISABLE_REASON_UNRECOVERABLE_ERROR;
+  return disable_reasons == DISABLE_REASON_NONE;
+}
+
+bool SyncService::IsSyncAllowed() const {
+  return !HasDisableReason(DISABLE_REASON_PLATFORM_OVERRIDE) &&
+         !HasDisableReason(DISABLE_REASON_ENTERPRISE_POLICY);
+}
+
+bool SyncService::HasUnrecoverableError() const {
+  return HasDisableReason(DISABLE_REASON_UNRECOVERABLE_ERROR);
+}
+
 }  // namespace syncer
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h
index 32366672..a014319 100644
--- a/components/sync/driver/sync_service.h
+++ b/components/sync/driver/sync_service.h
@@ -180,11 +180,10 @@
   // use GetState instead.
   virtual bool IsFirstSetupComplete() const = 0;
 
-  // Whether sync is allowed to start. Command line flags, platform-level
-  // overrides, and account-level overrides are examples of reasons this
-  // might be false.
-  // DEPRECATED! Use GetDisableReasons instead.
-  virtual bool IsSyncAllowed() const = 0;
+  // DEPRECATED! Use GetDisableReasons/HasDisableReason instead.
+  // Equivalent to "!HasDisableReason(DISABLE_REASON_PLATFORM_OVERRIDE) &&
+  // !HasDisableReason(DISABLE_REASON_ENTERPRISE_POLICY)".
+  bool IsSyncAllowed() const;
 
   // Returns true if sync is fully initialized and active. This implies that
   // an initial configuration has successfully completed, although there may
@@ -231,12 +230,11 @@
   // told to MergeDataAndStartSyncing yet.
   virtual void OnDataTypeRequestsSyncStartup(ModelType type) = 0;
 
-  // Returns true if sync is allowed, requested, and the user is logged in.
-  // (being logged in does not mean that tokens are available - tokens may
-  // be missing because they have not loaded yet, or because they were deleted
-  // due to http://crbug.com/121755).
-  // DEPRECATED! Use GetState instead.
-  virtual bool CanSyncStart() const = 0;
+  // DEPRECATED! Use GetDisableReasons/HasDisableReason instead.
+  // Equivalent to having no disable reasons except UNRECOVERABLE_ERROR, i.e.
+  // "(GetDisableReasons() & ~DISABLE_REASON_UNRECOVERABLE_ERROR) ==
+  // DISABLE_REASON_NONE".
+  bool CanSyncStart() const;
 
   // Stops sync at the user's request. |data_fate| controls whether the sync
   // engine should clear its data directory when it shuts down. Generally
@@ -292,8 +290,9 @@
 
   virtual const GoogleServiceAuthError& GetAuthError() const = 0;
 
-  // DEPRECATED! Use GetDisableReasons instead.
-  virtual bool HasUnrecoverableError() const = 0;
+  // DEPRECATED! Use GetDisableReasons/HasDisableReason instead.
+  // Equivalent to "HasDisableReason(DISABLE_REASON_UNRECOVERABLE_ERROR)".
+  bool HasUnrecoverableError() const;
 
   // Returns true if the SyncEngine has told us it's ready to accept changes.
   // DEPRECATED! Use GetState instead.
diff --git a/components/sync/driver/sync_service_utils_unittest.cc b/components/sync/driver/sync_service_utils_unittest.cc
index 76f4d874..e26224d 100644
--- a/components/sync/driver/sync_service_utils_unittest.cc
+++ b/components/sync/driver/sync_service_utils_unittest.cc
@@ -17,7 +17,9 @@
   TestSyncService() = default;
   ~TestSyncService() override = default;
 
-  void SetSyncAllowed(bool allowed) { sync_allowed_ = allowed; }
+  void SetDisableReasons(int disable_reasons) {
+    disable_reasons_ = disable_reasons;
+  }
   void SetSyncActive(bool active) { sync_active_ = active; }
   void SetLocalSyncEnabled(bool local) { local_sync_enabled_ = local; }
   void SetPreferredDataTypes(const ModelTypeSet& types) {
@@ -33,8 +35,7 @@
   void SetSyncCycleComplete(bool complete) { sync_cycle_complete_ = complete; }
 
   // SyncService implementation.
-  bool IsSyncAllowed() const override { return sync_allowed_; }
-  bool CanSyncStart() const override { return sync_allowed_; }
+  int GetDisableReasons() const override { return disable_reasons_; }
   bool IsSyncActive() const override { return sync_active_; }
   bool IsLocalSyncEnabled() const override { return local_sync_enabled_; }
   ModelTypeSet GetPreferredDataTypes() const override {
@@ -75,7 +76,7 @@
   }
 
  private:
-  bool sync_allowed_ = false;
+  int disable_reasons_ = DISABLE_REASON_PLATFORM_OVERRIDE;
   bool sync_active_ = false;
   bool sync_cycle_complete_ = false;
   bool local_sync_enabled_ = false;
@@ -90,7 +91,8 @@
 
   // If sync is not allowed, uploading should never be enabled, even if
   // configuration is done and all the data types are enabled.
-  service.SetSyncAllowed(false);
+  service.SetDisableReasons(
+      syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
 
   service.SetConfigurationDone(true);
   service.SetPreferredDataTypes(ProtocolTypes());
@@ -101,7 +103,7 @@
 
   // Once sync gets allowed (e.g. policy is updated), uploading should not be
   // disabled anymore (though not necessarily active yet).
-  service.SetSyncAllowed(true);
+  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
 
   EXPECT_NE(UploadState::NOT_ACTIVE,
             GetUploadToGoogleState(&service, syncer::BOOKMARKS));
@@ -110,7 +112,7 @@
 TEST(SyncServiceUtilsTest,
      UploadToGoogleInitializingUntilConfiguredAndActiveAndSyncCycleComplete) {
   TestSyncService service;
-  service.SetSyncAllowed(true);
+  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
 
@@ -135,7 +137,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledForModelType) {
   TestSyncService service;
-  service.SetSyncAllowed(true);
+  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
   service.SetConfigurationDone(true);
   service.SetSyncActive(true);
   service.SetSyncCycleComplete(true);
@@ -159,7 +161,7 @@
 TEST(SyncServiceUtilsTest,
      UploadToGoogleDisabledForModelTypeThatFailedToStart) {
   TestSyncService service;
-  service.SetSyncAllowed(true);
+  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
   service.SetConfigurationDone(true);
   service.SetSyncActive(true);
   service.SetSyncCycleComplete(true);
@@ -181,7 +183,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfLocalSyncEnabled) {
   TestSyncService service;
-  service.SetSyncAllowed(true);
+  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
   service.SetSyncActive(true);
@@ -202,7 +204,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledOnPersistentAuthError) {
   TestSyncService service;
-  service.SetSyncAllowed(true);
+  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
   service.SetSyncActive(true);
@@ -242,7 +244,7 @@
 
 TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfCustomPassphraseInUse) {
   TestSyncService service;
-  service.SetSyncAllowed(true);
+  service.SetDisableReasons(syncer::SyncService::DISABLE_REASON_NONE);
   service.SetPreferredDataTypes(ProtocolTypes());
   service.SetActiveDataTypes(ProtocolTypes());
   service.SetSyncActive(true);
diff --git a/components/unified_consent/unified_consent_service_unittest.cc b/components/unified_consent/unified_consent_service_unittest.cc
index b81a988..3a09e3c 100644
--- a/components/unified_consent/unified_consent_service_unittest.cc
+++ b/components/unified_consent/unified_consent_service_unittest.cc
@@ -20,7 +20,7 @@
 
 class TestSyncService : public syncer::FakeSyncService {
  public:
-  bool IsSyncAllowed() const override { return true; }
+  int GetDisableReasons() const override { return DISABLE_REASON_NONE; }
 };
 
 class UnifiedConsentServiceTest : public testing::Test,
diff --git a/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc b/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc
index fe58e83d..49a6f8f 100644
--- a/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc
+++ b/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc
@@ -30,8 +30,7 @@
   }
 
   // syncer::FakeSyncService:
-  bool IsSyncAllowed() const override { return true; }
-  bool CanSyncStart() const override { return true; }
+  int GetDisableReasons() const override { return DISABLE_REASON_NONE; }
   syncer::ModelTypeSet GetPreferredDataTypes() const override {
     return syncer::ModelTypeSet(syncer::ModelType::HISTORY_DELETE_DIRECTIVES,
                                 syncer::ModelType::USER_EVENTS);
diff --git a/components/variations/field_trial_config/BUILD.gn b/components/variations/field_trial_config/BUILD.gn
index 5dcae68c..785afb4 100644
--- a/components/variations/field_trial_config/BUILD.gn
+++ b/components/variations/field_trial_config/BUILD.gn
@@ -28,6 +28,13 @@
     "--platform=" + current_os,
     "--output=$out_name",
   ]
+
+  # At build-time, Chrome and WebView both use platform "android", but at
+  # run-time, variations hase separate platforms "android" and "android_webview".
+  # So if building "android", also include WebView.
+  if (current_os == "android") {
+    args += [ "--platform=android_webview" ]
+  }
 }
 
 static_library("field_trial_config") {
@@ -42,8 +49,11 @@
     ":field_trial_testing_config_action",
     "//base",
     "//components/variations",
+    "//components/variations/proto:proto",
     "//net",
   ]
+
+  public_deps = [ "//third_party/protobuf:protobuf_lite" ]
 }
 
 source_set("unit_tests") {
diff --git a/components/variations/field_trial_config/field_trial_testing_config_schema.json b/components/variations/field_trial_config/field_trial_testing_config_schema.json
index 31419f0b..51bfe19 100644
--- a/components/variations/field_trial_config/field_trial_testing_config_schema.json
+++ b/components/variations/field_trial_config/field_trial_testing_config_schema.json
@@ -4,6 +4,7 @@
 
 {
   "type_name": "FieldTrialTestingConfig",
+  "headers": ["components/variations/proto/study.pb.h"],
   "schema": [{
     "field": "studies",
     "type": "array",
@@ -21,6 +22,11 @@
             "fields": [
               {"field": "name", "type": "string"},
               {
+                "field": "platforms",
+                "type": "array",
+                "contents": {"type": "enum", "ctype": "Study::Platform"}
+              },
+              {
                 "field": "params",
                 "type": "array",
                 "contents": {
diff --git a/components/variations/field_trial_config/field_trial_util.cc b/components/variations/field_trial_config/field_trial_util.cc
index 4ee47dc..a77d5c8e 100644
--- a/components/variations/field_trial_config/field_trial_util.cc
+++ b/components/variations/field_trial_config/field_trial_util.cc
@@ -6,7 +6,10 @@
 
 #include <stddef.h>
 
+#include <map>
+#include <set>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/command_line.h"
@@ -21,6 +24,15 @@
 namespace variations {
 namespace {
 
+bool HasPlatform(const FieldTrialTestingExperiment& experiment,
+                 Study::Platform platform) {
+  for (size_t i = 0; i < experiment.platforms_size; ++i) {
+    if (experiment.platforms[i] == platform)
+      return true;
+  }
+  return false;
+}
+
 void AssociateParamsFromExperiment(
     const std::string& study_name,
     const FieldTrialTestingExperiment& experiment,
@@ -55,27 +67,35 @@
   }
 }
 
-// Chooses an experiment taking into account the command line. Defaults to
-// picking the first experiment.
-const FieldTrialTestingExperiment& ChooseExperiment(
-    const FieldTrialTestingExperiment experiments[],
-    size_t experiment_size) {
-  DCHECK_GT(experiment_size, 0ul);
+// Choose an experiment to associate. The rules are:
+// - Out of the experiments which match this platform:
+//   - If there is a forcing flag for any experiment, choose the first such
+//     experiment.
+//   - Otherwise, choose the first experiment.
+// - If no experiments match this platform, do not associate any of them.
+void ChooseExperiment(const FieldTrialTestingStudy& study,
+                      base::FeatureList* feature_list,
+                      Study::Platform platform) {
   const auto& command_line = *base::CommandLine::ForCurrentProcess();
-  size_t chosen_index = 0;
-  for (size_t i = 1; i < experiment_size && chosen_index == 0; ++i) {
-    const auto& experiment = experiments[i];
-    if (experiment.forcing_flag &&
-        command_line.HasSwitch(experiment.forcing_flag)) {
-      chosen_index = i;
-      break;
+  const FieldTrialTestingExperiment* chosen_experiment = nullptr;
+  for (size_t i = 0; i < study.experiments_size; ++i) {
+    const FieldTrialTestingExperiment* experiment = study.experiments + i;
+    if (HasPlatform(*experiment, platform)) {
+      if (!chosen_experiment)
+        chosen_experiment = experiment;
+
+      if (experiment->forcing_flag &&
+          command_line.HasSwitch(experiment->forcing_flag)) {
+        chosen_experiment = experiment;
+        break;
+      }
     }
   }
-  DCHECK_GT(experiment_size, chosen_index);
-  return experiments[chosen_index];
+  if (chosen_experiment)
+    AssociateParamsFromExperiment(study.name, *chosen_experiment, feature_list);
 }
 
-} // namespace
+}  // namespace
 
 std::string UnescapeValue(const std::string& value) {
   return net::UnescapeURLComponent(
@@ -156,22 +176,22 @@
 }
 
 void AssociateParamsFromFieldTrialConfig(const FieldTrialTestingConfig& config,
-                                         base::FeatureList* feature_list) {
+                                         base::FeatureList* feature_list,
+                                         Study::Platform platform) {
   for (size_t i = 0; i < config.studies_size; ++i) {
     const FieldTrialTestingStudy& study = config.studies[i];
     if (study.experiments_size > 0) {
-      AssociateParamsFromExperiment(
-          study.name,
-          ChooseExperiment(study.experiments, study.experiments_size),
-          feature_list);
+      ChooseExperiment(study, feature_list, platform);
     } else {
       DLOG(ERROR) << "Unexpected empty study: " << study.name;
     }
   }
 }
 
-void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list) {
-  AssociateParamsFromFieldTrialConfig(kFieldTrialConfig, feature_list);
+void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list,
+                                      Study::Platform platform) {
+  AssociateParamsFromFieldTrialConfig(kFieldTrialConfig, feature_list,
+                                      platform);
 }
 
 }  // namespace variations
diff --git a/components/variations/field_trial_config/field_trial_util.h b/components/variations/field_trial_config/field_trial_util.h
index 053a049..1cbbb39a 100644
--- a/components/variations/field_trial_config/field_trial_util.h
+++ b/components/variations/field_trial_config/field_trial_util.h
@@ -7,6 +7,8 @@
 
 #include <string>
 
+#include "components/variations/proto/study.pb.h"
+
 namespace base {
 class FeatureList;
 }
@@ -33,12 +35,14 @@
 // of FieldTrial groups specified in the |config|. Registers features associated
 // with default field trials with |feature_list|.
 void AssociateParamsFromFieldTrialConfig(const FieldTrialTestingConfig& config,
-                                         base::FeatureList* feature_list);
+                                         base::FeatureList* feature_list,
+                                         Study::Platform platform);
 
 // Associates params and features to FieldTrial groups and forces the selection
 // of groups specified in testing/variations/fieldtrial_testing_config.json.
 // Registers features associated with default field trials with |feature_list|.
-void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list);
+void AssociateDefaultFieldTrialConfig(base::FeatureList* feature_list,
+                                      Study::Platform platform);
 
 }  // namespace variations
 
diff --git a/components/variations/field_trial_config/field_trial_util_unittest.cc b/components/variations/field_trial_config/field_trial_util_unittest.cc
index c27a7c7..3cea9ba 100644
--- a/components/variations/field_trial_config/field_trial_util_unittest.cc
+++ b/components/variations/field_trial_config/field_trial_util_unittest.cc
@@ -4,12 +4,14 @@
 
 #include "components/variations/field_trial_config/field_trial_util.h"
 
+#include <map>
 #include <memory>
 #include <utility>
 
 #include "base/command_line.h"
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
+#include "base/stl_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "components/variations/field_trial_config/fieldtrial_testing_config.h"
 #include "components/variations/variations_associated_data.h"
@@ -62,19 +64,20 @@
 }
 
 TEST_F(FieldTrialUtilTest, AssociateParamsFromFieldTrialConfig) {
+  const Study::Platform platform = Study::PLATFORM_LINUX;
   const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params_0[] =
       {{"x", "1"}, {"y", "2"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
-      {"TestGroup1", array_kFieldTrialConfig_params_0, 2, nullptr, 0,
-       nullptr, 0, nullptr},
+      {"TestGroup1", &platform, 1, array_kFieldTrialConfig_params_0, 2,
+       nullptr, 0, nullptr, 0, nullptr},
   };
   const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params_1[] =
       {{"x", "3"}, {"y", "4"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
-      {"TestGroup2", array_kFieldTrialConfig_params_0, 2, nullptr, 0,
-       nullptr, 0, nullptr},
-      {"TestGroup2-2", array_kFieldTrialConfig_params_1, 2, nullptr, 0,
-       nullptr, 0, nullptr},
+      {"TestGroup2", &platform, 1, array_kFieldTrialConfig_params_0, 2,
+       nullptr, 0, nullptr, 0, nullptr},
+      {"TestGroup2-2", &platform, 1, array_kFieldTrialConfig_params_1, 2,
+       nullptr, 0, nullptr, 0, nullptr},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
       {"TestTrial1", array_kFieldTrialConfig_experiments_0, 1},
@@ -85,7 +88,7 @@
   };
 
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list);
+  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
 
   EXPECT_EQ("1", GetVariationParamValue("TestTrial1", "x"));
   EXPECT_EQ("2", GetVariationParamValue("TestTrial1", "y"));
@@ -100,6 +103,115 @@
   EXPECT_EQ("TestGroup2", base::FieldTrialList::FindFullName("TestTrial2"));
 }
 
+TEST_F(FieldTrialUtilTest,
+       AssociateParamsFromFieldTrialConfigWithEachPlatform) {
+  const Study::Platform all_platforms[] = {
+      Study::PLATFORM_ANDROID,
+      Study::PLATFORM_ANDROID_WEBVIEW,
+      Study::PLATFORM_CHROMEOS,
+      Study::PLATFORM_FUCHSIA,
+      Study::PLATFORM_IOS,
+      Study::PLATFORM_LINUX,
+      Study::PLATFORM_MAC,
+      Study::PLATFORM_WINDOWS,
+  };
+
+  // Break if platforms are added without updating |all_platforms|.
+  static_assert(base::size(all_platforms) == Study::Platform_ARRAYSIZE,
+                "|all_platforms| must include all platforms.");
+
+  const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params[] =
+      {{"x", "1"}, {"y", "2"}};
+
+  for (size_t i = 0; i < base::size(all_platforms); ++i) {
+    const Study::Platform platform = all_platforms[i];
+    const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
+        {"TestGroup", &platform, 1,
+         array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr},
+    };
+    const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
+        {"TestTrial", array_kFieldTrialConfig_experiments, 1}
+    };
+    const FieldTrialTestingConfig kConfig = {
+        array_kFieldTrialConfig_studies, 1
+    };
+
+    base::FeatureList feature_list;
+    AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
+
+    EXPECT_EQ("1", GetVariationParamValue("TestTrial", "x"));
+    EXPECT_EQ("2", GetVariationParamValue("TestTrial", "y"));
+
+    std::map<std::string, std::string> params;
+    EXPECT_TRUE(GetVariationParams("TestTrial", &params));
+    EXPECT_EQ(2U, params.size());
+    EXPECT_EQ("1", params["x"]);
+    EXPECT_EQ("2", params["y"]);
+
+    EXPECT_EQ("TestGroup", base::FieldTrialList::FindFullName("TestTrial"));
+  }
+}
+
+TEST_F(FieldTrialUtilTest,
+       AssociateParamsFromFieldTrialConfigWithDifferentPlatform) {
+  const Study::Platform platform = Study::PLATFORM_ANDROID;
+  const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params[] =
+      {{"x", "1"}, {"y", "2"}};
+  const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
+      {"TestGroup", &platform, 1, array_kFieldTrialConfig_params, 2, nullptr, 0,
+       nullptr, 0, nullptr},
+  };
+  const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] =
+      {{"TestTrial", array_kFieldTrialConfig_experiments, 1}};
+  const FieldTrialTestingConfig kConfig =
+      {array_kFieldTrialConfig_studies, 1};
+
+  // The platforms don't match, so trial shouldn't be added.
+  base::FeatureList feature_list;
+  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list,
+                                      Study::PLATFORM_ANDROID_WEBVIEW);
+
+  EXPECT_EQ("", GetVariationParamValue("TestTrial", "x"));
+  EXPECT_EQ("", GetVariationParamValue("TestTrial", "y"));
+
+  std::map<std::string, std::string> params;
+  EXPECT_FALSE(GetVariationParams("TestTrial", &params));
+
+  EXPECT_EQ("", base::FieldTrialList::FindFullName("TestTrial"));
+}
+
+TEST_F(FieldTrialUtilTest,
+       AssociateParamsFromFieldTrialConfigWithMultiplePlatforms) {
+  const Study::Platform platforms[] =
+      {Study::PLATFORM_ANDROID, Study::PLATFORM_ANDROID_WEBVIEW};
+  const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params[] =
+      {{"x", "1"}, {"y", "2"}};
+  const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
+      {"TestGroup", platforms, 2, array_kFieldTrialConfig_params, 2, nullptr, 0,
+       nullptr, 0, nullptr},
+  };
+  const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] =
+      {{"TestTrial", array_kFieldTrialConfig_experiments, 1}};
+  const FieldTrialTestingConfig kConfig =
+      {array_kFieldTrialConfig_studies, 1};
+
+  // One of the platforms matches, so trial should be added.
+  base::FeatureList feature_list;
+  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list,
+                                      Study::PLATFORM_ANDROID_WEBVIEW);
+
+  EXPECT_EQ("1", GetVariationParamValue("TestTrial", "x"));
+  EXPECT_EQ("2", GetVariationParamValue("TestTrial", "y"));
+
+  std::map<std::string, std::string> params;
+  EXPECT_TRUE(GetVariationParams("TestTrial", &params));
+  EXPECT_EQ(2U, params.size());
+  EXPECT_EQ("1", params["x"]);
+  EXPECT_EQ("2", params["y"]);
+
+  EXPECT_EQ("TestGroup", base::FieldTrialList::FindFullName("TestTrial"));
+}
+
 TEST_F(FieldTrialUtilTest, AssociateFeaturesFromFieldTrialConfig) {
   const base::Feature kFeatureA{"A", base::FEATURE_DISABLED_BY_DEFAULT};
   const base::Feature kFeatureB{"B", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -109,12 +221,16 @@
   const char* enable_features[] = {"A", "B"};
   const char* disable_features[] = {"C", "D"};
 
+  const Study::Platform platform = Study::PLATFORM_LINUX;
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
-      {"TestGroup1", nullptr, 0, enable_features, 2, nullptr, 0, nullptr},
+      {"TestGroup1", &platform, 1, nullptr, 0, enable_features, 2, nullptr, 0,
+       nullptr},
   };
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
-      {"TestGroup2", nullptr, 0, nullptr, 0, disable_features, 2, nullptr},
-      {"TestGroup2-2", nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
+      {"TestGroup2", &platform, 1, nullptr, 0, nullptr, 0, disable_features, 2,
+       nullptr},
+      {"TestGroup2-2", &platform, 1, nullptr, 0, nullptr, 0, nullptr, 0,
+       nullptr},
   };
 
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
@@ -127,7 +243,7 @@
   };
 
   std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
-  AssociateParamsFromFieldTrialConfig(kConfig, feature_list.get());
+  AssociateParamsFromFieldTrialConfig(kConfig, feature_list.get(), platform);
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatureList(std::move(feature_list));
 
@@ -145,17 +261,23 @@
 }
 
 TEST_F(FieldTrialUtilTest, AssociateForcingFlagsFromFieldTrialConfig) {
+  const Study::Platform platform = Study::PLATFORM_LINUX;
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
-      {"TestGroup1", nullptr, 0, nullptr, 0, nullptr, 0, nullptr}
+      {"TestGroup1", &platform, 1, nullptr, 0, nullptr, 0, nullptr, 0, nullptr}
   };
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
-      {"TestGroup2", nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
-      {"ForcedGroup2", nullptr, 0, nullptr, 0, nullptr, 0, "flag-2"},
+      {"TestGroup2", &platform, 1, nullptr, 0, nullptr, 0, nullptr, 0,
+       nullptr},
+      {"ForcedGroup2", &platform, 1, nullptr, 0, nullptr, 0, nullptr, 0,
+       "flag-2"},
   };
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_2[] = {
-      {"TestGroup3", nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
-      {"ForcedGroup3", nullptr, 0, nullptr, 0, nullptr, 0, "flag-3"},
-      {"ForcedGroup3-2", nullptr, 0, nullptr, 0, nullptr, 0, "flag-3-2"},
+      {"TestGroup3", &platform, 1, nullptr, 0, nullptr, 0, nullptr, 0,
+       nullptr},
+      {"ForcedGroup3", &platform, 1, nullptr, 0, nullptr, 0, nullptr, 0,
+       "flag-3"},
+      {"ForcedGroup3-2", &platform, 1, nullptr, 0, nullptr, 0, nullptr, 0,
+       "flag-3-2"},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] = {
       {"TestTrial1", array_kFieldTrialConfig_experiments_0, 1},
@@ -170,7 +292,7 @@
   base::CommandLine::ForCurrentProcess()->AppendSwitch("flag-3");
 
   base::FeatureList feature_list;
-  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list);
+  AssociateParamsFromFieldTrialConfig(kConfig, &feature_list, platform);
 
   EXPECT_EQ("TestGroup1", base::FieldTrialList::FindFullName("TestTrial1"));
   EXPECT_EQ("ForcedGroup2", base::FieldTrialList::FindFullName("TestTrial2"));
diff --git a/components/variations/proto/study.proto b/components/variations/proto/study.proto
index 3252414b..0169db04 100644
--- a/components/variations/proto/study.proto
+++ b/components/variations/proto/study.proto
@@ -181,6 +181,7 @@
   }
 
   // Possible Chrome operating system platforms.
+  // These names must match those in tools/variations/fieldtrial_to_struct.py.
   enum Platform {
     PLATFORM_WINDOWS         = 0;
     PLATFORM_MAC             = 1;
diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc
index 966d21d..5f33665 100644
--- a/components/variations/service/variations_field_trial_creator.cc
+++ b/components/variations/service/variations_field_trial_creator.cc
@@ -250,9 +250,7 @@
   state->version = version;
   state->channel = GetChannelForVariations(client_->GetChannel());
   state->form_factor = GetCurrentFormFactor();
-  state->platform = (has_platform_override_)
-                        ? platform_override_
-                        : ClientFilterableState::GetCurrentPlatform();
+  state->platform = GetPlatform();
   state->hardware_class = GetShortHardwareClass();
 #if defined(OS_ANDROID)
   // This is set on Android only currently, because the IsLowEndDevice() API
@@ -493,7 +491,7 @@
   if (!command_line->HasSwitch(switches::kDisableFieldTrialTestingConfig) &&
       !command_line->HasSwitch(::switches::kForceFieldTrials) &&
       !command_line->HasSwitch(switches::kVariationsServerURL)) {
-    AssociateDefaultFieldTrialConfig(feature_list.get());
+    AssociateDefaultFieldTrialConfig(feature_list.get(), GetPlatform());
   }
 #endif  // defined(FIELDTRIAL_TESTING_ENABLED)
 
@@ -515,4 +513,10 @@
   return &seed_store_;
 }
 
+Study::Platform VariationsFieldTrialCreator::GetPlatform() {
+  if (has_platform_override_)
+    return platform_override_;
+  return ClientFilterableState::GetCurrentPlatform();
+}
+
 }  // namespace variations
diff --git a/components/variations/service/variations_field_trial_creator.h b/components/variations/service/variations_field_trial_creator.h
index ae9cc95..6d6ff5db 100644
--- a/components/variations/service/variations_field_trial_creator.h
+++ b/components/variations/service/variations_field_trial_creator.h
@@ -14,6 +14,7 @@
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
 #include "components/variations/client_filterable_state.h"
+#include "components/variations/proto/study.pb.h"
 #include "components/variations/seed_response.h"
 #include "components/variations/service/ui_string_overrider.h"
 #include "components/variations/variations_seed_store.h"
@@ -133,6 +134,9 @@
   // Returns the seed store. Virtual for testing.
   virtual VariationsSeedStore* GetSeedStore();
 
+  // Get the platform we're running on, respecting OverrideVariationsPlatform().
+  Study::Platform GetPlatform();
+
   PrefService* local_state() { return seed_store_.local_state(); }
   const PrefService* local_state() const { return seed_store_.local_state(); }
 
diff --git a/content/browser/android/content_ui_event_handler.cc b/content/browser/android/content_ui_event_handler.cc
index a185cfe..c043c6a7 100644
--- a/content/browser/android/content_ui_event_handler.cc
+++ b/content/browser/android/content_ui_event_handler.cc
@@ -172,15 +172,21 @@
   float dip_scale = web_contents_->GetNativeView()->GetDipScale();
   float delta_xdip = delta_x / dip_scale;
   float delta_ydip = delta_y / dip_scale;
+  constexpr bool target_viewport = true;
+  constexpr bool synthetic_scroll = false;
+  constexpr bool prevent_boosting = false;
   event_handler->OnGestureEvent(ui::GestureEventAndroid(
       ui::GESTURE_EVENT_TYPE_SCROLL_START, gfx::PointF(), gfx::PointF(),
-      time_ms, 0, -delta_xdip, -delta_ydip, 0, 0, true, false));
+      time_ms, 0, -delta_xdip, -delta_ydip, 0, 0, target_viewport,
+      synthetic_scroll, prevent_boosting));
   event_handler->OnGestureEvent(ui::GestureEventAndroid(
       ui::GESTURE_EVENT_TYPE_SCROLL_BY, gfx::PointF(), gfx::PointF(), time_ms,
-      0, -delta_xdip, -delta_ydip, 0, 0, true, false));
+      0, -delta_xdip, -delta_ydip, 0, 0, target_viewport, synthetic_scroll,
+      prevent_boosting));
   event_handler->OnGestureEvent(ui::GestureEventAndroid(
       ui::GESTURE_EVENT_TYPE_SCROLL_END, gfx::PointF(), gfx::PointF(), time_ms,
-      0, -delta_xdip, -delta_ydip, 0, 0, true, false));
+      0, -delta_xdip, -delta_ydip, 0, 0, target_viewport, synthetic_scroll,
+      prevent_boosting));
 }
 
 void ContentUiEventHandler::CancelFling(JNIEnv* env,
@@ -191,7 +197,8 @@
     return;
   event_handler->OnGestureEvent(ui::GestureEventAndroid(
       ui::GESTURE_EVENT_TYPE_FLING_CANCEL, gfx::PointF(), gfx::PointF(),
-      time_ms, 0, 0, 0, 0, 0, false, false));
+      time_ms, 0, 0, 0, 0, 0, /*target_viewport*/ false,
+      /*synthetic_scroll*/ false, true));
 }
 
 jlong JNI_ContentUiEventHandler_Init(
diff --git a/content/browser/appcache/appcache_navigation_handle_core.cc b/content/browser/appcache/appcache_navigation_handle_core.cc
index 2b7f0eb..3c6d8fb 100644
--- a/content/browser/appcache/appcache_navigation_handle_core.cc
+++ b/content/browser/appcache/appcache_navigation_handle_core.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/feature_list.h"
 #include "base/lazy_instance.h"
 #include "base/strings/stringprintf.h"
 #include "content/browser/appcache/appcache_host.h"
@@ -16,6 +17,7 @@
 #include "content/browser/appcache/chrome_appcache_service.h"
 #include "content/common/service_worker/service_worker_utils.h"
 #include "content/public/browser/browser_thread.h"
+#include "services/network/public/cpp/features.h"
 
 namespace {
 
@@ -38,8 +40,14 @@
     : appcache_service_(appcache_service),
       appcache_host_id_(appcache_host_id),
       ui_handle_(ui_handle) {
-  if (ServiceWorkerUtils::IsServicificationEnabled())
+  if (ServiceWorkerUtils::IsServicificationEnabled()) {
     debug_log_ = base::make_optional<std::vector<std::string>>();
+    debug_log_->push_back(base::StringPrintf(
+        "Ctor:host=%d,ns=%s", appcache_host_id,
+        base::FeatureList::IsEnabled(network::features::kNetworkService)
+            ? "T"
+            : "F"));
+  }
 
   // The AppCacheNavigationHandleCore is created on the UI thread but
   // should only be accessed from the IO thread afterwards.
@@ -66,7 +74,7 @@
   g_appcache_handle_map.Get()[appcache_host_id_] = this;
 
   if (debug_log_)
-    debug_log_->emplace_back("Init:" + std::to_string(appcache_host_id_));
+    debug_log_->push_back("Init:" + std::to_string(appcache_host_id_));
 }
 
 // static
@@ -80,7 +88,7 @@
     DCHECK(instance);
     auto host = std::move(instance->precreated_host_);
     if (instance->debug_log_) {
-      instance->debug_log_->emplace_back(
+      instance->debug_log_->push_back(
           host ? base::StringPrintf("Get:id=%d,host=%d", host_id,
                                     host->host_id())
                : base::StringPrintf("Get:id=%d,host=null", host_id));
@@ -97,8 +105,8 @@
 void AppCacheNavigationHandleCore::AddRequestToDebugLog(const GURL& url) {
   if (debug_log_) {
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    debug_log_->emplace_back("Req:host=" + HostToString() +
-                             ",url=" + url.spec().substr(0, 64));
+    debug_log_->push_back("Req:host=" + HostToString() +
+                          ",url=" + url.spec().substr(0, 64));
   }
 }
 
@@ -106,7 +114,8 @@
     bool was_request_intercepted) {
   if (debug_log_) {
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    debug_log_->emplace_back(
+    CHECK(!debug_log_->empty());
+    debug_log_->push_back(
         base::StringPrintf("Fac:host=%s,int=%s", HostToString().c_str(),
                            was_request_intercepted ? "T" : "F"));
   }
@@ -115,14 +124,18 @@
 void AppCacheNavigationHandleCore::AddCreateURLLoaderToDebugLog() {
   if (debug_log_) {
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    debug_log_->emplace_back("Load:host=" + HostToString());
+    CHECK(!debug_log_->empty());
+    debug_log_->push_back("Load:host=" + HostToString());
   }
 }
 
-void AppCacheNavigationHandleCore::AddNavigationStartToDebugLog() {
+void AppCacheNavigationHandleCore::AddNavigationStartToDebugLog(
+    bool network_service) {
   if (debug_log_) {
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    debug_log_->emplace_back("Start:host=" + HostToString());
+    debug_log_->push_back(base::StringPrintf("Start:host=%s,ns=%s",
+                                             HostToString().c_str(),
+                                             network_service ? "T" : "F"));
   }
 }
 
diff --git a/content/browser/appcache/appcache_navigation_handle_core.h b/content/browser/appcache/appcache_navigation_handle_core.h
index bb7eddc7..7a5f1e3 100644
--- a/content/browser/appcache/appcache_navigation_handle_core.h
+++ b/content/browser/appcache/appcache_navigation_handle_core.h
@@ -50,7 +50,7 @@
   void AddRequestToDebugLog(const GURL& url);
   void AddDefaultFactoryRunToDebugLog(bool was_request_intercepted);
   void AddCreateURLLoaderToDebugLog();
-  void AddNavigationStartToDebugLog();
+  void AddNavigationStartToDebugLog(bool network_service);
   std::string GetDebugLog();
 
  protected:
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
index 4d08d44..bea7677 100644
--- a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
+++ b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -281,8 +281,7 @@
           base::Bind(&BluetoothDeviceChooserController::StopDeviceDiscovery,
                      // base::Timer guarantees it won't call back after its
                      // destructor starts.
-                     base::Unretained(this)),
-          /*is_repeating=*/false),
+                     base::Unretained(this))),
       weak_ptr_factory_(this) {
   CHECK(adapter_);
 }
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller.h b/content/browser/bluetooth/bluetooth_device_chooser_controller.h
index 54eb7a1..b2e16cb 100644
--- a/content/browser/bluetooth/bluetooth_device_chooser_controller.h
+++ b/content/browser/bluetooth/bluetooth_device_chooser_controller.h
@@ -147,7 +147,7 @@
 
   // Automatically stops Bluetooth discovery a set amount of time after it was
   // started.
-  base::Timer discovery_session_timer_;
+  base::RetainingOneShotTimer discovery_session_timer_;
 
   // The last discovery session to be started.
   // TODO(ortuno): This should be null unless there is an active discovery
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc
index cd976a5..296270a 100644
--- a/content/browser/devtools/protocol/tracing_handler.cc
+++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -596,14 +596,13 @@
 
   base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
       std::ceil(usage_reporting_interval));
-  buffer_usage_poll_timer_.reset(new base::Timer(
+  buffer_usage_poll_timer_.reset(new base::RepeatingTimer());
+  buffer_usage_poll_timer_->Start(
       FROM_HERE, interval,
       base::Bind(base::IgnoreResult(&TracingController::GetTraceBufferUsage),
                  base::Unretained(TracingController::GetInstance()),
                  base::Bind(&TracingHandler::OnBufferUsage,
-                            weak_factory_.GetWeakPtr())),
-      true));
-  buffer_usage_poll_timer_->Reset();
+                            weak_factory_.GetWeakPtr())));
 }
 
 void TracingHandler::StopTracing(
diff --git a/content/browser/devtools/protocol/tracing_handler.h b/content/browser/devtools/protocol/tracing_handler.h
index c6312f2..82f11ef 100644
--- a/content/browser/devtools/protocol/tracing_handler.h
+++ b/content/browser/devtools/protocol/tracing_handler.h
@@ -24,7 +24,7 @@
 #include "content/public/browser/tracing_controller.h"
 
 namespace base {
-class Timer;
+class RepeatingTimer;
 }
 
 namespace media {
@@ -121,7 +121,7 @@
                        std::unordered_set<base::ProcessId>* process_set);
   void OnProcessReady(RenderProcessHost*);
 
-  std::unique_ptr<base::Timer> buffer_usage_poll_timer_;
+  std::unique_ptr<base::RepeatingTimer> buffer_usage_poll_timer_;
 
   std::unique_ptr<Tracing::Frontend> frontend_;
   DevToolsIOContext* io_context_;
diff --git a/content/browser/do_not_track_browsertest.cc b/content/browser/do_not_track_browsertest.cc
index c09c64f..cc053f0 100644
--- a/content/browser/do_not_track_browsertest.cc
+++ b/content/browser/do_not_track_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/strings/utf_string_conversions.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/renderer_preferences.h"
 #include "content/public/test/browser_test_utils.h"
@@ -9,6 +10,8 @@
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
 
 namespace content {
 
@@ -43,6 +46,20 @@
   }
 };
 
+std::unique_ptr<net::test_server::HttpResponse> CaptureHeaderHandler(
+    const std::string& path,
+    net::test_server::HttpRequest::HeaderMap* header_map,
+    base::OnceClosure done_callback,
+    const net::test_server::HttpRequest& request) {
+  GURL request_url = request.GetURL();
+  if (request_url.path() != path)
+    return nullptr;
+
+  *header_map = request.headers;
+  std::move(done_callback).Run();
+  return std::make_unique<net::test_server::BasicHttpResponse>();
+}
+
 // Checks that the DNT header is not sent by default.
 IN_PROC_BROWSER_TEST_F(DoNotTrackTest, NotEnabled) {
   ASSERT_TRUE(embedded_test_server()->Start());
@@ -84,6 +101,115 @@
   EXPECT_EQ("1", GetDOMDoNotTrackProperty());
 }
 
+// Checks that the DNT header is sent in a request for a dedicated worker
+// script.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Worker) {
+  net::test_server::HttpRequest::HeaderMap header_map;
+  base::RunLoop loop;
+  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+      &CaptureHeaderHandler, "/capture", &header_map, loop.QuitClosure()));
+  ASSERT_TRUE(embedded_test_server()->Start());
+  EnableDoNotTrack();
+  const GURL url = embedded_test_server()->GetURL(
+      std::string("/workers/create_worker.html?worker_url=/capture"));
+  NavigateToURL(shell(), url);
+  loop.Run();
+
+  EXPECT_TRUE(header_map.find("DNT") != header_map.end());
+  EXPECT_EQ("1", header_map["DNT"]);
+}
+
+// Checks that the DNT header is sent in a request for a shared worker
+// script.
+// Disabled due to crbug.com/853085.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, DISABLED_SharedWorker) {
+  net::test_server::HttpRequest::HeaderMap header_map;
+  base::RunLoop loop;
+  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+      &CaptureHeaderHandler, "/capture", &header_map, loop.QuitClosure()));
+  ASSERT_TRUE(embedded_test_server()->Start());
+  EnableDoNotTrack();
+  const GURL url = embedded_test_server()->GetURL(
+      std::string("/workers/create_shared_worker.html?worker_url=/capture"));
+  NavigateToURL(shell(), url);
+  loop.Run();
+
+  EXPECT_TRUE(header_map.find("DNT") != header_map.end());
+  EXPECT_EQ("1", header_map["DNT"]);
+}
+
+// Checks that the DNT header is sent in a request for a service worker
+// script.
+// Disabled due to crbug.com/853085.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, DISABLED_ServiceWorker) {
+  net::test_server::HttpRequest::HeaderMap header_map;
+  base::RunLoop loop;
+  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+      &CaptureHeaderHandler, "/capture", &header_map, loop.QuitClosure()));
+  ASSERT_TRUE(embedded_test_server()->Start());
+  EnableDoNotTrack();
+  const GURL url = embedded_test_server()->GetURL(std::string(
+      "/service_worker/create_service_worker.html?worker_url=/capture"));
+  NavigateToURL(shell(), url);
+  loop.Run();
+
+  EXPECT_TRUE(header_map.find("DNT") != header_map.end());
+  EXPECT_EQ("1", header_map["DNT"]);
+}
+
+// Checks that the DNT header is preserved when fetching from a dedicated
+// worker.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, FetchFromWorker) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  EnableDoNotTrack();
+  const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
+  const GURL url = embedded_test_server()->GetURL(
+      std::string("/workers/fetch_from_worker.html?url=") + fetch_url.spec());
+  NavigateToURL(shell(), url);
+
+  const base::string16 title = base::ASCIIToUTF16("DONE");
+  TitleWatcher watcher(shell()->web_contents(), title);
+  EXPECT_EQ(title, watcher.WaitAndGetTitle());
+
+  ExpectPageTextEq("1");
+}
+
+// Checks that the DNT header is preserved when fetching from a shared worker.
+// Disabled due to crbug.com/853085.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, DISABLED_FetchFromSharedWorker) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  EnableDoNotTrack();
+  const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
+  const GURL url = embedded_test_server()->GetURL(
+      std::string("/workers/fetch_from_shared_worker.html?url=") +
+      fetch_url.spec());
+  NavigateToURL(shell(), url);
+
+  const base::string16 title = base::ASCIIToUTF16("DONE");
+  TitleWatcher watcher(shell()->web_contents(), title);
+  EXPECT_EQ(title, watcher.WaitAndGetTitle());
+
+  ExpectPageTextEq("1");
+}
+
+// Checks that the DNT header is preserved when fetching from a service worker.
+// Disabled due to crbug.com/853085.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, DISABLED_FetchFromServiceWorker) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  EnableDoNotTrack();
+  const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
+  const GURL url = embedded_test_server()->GetURL(
+      std::string("/service_worker/fetch_from_service_worker.html?url=") +
+      fetch_url.spec());
+  NavigateToURL(shell(), url);
+
+  const base::string16 title = base::ASCIIToUTF16("DONE");
+  TitleWatcher watcher(shell()->web_contents(), title);
+  EXPECT_EQ(title, watcher.WaitAndGetTitle());
+
+  ExpectPageTextEq("1");
+}
+
 }  // namespace
 
-}  // namespace content
\ No newline at end of file
+}  // namespace content
diff --git a/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc b/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc
index e04bbb4e..0be77f3 100644
--- a/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc
+++ b/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc
@@ -16,7 +16,7 @@
     std::list<std::unique_ptr<IndexedDBPreCloseTaskQueue::PreCloseTask>> tasks,
     base::OnceClosure on_complete,
     base::TimeDelta max_run_time,
-    std::unique_ptr<base::Timer> timer)
+    std::unique_ptr<base::OneShotTimer> timer)
     : tasks_(std::move(tasks)),
       on_done_(std::move(on_complete)),
       timeout_time_(max_run_time),
diff --git a/content/browser/indexed_db/indexed_db_pre_close_task_queue.h b/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
index 4010a5a4..7e2aa84 100644
--- a/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
+++ b/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
@@ -64,7 +64,7 @@
   IndexedDBPreCloseTaskQueue(std::list<std::unique_ptr<PreCloseTask>> tasks,
                              base::OnceClosure on_complete,
                              base::TimeDelta max_run_time,
-                             std::unique_ptr<base::Timer> timer);
+                             std::unique_ptr<base::OneShotTimer> timer);
   ~IndexedDBPreCloseTaskQueue();
 
   bool started() const { return started_; }
@@ -96,7 +96,7 @@
   base::OnceClosure on_done_;
 
   base::TimeDelta timeout_time_;
-  std::unique_ptr<base::Timer> timeout_timer_;
+  std::unique_ptr<base::OneShotTimer> timeout_timer_;
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   base::WeakPtrFactory<IndexedDBPreCloseTaskQueue> ptr_factory_;
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 5476802f..0cd03e5 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -373,6 +373,7 @@
     // Temporary CHECKs for https://crbug.com/857005.
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     CHECK(started_);
+    CHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
     if (appcache_handle_core)
       appcache_handle_core->AddDefaultFactoryRunToDebugLog(
           was_request_intercepted);
@@ -403,8 +404,10 @@
       AppCacheNavigationHandleCore* appcache_handle_core,
       network::mojom::URLLoaderRequest url_loader,
       network::mojom::URLLoaderClientPtr url_loader_client) {
-    DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
-    DCHECK_CURRENTLY_ON(BrowserThread::IO);
+    // Temporary CHECKs for https://crbug.com/857005.
+    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+    CHECK(started_);
+    CHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
 
     if (appcache_handle_core)
       appcache_handle_core->AddCreateURLLoaderToDebugLog();
@@ -475,7 +478,8 @@
     CHECK(!started_);
     CHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
     if (appcache_handle_core)
-      appcache_handle_core->AddNavigationStartToDebugLog();
+      appcache_handle_core->AddNavigationStartToDebugLog(
+          false /* network_service */);
 
     started_ = true;
     request_info_ = std::move(request_info);
@@ -570,6 +574,9 @@
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     CHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
     CHECK(!started_);
+    if (appcache_handle_core)
+      appcache_handle_core->AddNavigationStartToDebugLog(
+          true /* network_service */);
     global_request_id_ = MakeGlobalRequestID();
     frame_tree_node_id_ = frame_tree_node_id;
     started_ = true;
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index d5f954f8..093aac601 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -292,6 +292,12 @@
     params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
     params.anchor = touch_point;
     params.distances.push_back(-distance);
+    // Set the speed to very high so that there is one GSU only.
+    // It seems that when the speed is too high, it has a race with the timeout
+    // test.
+    if (jank_time != kLongJankTime) {
+      params.speed_in_pixels_s = 1000000;
+    }
 
     run_loop_ = std::make_unique<base::RunLoop>();
 
@@ -340,17 +346,9 @@
     int scroll_top = GetScrollTop();
     int scroll_left = GetScrollLeft();
 
-    // It is hard to know when would the synthetic gesture being completely
-    // processed, so just make sure that it scrolled at least 1px along the
-    // expected scroll direction.
-    if (expected_scroll_position_after_scroll.y() > 0)
-      EXPECT_GT(scroll_top, 1);
-    else
-      EXPECT_EQ(scroll_top, 0);
-    if (expected_scroll_position_after_scroll.x() > 0)
-      EXPECT_GT(scroll_left, 1);
-    else
-      EXPECT_EQ(scroll_left, 0);
+    // Expect it scrolled at least half of the expected distance.
+    EXPECT_LE(expected_scroll_position_after_scroll.y() / 2, scroll_top);
+    EXPECT_LE(expected_scroll_position_after_scroll.x() / 2, scroll_left);
   }
 
   std::unique_ptr<RenderFrameSubmissionObserver> frame_observer_;
@@ -477,7 +475,7 @@
                        MAYBE_PanXYAtXAreaMainThreadJanky) {
   LoadURL(kTouchActionURLWithOverlapArea);
 
-  DoTouchScroll(gfx::Point(125, 25), gfx::Vector2d(45, 45), false, 10000,
+  DoTouchScroll(gfx::Point(125, 25), gfx::Vector2d(45, 20), false, 10000,
                 gfx::Vector2d(45, 0), kShortJankTime);
 }
 
@@ -491,16 +489,15 @@
                        MAYBE_PanXYAtYAreaMainThreadJanky) {
   LoadURL(kTouchActionURLWithOverlapArea);
 
-  DoTouchScroll(gfx::Point(25, 125), gfx::Vector2d(45, 45), false, 10000,
+  DoTouchScroll(gfx::Point(25, 125), gfx::Vector2d(20, 45), false, 10000,
                 gfx::Vector2d(0, 45), kShortJankTime);
 }
 
-// Flaky on all platforms.  http://crbug.com/851619
 IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest,
-                       DISABLED_PanXYAtAutoYOverlapAreaMainThreadJanky) {
+                       PanXYAtAutoYOverlapAreaMainThreadJanky) {
   LoadURL(kTouchActionURLWithOverlapArea);
 
-  DoTouchScroll(gfx::Point(75, 125), gfx::Vector2d(45, 45), false, 10000,
+  DoTouchScroll(gfx::Point(75, 125), gfx::Vector2d(20, 45), false, 10000,
                 gfx::Vector2d(0, 45), kShortJankTime);
 }
 
@@ -515,7 +512,7 @@
                        MAYBE_PanXYAtAutoXOverlapAreaMainThreadJanky) {
   LoadURL(kTouchActionURLWithOverlapArea);
 
-  DoTouchScroll(gfx::Point(125, 75), gfx::Vector2d(45, 45), false, 10000,
+  DoTouchScroll(gfx::Point(125, 75), gfx::Vector2d(45, 20), false, 10000,
                 gfx::Vector2d(45, 0), kShortJankTime);
 }
 
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
index 746afa48..3b7ecd5 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
@@ -130,8 +130,7 @@
           FROM_HERE,
           base::TimeDelta::FromMilliseconds(kQuickMenuDelayInMs),
           base::Bind(&TouchSelectionControllerClientAura::ShowQuickMenu,
-                     base::Unretained(this)),
-          false),
+                     base::Unretained(this))),
       quick_menu_requested_(false),
       touch_down_(false),
       scroll_in_progress_(false),
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura.h b/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
index 791ee5a4..a1888653 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
+++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
@@ -125,7 +125,7 @@
   base::ObserverList<TouchSelectionControllerClientManager::Observer>
       observers_;
 
-  base::Timer quick_menu_timer_;
+  base::RetainingOneShotTimer quick_menu_timer_;
   bool quick_menu_requested_;
   bool touch_down_;
   bool scroll_in_progress_;
diff --git a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 925e600..dafc06b 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/sys_byteorder.h"
 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
 #include "content/browser/renderer_host/p2p/socket_host_throttler.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/io_buffer.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
@@ -90,7 +91,7 @@
   int RecvFrom(net::IOBuffer* buf,
                int buf_len,
                net::IPEndPoint* address,
-               const net::CompletionCallback& callback) override {
+               net::CompletionOnceCallback callback) override {
     CHECK(recv_callback_.is_null());
     if (incoming_packets_.size() > 0) {
       scoped_refptr<net::IOBuffer> buffer(buf);
@@ -101,7 +102,7 @@
       incoming_packets_.pop_front();
       return size;
     } else {
-      recv_callback_ = callback;
+      recv_callback_ = std::move(callback);
       recv_buffer_ = buf;
       recv_size_ = buf_len;
       recv_address_ = address;
@@ -112,7 +113,7 @@
   int SendTo(net::IOBuffer* buf,
              int buf_len,
              const net::IPEndPoint& address,
-             const net::CompletionCallback& callback) override {
+             net::CompletionOnceCallback callback) override {
     scoped_refptr<net::IOBuffer> buffer(buf);
     std::vector<char> data_vector(buffer->data(), buffer->data() + buf_len);
     sent_packets_->push_back(UDPPacket(address, data_vector));
@@ -132,10 +133,8 @@
       int size = std::min(recv_size_, static_cast<int>(data.size()));
       memcpy(recv_buffer_->data(), &*data.begin(), size);
       *recv_address_ = address;
-      net::CompletionCallback cb = recv_callback_;
-      recv_callback_.Reset();
       recv_buffer_ = nullptr;
-      std::move(cb).Run(size);
+      std::move(recv_callback_).Run(size);
     } else {
       incoming_packets_.push_back(UDPPacket(address, data));
     }
@@ -188,7 +187,7 @@
   scoped_refptr<net::IOBuffer> recv_buffer_;
   net::IPEndPoint* recv_address_;
   int recv_size_;
-  net::CompletionCallback recv_callback_;
+  net::CompletionOnceCallback recv_callback_;
   std::vector<uint16_t>* used_ports_;
 };
 
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 4eb3515..b7a8e3a 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -700,7 +700,9 @@
     web_event = ui::CreateWebGestureEventFromGestureEventAndroid(
         ui::GestureEventAndroid(event.type(), event.location(),
                                 event.screen_location(), event.time(), delta, 0,
-                                0, 0, 0, false, false));
+                                0, 0, 0, /*target_viewport*/ false,
+                                /*synthetic_scroll*/ false,
+                                /*prevent_boosting*/ false));
   } else {
     web_event = ui::CreateWebGestureEventFromGestureEventAndroid(event);
   }
diff --git a/content/browser/resources/service_worker/serviceworker_internals.js b/content/browser/resources/service_worker/serviceworker_internals.js
index 810676a..a1a697b8 100644
--- a/content/browser/resources/service_worker/serviceworker_internals.js
+++ b/content/browser/resources/service_worker/serviceworker_internals.js
@@ -198,8 +198,6 @@
 
   function onErrorReported(partition_id,
                            version_id,
-                           process_id,
-                           thread_id,
                            error_info) {
     outputLogMessage(partition_id,
                      version_id,
@@ -208,8 +206,6 @@
 
   function onConsoleMessageReported(partition_id,
                                     version_id,
-                                    process_id,
-                                    thread_id,
                                     message) {
     outputLogMessage(partition_id,
                      version_id,
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 9e9b698..b58c2d9e 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -236,7 +236,6 @@
     case EmbeddedWorkerInstance::SCRIPT_READ_FINISHED:
     case EmbeddedWorkerInstance::SCRIPT_STREAMING:
     case EmbeddedWorkerInstance::SCRIPT_LOADED:
-    case EmbeddedWorkerInstance::SCRIPT_EVALUATED:
     case EmbeddedWorkerInstance::THREAD_STARTED:
       return true;
     case EmbeddedWorkerInstance::STARTING_PHASE_MAX_VALUE:
@@ -792,21 +791,8 @@
     observer.OnThreadStarted();
 }
 
-void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) {
-  if (!inflight_start_task_)
-    return;
-
-  DCHECK_EQ(EmbeddedWorkerStatus::STARTING, status_);
-  starting_phase_ = SCRIPT_EVALUATED;
-
-  if (!success) {
-    // TODO(falken): Move this to OnStarted().
-    owner_version_->OnScriptEvaluateFailed();
-    // |this| may be destroyed.
-  }
-}
-
 void EmbeddedWorkerInstance::OnStarted(
+    blink::mojom::ServiceWorkerStartStatus start_status,
     mojom::EmbeddedWorkerStartTimingPtr start_timing) {
   if (!(start_timing->start_worker_received_time <=
             start_timing->script_evaluation_start_time &&
@@ -818,7 +804,9 @@
 
   if (!registry_->OnWorkerStarted(process_id(), embedded_worker_id_))
     return;
-  // Stop is requested before OnStarted is sent back from the worker.
+  // Stop was requested before OnStarted was sent back from the worker. Just
+  // pretend startup didn't happen, so observers don't try to use the running
+  // worker as it will stop soon.
   if (status_ == EmbeddedWorkerStatus::STOPPING)
     return;
 
@@ -838,11 +826,15 @@
 
     ServiceWorkerMetrics::RecordStartWorkerTiming(times, start_situation_);
   }
+
   DCHECK_EQ(EmbeddedWorkerStatus::STARTING, status_);
   status_ = EmbeddedWorkerStatus::RUNNING;
   inflight_start_task_.reset();
-  for (auto& observer : listener_list_)
-    observer.OnStarted();
+  for (auto& observer : listener_list_) {
+    observer.OnStarted(start_status);
+    // |this| may be destroyed here. Fortunately we know there is only one
+    // observer in production code.
+  }
 }
 
 void EmbeddedWorkerInstance::OnStopped() {
@@ -991,8 +983,6 @@
       return "Script downloading";
     case SCRIPT_LOADED:
       return "Script loaded";
-    case SCRIPT_EVALUATED:
-      return "Script evaluated";
     case THREAD_STARTED:
       return "Thread started";
     case SCRIPT_READ_STARTED:
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index 54117fa..ce77845 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -66,8 +66,8 @@
     SENT_START_WORKER = 3,
     SCRIPT_DOWNLOADING = 4,
     SCRIPT_LOADED = 5,
-    SCRIPT_EVALUATED = 6,
-    // THREAD_STARTED happens after SCRIPT_LOADED and before SCRIPT_EVALUATED
+    // SCRIPT_EVALUATED = 6,  // Obsolete
+    // THREAD_STARTED happens after SCRIPT_LOADED
     THREAD_STARTED = 7,
     // Script read happens after SENT_START_WORKER and before SCRIPT_LOADED
     // (installed scripts only)
@@ -92,7 +92,7 @@
     virtual void OnRegisteredToDevToolsManager() {}
     virtual void OnStartWorkerMessageSent() {}
     virtual void OnThreadStarted() {}
-    virtual void OnStarted() {}
+    virtual void OnStarted(blink::mojom::ServiceWorkerStartStatus status) {}
 
     // Called when status changed to STOPPING. The renderer has been sent a Stop
     // IPC message and OnStopped() will be called upon successful completion.
@@ -270,10 +270,9 @@
   // Notifies the corresponding provider host that the thread has started and is
   // ready to receive messages.
   void OnThreadStarted(int thread_id) override;
-  // Fires the callback passed to Start().
-  void OnScriptEvaluated(bool success) override;
   // Changes the internal worker status from STARTING to RUNNING.
-  void OnStarted(mojom::EmbeddedWorkerStartTimingPtr start_timing) override;
+  void OnStarted(blink::mojom::ServiceWorkerStartStatus status,
+                 mojom::EmbeddedWorkerStartTimingPtr start_timing) override;
   // Resets the embedded worker instance to the initial state. This will change
   // the internal status from STARTING or RUNNING to STOPPED.
   void OnStopped() override;
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
index 5b0b178..14e2c9a6 100644
--- a/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -31,6 +31,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
 
 namespace content {
@@ -120,13 +121,15 @@
 
   struct EventLog {
     EventType type;
-    EmbeddedWorkerStatus status;
+    base::Optional<EmbeddedWorkerStatus> status;
+    base::Optional<blink::mojom::ServiceWorkerStartStatus> start_status;
   };
 
-  void RecordEvent(
-      EventType type,
-      EmbeddedWorkerStatus status = EmbeddedWorkerStatus::STOPPED) {
-    EventLog log = {type, status};
+  void RecordEvent(EventType type,
+                   base::Optional<EmbeddedWorkerStatus> status = base::nullopt,
+                   base::Optional<blink::mojom::ServiceWorkerStartStatus>
+                       start_status = base::nullopt) {
+    EventLog log = {type, status, start_status};
     events_.push_back(log);
   }
 
@@ -134,7 +137,9 @@
   void OnStartWorkerMessageSent() override {
     RecordEvent(START_WORKER_MESSAGE_SENT);
   }
-  void OnStarted() override { RecordEvent(STARTED); }
+  void OnStarted(blink::mojom::ServiceWorkerStartStatus status) override {
+    RecordEvent(STARTED, base::nullopt, status);
+  }
   void OnStopped(EmbeddedWorkerStatus old_status) override {
     RecordEvent(STOPPED, old_status);
   }
@@ -354,7 +359,6 @@
   worker->AddObserver(this);
 
   // Start should succeed.
-  base::RunLoop run_loop;
   mojom::EmbeddedWorkerStartParamsPtr params =
       CreateStartParams(service_worker_version_id, pattern, url);
   StartWorker(worker.get(), std::move(params));
@@ -378,6 +382,8 @@
   EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
   EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
   EXPECT_EQ(STARTED, events_[2].type);
+  EXPECT_EQ(blink::mojom::ServiceWorkerStartStatus::kNormalCompletion,
+            events_[2].start_status.value());
   EXPECT_EQ(STOPPED, events_[3].type);
 }
 
@@ -535,7 +541,7 @@
   // "PROCESS_ALLOCATED" event should not be recorded.
   ASSERT_EQ(1u, events_.size());
   EXPECT_EQ(DETACHED, events_[0].type);
-  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
+  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status.value());
 }
 
 TEST_P(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
@@ -565,7 +571,7 @@
   // "STARTED" event should not be recorded.
   ASSERT_EQ(1u, events_.size());
   EXPECT_EQ(DETACHED, events_[0].type);
-  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
+  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status.value());
 }
 
 TEST_P(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
@@ -598,7 +604,7 @@
   // "PROCESS_ALLOCATED" event should not be recorded.
   ASSERT_EQ(1u, events_.size());
   EXPECT_EQ(STOPPED, events_[0].type);
-  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
+  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status.value());
   events_.clear();
 
   // Restart the worker.
@@ -694,7 +700,7 @@
   // "STARTED" event should not be recorded.
   ASSERT_EQ(1u, events_.size());
   EXPECT_EQ(STOPPED, events_[0].type);
-  EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, events_[0].status);
+  EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, events_[0].status.value());
   events_.clear();
 
   // Restart the worker.
@@ -773,7 +779,7 @@
   EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
   EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
   EXPECT_EQ(DETACHED, events_[2].type);
-  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status);
+  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status.value());
   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
 }
 
@@ -822,7 +828,7 @@
   EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
   EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
   EXPECT_EQ(DETACHED, events_[2].type);
-  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status);
+  EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status.value());
 }
 
 class StoreMessageInstanceClient
@@ -983,6 +989,45 @@
   }
 }
 
+// Starts the worker with kAbruptCompletion status.
+class AbruptCompletionHelper : public EmbeddedWorkerTestHelper {
+ public:
+  AbruptCompletionHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
+  ~AbruptCompletionHelper() override = default;
+
+  void OnResumeAfterDownload(int embedded_worker_id) override {
+    SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id);
+    SimulateWorkerStarted(
+        embedded_worker_id,
+        blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion);
+  }
+};
+
+// Tests that kAbruptCompletion is the OnStarted() status when the
+// renderer reports abrupt completion.
+TEST_P(EmbeddedWorkerInstanceTest, AbruptCompletion) {
+  const GURL scope("http://example.com/");
+  const GURL url("http://example.com/worker.js");
+  helper_ = std::make_unique<AbruptCompletionHelper>();
+
+  RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+  const int64_t version_id = pair.second->version_id();
+  std::unique_ptr<EmbeddedWorkerInstance> worker =
+      embedded_worker_registry()->CreateWorker(pair.second.get());
+  EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
+  worker->AddObserver(this);
+
+  StartWorker(worker.get(), CreateStartParams(version_id, scope, url));
+
+  ASSERT_EQ(3u, events_.size());
+  EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
+  EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
+  EXPECT_EQ(STARTED, events_[2].type);
+  EXPECT_EQ(blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion,
+            events_[2].start_status.value());
+  worker->Stop();
+}
+
 INSTANTIATE_TEST_CASE_P(IsServiceWorkerServicificationEnabled,
                         EmbeddedWorkerInstanceTest,
                         ::testing::Bool(););
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc
index fa9717e..c1bb8c1 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -567,8 +567,9 @@
 
 void EmbeddedWorkerTestHelper::OnResumeAfterDownload(int embedded_worker_id) {
   SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id);
-  SimulateWorkerScriptEvaluated(embedded_worker_id, true /* success */);
-  SimulateWorkerStarted(embedded_worker_id);
+  SimulateWorkerStarted(
+      embedded_worker_id,
+      blink::mojom::ServiceWorkerStartStatus::kNormalCompletion);
 }
 
 void EmbeddedWorkerTestHelper::OnStopWorker(int embedded_worker_id) {
@@ -784,23 +785,14 @@
   base::RunLoop().RunUntilIdle();
 }
 
-void EmbeddedWorkerTestHelper::SimulateWorkerScriptEvaluated(
+void EmbeddedWorkerTestHelper::SimulateWorkerStarted(
     int embedded_worker_id,
-    bool success) {
-  EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
-  ASSERT_TRUE(worker);
-  ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
-  embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]
-      ->OnScriptEvaluated(success);
-  base::RunLoop().RunUntilIdle();
-}
-
-void EmbeddedWorkerTestHelper::SimulateWorkerStarted(int embedded_worker_id) {
+    blink::mojom::ServiceWorkerStartStatus status) {
   EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
   ASSERT_TRUE(worker);
   ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
   embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]->OnStarted(
-      mojom::EmbeddedWorkerStartTiming::New());
+      status, mojom::EmbeddedWorkerStartTiming::New());
   base::RunLoop().RunUntilIdle();
 }
 
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h
index 49fef64..8154d54 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -27,6 +27,7 @@
 #include "services/network/public/mojom/cookie_manager.mojom.h"
 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
 #include "url/gurl.h"
 
@@ -249,8 +250,8 @@
                                   base::OnceClosure callback);
   void SimulateWorkerScriptLoaded(int embedded_worker_id);
   void SimulateWorkerThreadStarted(int thread_id, int embedded_worker_id);
-  void SimulateWorkerScriptEvaluated(int embedded_worker_id, bool success);
-  void SimulateWorkerStarted(int embedded_worker_id);
+  void SimulateWorkerStarted(int embedded_worker_id,
+                             blink::mojom::ServiceWorkerStartStatus status);
   void SimulateWorkerStopped(int embedded_worker_id);
 
   EmbeddedWorkerRegistry* registry();
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index 6d8bf9b..7afaea0 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -525,8 +525,6 @@
 
   // ServiceWorkerContextCoreObserver overrides.
   void OnReportConsoleMessage(int64_t version_id,
-                              int process_id,
-                              int thread_id,
                               const ConsoleMessage& console_message) override {
     messages_.push_back(console_message.message);
     if (messages_.size() == expected_message_count_) {
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index 0a9a4f2..303529ad 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -782,8 +782,7 @@
     const GURL& source_url) {
   observer_list_->Notify(
       FROM_HERE, &ServiceWorkerContextCoreObserver::OnErrorReported,
-      version->version_id(), version->embedded_worker()->process_id(),
-      version->embedded_worker()->thread_id(),
+      version->version_id(),
       ServiceWorkerContextCoreObserver::ErrorInfo(error_message, line_number,
                                                   column_number, source_url));
 }
@@ -797,8 +796,7 @@
     const GURL& source_url) {
   observer_list_->Notify(
       FROM_HERE, &ServiceWorkerContextCoreObserver::OnReportConsoleMessage,
-      version->version_id(), version->embedded_worker()->process_id(),
-      version->embedded_worker()->thread_id(),
+      version->version_id(),
       ServiceWorkerContextCoreObserver::ConsoleMessage(
           source_identifier, message_level, message, line_number, source_url));
 }
diff --git a/content/browser/service_worker/service_worker_context_core_observer.h b/content/browser/service_worker/service_worker_context_core_observer.h
index 1a5a4d2..7436571 100644
--- a/content/browser/service_worker/service_worker_context_core_observer.h
+++ b/content/browser/service_worker/service_worker_context_core_observer.h
@@ -6,6 +6,7 @@
 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_OBSERVER_H_
 
 #include <stdint.h>
+#include <string>
 
 #include "base/callback.h"
 #include "base/strings/string16.h"
@@ -71,13 +72,8 @@
       int64_t version_id,
       base::Time script_response_time,
       base::Time script_last_modified) {}
-  virtual void OnErrorReported(int64_t version_id,
-                               int process_id,
-                               int thread_id,
-                               const ErrorInfo& info) {}
+  virtual void OnErrorReported(int64_t version_id, const ErrorInfo& info) {}
   virtual void OnReportConsoleMessage(int64_t version_id,
-                                      int process_id,
-                                      int thread_id,
                                       const ConsoleMessage& message) {}
   // |web_contents_getter| is only set in PlzNavigate.
   virtual void OnControlleeAdded(
diff --git a/content/browser/service_worker/service_worker_context_watcher.cc b/content/browser/service_worker/service_worker_context_watcher.cc
index 048a84c..53f15ff6 100644
--- a/content/browser/service_worker/service_worker_context_watcher.cc
+++ b/content/browser/service_worker/service_worker_context_watcher.cc
@@ -297,8 +297,6 @@
 }
 
 void ServiceWorkerContextWatcher::OnErrorReported(int64_t version_id,
-                                                  int process_id,
-                                                  int thread_id,
                                                   const ErrorInfo& info) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
@@ -314,8 +312,6 @@
 
 void ServiceWorkerContextWatcher::OnReportConsoleMessage(
     int64_t version_id,
-    int process_id,
-    int thread_id,
     const ConsoleMessage& message) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (message.message_level != CONSOLE_MESSAGE_LEVEL_ERROR)
diff --git a/content/browser/service_worker/service_worker_context_watcher.h b/content/browser/service_worker/service_worker_context_watcher.h
index 1ec9269..be8fe5e 100644
--- a/content/browser/service_worker/service_worker_context_watcher.h
+++ b/content/browser/service_worker/service_worker_context_watcher.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <memory>
+#include <string>
 #include <unordered_map>
 #include <vector>
 
@@ -96,12 +98,8 @@
       base::Time script_response_time,
       base::Time script_last_modified) override;
   void OnErrorReported(int64_t version_id,
-                       int process_id,
-                       int thread_id,
                        const ErrorInfo& info) override;
   void OnReportConsoleMessage(int64_t version_id,
-                              int process_id,
-                              int thread_id,
                               const ConsoleMessage& message) override;
   void OnControlleeAdded(
       int64_t version_id,
diff --git a/content/browser/service_worker/service_worker_context_watcher_unittest.cc b/content/browser/service_worker/service_worker_context_watcher_unittest.cc
index e2fd3e795..5ba18ee1 100644
--- a/content/browser/service_worker/service_worker_context_watcher_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_watcher_unittest.cc
@@ -164,8 +164,7 @@
       scoped_refptr<ServiceWorkerContextWatcher> watcher,
       int64_t version_id,
       const ServiceWorkerContextCoreObserver::ErrorInfo& error_info) {
-    watcher->OnErrorReported(version_id, 0 /* process_id */, 0 /* thread_id */,
-                             error_info);
+    watcher->OnErrorReported(version_id, error_info);
   }
 
  private:
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc
index 6084f168..3b93dc1 100644
--- a/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -268,15 +268,11 @@
         Value(base::Int64ToString(version_id)));
   }
   void OnErrorReported(int64_t version_id,
-                       int process_id,
-                       int thread_id,
                        const ErrorInfo& info) override {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     std::vector<std::unique_ptr<const Value>> args;
     args.push_back(std::make_unique<Value>(partition_id_));
     args.push_back(std::make_unique<Value>(base::Int64ToString(version_id)));
-    args.push_back(std::make_unique<Value>(process_id));
-    args.push_back(std::make_unique<Value>(thread_id));
     auto value = std::make_unique<DictionaryValue>();
     value->SetString("message", info.error_message);
     value->SetInteger("lineNumber", info.line_number);
@@ -287,15 +283,11 @@
                                           ConvertToRawPtrVector(args));
   }
   void OnReportConsoleMessage(int64_t version_id,
-                              int process_id,
-                              int thread_id,
                               const ConsoleMessage& message) override {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     std::vector<std::unique_ptr<const Value>> args;
     args.push_back(std::make_unique<Value>(partition_id_));
     args.push_back(std::make_unique<Value>(base::Int64ToString(version_id)));
-    args.push_back(std::make_unique<Value>(process_id));
-    args.push_back(std::make_unique<Value>(thread_id));
     auto value = std::make_unique<DictionaryValue>();
     value->SetInteger("sourceIdentifier", message.source_identifier);
     value->SetInteger("message_level", message.message_level);
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc
index 24dc582..d3810c64e 100644
--- a/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -1028,12 +1028,14 @@
   }
 
   void OnResumeAfterDownload(int embedded_worker_id) override {
-    if (!force_start_worker_failure_) {
-      EmbeddedWorkerTestHelper::OnResumeAfterDownload(embedded_worker_id);
-    } else {
+    if (force_start_worker_failure_) {
       SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id);
-      SimulateWorkerScriptEvaluated(embedded_worker_id, false);
+      SimulateWorkerStarted(
+          embedded_worker_id,
+          blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion);
+      return;
     }
+    EmbeddedWorkerTestHelper::OnResumeAfterDownload(embedded_worker_id);
   }
 
   // ServiceWorkerRegistration::Listener overrides
diff --git a/content/browser/service_worker/service_worker_provider_host_unittest.cc b/content/browser/service_worker/service_worker_provider_host_unittest.cc
index 876ff87..d17fe02 100644
--- a/content/browser/service_worker/service_worker_provider_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -553,10 +553,6 @@
 }
 
 TEST_P(ServiceWorkerProviderHostTest, AllowsServiceWorker) {
-  // TODO(crbug.com/860380): Fails with NetS13nServiceWorker.
-  if (IsServiceWorkerServicificationEnabled())
-    return;
-
   // Create an active version.
   scoped_refptr<ServiceWorkerVersion> version =
       base::MakeRefCounted<ServiceWorkerVersion>(
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc
index c1d043e..f5617b2 100644
--- a/content/browser/service_worker/service_worker_test_utils.cc
+++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -17,6 +17,7 @@
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_storage.h"
 #include "content/common/service_worker/service_worker_provider.mojom.h"
+#include "content/common/service_worker/service_worker_utils.h"
 #include "content/public/common/child_process_host.h"
 #include "net/base/io_buffer.h"
 #include "net/base/test_completion_callback.h"
@@ -26,6 +27,60 @@
 
 namespace {
 
+// A mock SharedURLLoaderFactory that always fails to start.
+// TODO(bashi): Make this factory not to fail when unit tests actually need
+// this to be working.
+class MockSharedURLLoaderFactory final
+    : public network::SharedURLLoaderFactory {
+ public:
+  MockSharedURLLoaderFactory() = default;
+
+  // network::mojom::URLLoaderFactory:
+  void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
+                            int32_t routing_id,
+                            int32_t request_id,
+                            uint32_t options,
+                            const network::ResourceRequest& url_request,
+                            network::mojom::URLLoaderClientPtr client,
+                            const net::MutableNetworkTrafficAnnotationTag&
+                                traffic_annotation) override {
+    client->OnComplete(
+        network::URLLoaderCompletionStatus(net::ERR_NOT_IMPLEMENTED));
+  }
+  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+    NOTREACHED();
+  }
+
+  // network::SharedURLLoaderFactory:
+  std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override {
+    NOTREACHED();
+    return nullptr;
+  }
+
+ private:
+  friend class base::RefCounted<MockSharedURLLoaderFactory>;
+
+  ~MockSharedURLLoaderFactory() override = default;
+
+  DISALLOW_COPY_AND_ASSIGN(MockSharedURLLoaderFactory);
+};
+
+// Returns MockSharedURLLoaderFactory.
+class MockSharedURLLoaderFactoryInfo final
+    : public network::SharedURLLoaderFactoryInfo {
+ public:
+  MockSharedURLLoaderFactoryInfo() = default;
+  ~MockSharedURLLoaderFactoryInfo() override = default;
+
+ protected:
+  scoped_refptr<network::SharedURLLoaderFactory> CreateFactory() override {
+    return base::MakeRefCounted<MockSharedURLLoaderFactory>();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockSharedURLLoaderFactoryInfo);
+};
+
 void OnWriteBodyInfoToDiskCache(
     std::unique_ptr<ServiceWorkerResponseWriter> writer,
     const std::string& body,
@@ -131,9 +186,16 @@
   std::unique_ptr<ServiceWorkerProviderHost> host =
       ServiceWorkerProviderHost::PreCreateForController(std::move(context));
   host->SetDocumentUrl(hosted_version->script_url());
+
+  scoped_refptr<network::SharedURLLoaderFactory> loader_factory;
+  if (ServiceWorkerUtils::IsServicificationEnabled()) {
+    loader_factory = network::SharedURLLoaderFactory::Create(
+        std::make_unique<MockSharedURLLoaderFactoryInfo>());
+  }
+
   mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
-      host->CompleteStartWorkerPreparation(
-          process_id, hosted_version, nullptr /* non_network_loader_factory */);
+      host->CompleteStartWorkerPreparation(process_id, hosted_version,
+                                           loader_factory);
   output_endpoint->BindWithProviderInfo(std::move(provider_info));
   return host;
 }
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 5907c5a..e203597 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -949,13 +949,22 @@
     observer.OnRunningStateChanged(this);
 }
 
-void ServiceWorkerVersion::OnStarted() {
+void ServiceWorkerVersion::OnStarted(
+    blink::mojom::ServiceWorkerStartStatus start_status) {
   DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status());
   RestartTick(&idle_time_);
 
+  // TODO(falken): This maps kAbruptCompletion to kErrorScriptEvaluated, which
+  // most start callbacks will consider to be a failure. But the worker thread
+  // is running, and the spec considers it a success, so the callbacks should
+  // change to treat kErrorScriptEvaluated as success, or use
+  // ServiceWorkerStartStatus directly.
+  blink::ServiceWorkerStatusCode status =
+      mojo::ConvertTo<blink::ServiceWorkerStatusCode>(start_status);
+
   // Fire all start callbacks.
   scoped_refptr<ServiceWorkerVersion> protect(this);
-  FinishStartWorker(blink::ServiceWorkerStatusCode::kOk);
+  FinishStartWorker(status);
   for (auto& observer : observers_)
     observer.OnRunningStateChanged(this);
 
@@ -1002,12 +1011,6 @@
   OnStoppedInternal(old_status);
 }
 
-void ServiceWorkerVersion::OnScriptEvaluateFailed() {
-  scoped_refptr<ServiceWorkerVersion> protect(this);
-  FinishStartWorker(DeduceStartWorkerFailureReason(
-      blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed));
-}
-
 void ServiceWorkerVersion::OnRegisteredToDevToolsManager() {
   for (auto& observer : observers_)
     observer.OnDevToolsRoutingIdChanged(this);
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index f0e57f0..8fdc8a111 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -479,11 +479,6 @@
 
   static bool IsInstalled(ServiceWorkerVersion::Status status);
 
-  // For ServiceWorkerRegisterJob to know if the worker started up with an
-  // uncaught runtime error occurred.
-  // TODO(falken): Move to a status in OnStarted().
-  void OnScriptEvaluateFailed();
-
  private:
   friend class base::RefCounted<ServiceWorkerVersion>;
   friend class ServiceWorkerReadFromCacheJobTest;
@@ -614,7 +609,7 @@
   // EmbeddedWorkerInstance::Listener overrides:
   void OnThreadStarted() override;
   void OnStarting() override;
-  void OnStarted() override;
+  void OnStarted(blink::mojom::ServiceWorkerStartStatus status) override;
   void OnStopping() override;
   void OnStopped(EmbeddedWorkerStatus old_status) override;
   void OnDetached(EmbeddedWorkerStatus old_status) override;
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index ee6ec9c..ad05494 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -9030,6 +9030,64 @@
   EXPECT_EQ(0UL, final_effective_policy[0].origins.size());
 }
 
+// Test that creating a new remote frame at the same origin as its parent
+// results in the correct feature policy in the RemoteSecurityContext.
+// https://crbug.com/852102
+IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
+                       FeaturePolicyConstructionInExistingProxy) {
+  WebContentsImpl* contents = web_contents();
+  FrameTreeNode* root = contents->GetFrameTree()->root();
+
+  // Navigate to a page (1) with a cross-origin iframe (2). After load, the
+  // frame tree should look like:
+  //
+  //    a.com(1)
+  //   /
+  // b.com(2)
+  EXPECT_TRUE(NavigateToURL(
+      shell(), embedded_test_server()->GetURL(
+                   "a.com", "/cross_site_iframe_factory.html?a(b)")));
+
+  // Programmatically create a new same-origin frame (3) under the root, with a
+  // cross-origin child (4). Since two SiteInstances already exist at this
+  // point, a proxy for frame 3 will be created in the renderer for frames 2 and
+  // 4. The frame tree should look like:
+  //
+  //    a.com(1)
+  //   /      \
+  // b.com(2) a.com(3)
+  //                \
+  //                b.com(4)
+  std::string create_subframe_script =
+      "var f = document.createElement('iframe'); f.src='" +
+      embedded_test_server()
+          ->GetURL("a.com",
+                   "/cross_site_iframe_factory.html?a(b{allow-autoplay})")
+          .spec() +
+      "'; document.body.appendChild(f);";
+  EXPECT_TRUE(ExecuteScript(root, create_subframe_script));
+  EXPECT_TRUE(WaitForLoadStop(contents));
+
+  // Verify the shape of the frame tree
+  EXPECT_EQ(2UL, root->child_count());
+  EXPECT_EQ(1UL, root->child_at(1)->child_count());
+
+  // Ask frame 4 to report the enabled state of the autoplay feature. Frame 3's
+  // policy should allow autoplay if created correctly, as it is same-origin
+  // with the root, where the feature is enabled by default, and therefore
+  // should be able to delegate it to frame 4.
+  // This indirectly tests the replicated policy in frame 3: Because frame 4 is
+  // cross-origin to frame 3, it will use the proxy's replicated policy as the
+  // parent policy; otherwise we would just ask frame 3 to report its own state.
+  bool success = false;
+  EXPECT_TRUE(
+      ExecuteScriptAndExtractBool(root->child_at(1)->child_at(0),
+                                  "window.domAutomationController.send("
+                                  "document.policy.allowsFeature('autoplay'));",
+                                  &success));
+  EXPECT_TRUE(success);
+}
+
 // Test harness that allows for "barrier" style delaying of requests matching
 // certain paths. Call SetDelayedRequestsForPath to delay requests, then
 // SetUpEmbeddedTestServer to register handlers and start the server.
diff --git a/content/common/service_worker/embedded_worker.mojom b/content/common/service_worker/embedded_worker.mojom
index a1b015d..91b9ea0b 100644
--- a/content/common/service_worker/embedded_worker.mojom
+++ b/content/common/service_worker/embedded_worker.mojom
@@ -13,6 +13,7 @@
 import "mojo/public/mojom/base/unguessable_token.mojom";
 import "services/service_manager/public/mojom/interface_provider.mojom";
 import "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
 import "third_party/blink/public/platform/web_feature.mojom";
 import "third_party/blink/public/web/console_message.mojom";
 import "third_party/blink/public/web/devtools_agent.mojom";
@@ -132,18 +133,14 @@
   // browser process knows it can resume the paused worker via
   // ResumeAfterDownloaded().
   OnScriptLoaded();
-
   // Indicates that the worker thread has started. |thread_id| is the actual
   // platform thread id on which the worker runs.
   // This is called after OnScriptLoaded.
   OnThreadStarted(int32 thread_id);
-  // Indicates that the worker has evaluated the script. |success| means
-  // evaluating the script completed and no uncaught exception occurred.
-  // This is called after OnThreadStarted.
-  OnScriptEvaluated(bool success);
   // Indicates that the worker has started.
-  // This is called after OnScriptEvaluated.
-  OnStarted(EmbeddedWorkerStartTiming start_timing);
+  // This is called after OnThreadStarted.
+  OnStarted(blink.mojom.ServiceWorkerStartStatus status,
+            EmbeddedWorkerStartTiming start_timing);
   // Reports that an uncaught exception occurred in the worker.
   OnReportException(mojo_base.mojom.String16 error_message, int32 line_number,
                     int32 column_number, url.mojom.Url source_url);
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
index 3319eda..fed9ec2b 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
@@ -169,7 +169,7 @@
         // It's a very real (and valid) possibility that a fling may still
         // be active when programatically scrolling. Cancelling the fling in
         // such cases ensures a consistent gesture event stream.
-        if (GestureListenerManagerImpl.fromWebContents(mWebContents).hasPotentiallyActiveFling()) {
+        if (GestureListenerManagerImpl.fromWebContents(mWebContents).hasActiveFlingScroll()) {
             nativeCancelFling(mNativeContentUiEventHandler, time);
         }
         nativeSendScrollEvent(mNativeContentUiEventHandler, time, dxPix, dyPix);
diff --git a/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java b/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java
index 43180afd..6cdcf09e 100644
--- a/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java
@@ -45,10 +45,6 @@
     private ViewAndroidDelegate mViewDelegate;
     private InternalAccessDelegate mScrollDelegate;
 
-    // The outstanding fling start events that hasn't got fling end yet. It may be > 1 because
-    // onFlingEnd() is called asynchronously.
-    private int mPotentiallyActiveFlingCount;
-
     private long mNativeGestureListenerManager;
 
     /**
@@ -59,6 +55,13 @@
     private boolean mIsTouchScrollInProgress;
 
     /**
+     * Whether a fling scroll is currently active. Used in combination with the
+     * above boolean for touch scrolling to determine if the content is
+     * "currently scrolling".
+     */
+    private boolean mHasActiveFlingScroll;
+
+    /**
      * @param webContents {@link WebContents} object.
      * @return {@link GestureListenerManager} object used for the give WebContents.
      *         Creates one if not present.
@@ -123,9 +126,9 @@
         for (mIterator.rewind(); mIterator.hasNext();) mIterator.next().onTouchDown();
     }
 
-    /** Checks if there's outstanding fling start events that hasn't got fling end yet. */
-    public boolean hasPotentiallyActiveFling() {
-        return mPotentiallyActiveFlingCount > 0;
+    /** Returns whether there's an active, ongoing fling scroll. */
+    public boolean hasActiveFlingScroll() {
+        return mHasActiveFlingScroll;
     }
 
     // WindowEventObserver
@@ -170,15 +173,15 @@
 
     /* Called when ongoing fling gesture needs to be reset. */
     public void resetFlingGesture() {
-        if (mPotentiallyActiveFlingCount > 0) {
+        if (mHasActiveFlingScroll) {
             onFlingEnd();
-            mPotentiallyActiveFlingCount = 0;
+            mHasActiveFlingScroll = false;
         }
     }
 
     @CalledByNative
     private void onFlingEnd() {
-        if (mPotentiallyActiveFlingCount > 0) mPotentiallyActiveFlingCount--;
+        mHasActiveFlingScroll = false;
         // Note that mTouchScrollInProgress should normally be false at this
         // point, but we reset it anyway as another failsafe.
         setTouchScrollInProgress(false);
@@ -193,7 +196,7 @@
             case WebInputEventType.GESTURE_FLING_START:
                 if (consumed) {
                     // The view expects the fling velocity in pixels/s.
-                    mPotentiallyActiveFlingCount++;
+                    mHasActiveFlingScroll = true;
                     setTouchScrollInProgress(false);
                     for (mIterator.rewind(); mIterator.hasNext();) {
                         mIterator.next().onFlingStartGesture(
@@ -333,7 +336,7 @@
 
     @Override
     public boolean isScrollInProgress() {
-        return mIsTouchScrollInProgress || hasPotentiallyActiveFling();
+        return mIsTouchScrollInProgress || mHasActiveFlingScroll;
     }
 
     void setTouchScrollInProgress(boolean touchScrollInProgress) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java b/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java
index 658cb78..a984f3b 100644
--- a/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java
@@ -63,7 +63,7 @@
         float velocityX = getVelocityFromJoystickAxis(event, MotionEvent.AXIS_X);
         float velocityY = getVelocityFromJoystickAxis(event, MotionEvent.AXIS_Y);
         if (velocityX == 0.f && velocityY == 0.f) return false;
-        mEventForwarder.startFling(event.getEventTime(), velocityX, velocityY, true);
+        mEventForwarder.startFling(event.getEventTime(), velocityX, velocityY, true, true);
         return true;
     }
 
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
index 881cc70..37119d45 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
@@ -116,7 +116,7 @@
             @Override
             public void run() {
                 mActivityTestRule.getWebContents().getEventForwarder().startFling(
-                        SystemClock.uptimeMillis(), vx, vy, false);
+                        SystemClock.uptimeMillis(), vx, vy, false, true);
             }
         });
     }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index c0bcc0ef..f2b919e5 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3539,6 +3539,7 @@
 
   std::unique_ptr<WorkerFetchContextImpl> worker_fetch_context =
       std::make_unique<WorkerFetchContextImpl>(
+          render_view_->renderer_preferences(),
           std::move(service_worker_client_request),
           std::move(service_worker_worker_client_registry_ptr_info),
           std::move(container_host_ptr_info), GetLoaderFactoryBundle()->Clone(),
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index b037e53..cbf52cbf 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -865,17 +865,22 @@
 void ServiceWorkerContextClient::DidEvaluateClassicScript(bool success) {
   DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
   start_timing_->script_evaluation_end_time = base::TimeTicks::Now();
-  (*instance_host_)->OnScriptEvaluated(success);
 
-  // Schedule a task to send back WorkerStarted asynchronously,
-  // so that at the time we send it we can be sure that the
-  // worker run loop has been started.
+  blink::mojom::ServiceWorkerStartStatus status =
+      success ? blink::mojom::ServiceWorkerStartStatus::kNormalCompletion
+              : blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion;
+
+  // Schedule a task to send back WorkerStarted asynchronously, so we can be
+  // sure that the worker is really started.
+  // TODO(falken): Is this really needed? Probably if kNormalCompletion, the
+  // worker is definitely running so we can SendStartWorker immediately.
   worker_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&ServiceWorkerContextClient::SendWorkerStarted,
-                                GetWeakPtr()));
+                                GetWeakPtr(), status));
 
   TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "EVALUATE_SCRIPT", this,
-                                  "Status", success ? "Success" : "Failure");
+                                  "Status",
+                                  ServiceWorkerUtils::MojoEnumToString(status));
 }
 
 void ServiceWorkerContextClient::DidInitializeWorkerContext(
@@ -1479,9 +1484,11 @@
   proxy_->DispatchPaymentRequestEvent(event_id, webEventData);
 }
 
-void ServiceWorkerContextClient::SendWorkerStarted() {
+void ServiceWorkerContextClient::SendWorkerStarted(
+    blink::mojom::ServiceWorkerStartStatus status) {
   DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
-  (*instance_host_)->OnStarted(std::move(start_timing_));
+
+  (*instance_host_)->OnStarted(status, std::move(start_timing_));
   TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "ServiceWorkerContextClient",
                                   this);
 
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h
index bba1476..cac0c0c 100644
--- a/content/renderer/service_worker/service_worker_context_client.h
+++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -271,7 +271,7 @@
   // in the browser process.
   int GetRoutingID() const { return embedded_worker_id_; }
 
-  void SendWorkerStarted();
+  void SendWorkerStarted(blink::mojom::ServiceWorkerStartStatus status);
 
   // Implements mojom::ServiceWorkerEventDispatcher.
   void InitializeGlobalScope(
diff --git a/content/renderer/service_worker/worker_fetch_context_impl.cc b/content/renderer/service_worker/worker_fetch_context_impl.cc
index 2e3524a..4c121c3 100644
--- a/content/renderer/service_worker/worker_fetch_context_impl.cc
+++ b/content/renderer/service_worker/worker_fetch_context_impl.cc
@@ -9,6 +9,7 @@
 #include "base/task_scheduler/post_task.h"
 #include "content/child/child_thread_impl.h"
 #include "content/child/thread_safe_sender.h"
+#include "content/common/content_constants_internal.h"
 #include "content/common/frame_messages.h"
 #include "content/common/service_worker/service_worker_provider.mojom.h"
 #include "content/common/service_worker/service_worker_utils.h"
@@ -141,6 +142,7 @@
 };
 
 WorkerFetchContextImpl::WorkerFetchContextImpl(
+    RendererPreferences renderer_preferences,
     mojom::ServiceWorkerWorkerClientRequest service_worker_client_request,
     mojom::ServiceWorkerWorkerClientRegistryPtrInfo
         service_worker_worker_client_registry_info,
@@ -161,6 +163,7 @@
       loader_factory_info_(std::move(loader_factory_info)),
       fallback_factory_info_(std::move(fallback_factory_info)),
       thread_safe_sender_(thread_safe_sender),
+      renderer_preferences_(std::move(renderer_preferences)),
       throttle_provider_(std::move(throttle_provider)),
       websocket_handshake_throttle_provider_(
           std::move(websocket_handshake_throttle_provider)),
@@ -181,7 +184,7 @@
   // currently not spec compliant and we don't want to propagate the wrong
   // behavior. See https://crbug.com/731604
   auto new_context = std::make_unique<WorkerFetchContextImpl>(
-      mojom::ServiceWorkerWorkerClientRequest(),
+      renderer_preferences_, mojom::ServiceWorkerWorkerClientRequest(),
       mojom::ServiceWorkerWorkerClientRegistryPtrInfo(),
       mojom::ServiceWorkerContainerHostPtrInfo(), loader_factory_->Clone(),
       fallback_factory_->Clone(),
@@ -251,6 +254,11 @@
 }
 
 void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
+  if (renderer_preferences_.enable_do_not_track) {
+    request.SetHTTPHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
+                               "1");
+  }
+
   auto extra_data = std::make_unique<RequestExtraData>();
   extra_data->set_service_worker_provider_id(service_worker_provider_id_);
   extra_data->set_render_frame_id(parent_frame_id_);
@@ -271,6 +279,11 @@
 
   if (g_rewrite_url)
     request.SetURL(g_rewrite_url(request.Url().GetString().Utf8(), false));
+
+  if (!renderer_preferences_.enable_referrers) {
+    request.SetHTTPReferrer(blink::WebString(),
+                            blink::kWebReferrerPolicyDefault);
+  }
 }
 
 blink::mojom::ControllerServiceWorkerMode
diff --git a/content/renderer/service_worker/worker_fetch_context_impl.h b/content/renderer/service_worker/worker_fetch_context_impl.h
index 87bc980..07cda56 100644
--- a/content/renderer/service_worker/worker_fetch_context_impl.h
+++ b/content/renderer/service_worker/worker_fetch_context_impl.h
@@ -8,6 +8,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "content/common/service_worker/service_worker_provider.mojom.h"
 #include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/renderer_preferences.h"
 #include "ipc/ipc_message.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -57,6 +58,7 @@
   // because it might additionally support non-NetworkService schemes (e.g.,
   // chrome-extension://).
   WorkerFetchContextImpl(
+      RendererPreferences renderer_preferences,
       mojom::ServiceWorkerWorkerClientRequest service_worker_client_request,
       mojom::ServiceWorkerWorkerClientRegistryPtrInfo
           service_worker_worker_client_registry_info,
@@ -190,6 +192,9 @@
   GURL origin_url_;
   int appcache_host_id_ = blink::WebApplicationCacheHost::kAppCacheNoHostId;
 
+  // TODO(shimazu): Propagate preference changes from the browser process.
+  RendererPreferences renderer_preferences_;
+
   // This is owned by ThreadedMessagingProxyBase on the main thread.
   base::WaitableEvent* terminate_sync_load_event_ = nullptr;
 
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
index 71d8792..22f4fe2 100644
--- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -18,6 +18,7 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/origin_util.h"
+#include "content/public/common/renderer_preferences.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/renderer/appcache/appcache_dispatcher.h"
 #include "content/renderer/appcache/web_application_cache_host_impl.h"
@@ -382,8 +383,12 @@
   // supposed to go through AppCache.
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory =
       loader_factories_->Clone();
+
+  // TODO(crbug.com/853085): Send the preference from the browser process.
+  RendererPreferences renderer_preferences;
+
   auto worker_fetch_context = std::make_unique<WorkerFetchContextImpl>(
-      std::move(worker_client_request),
+      std::move(renderer_preferences), std::move(worker_client_request),
       std::move(worker_client_registry_ptr_info),
       std::move(container_host_ptr_info), loader_factories_->Clone(),
       std::move(fallback_factory),
diff --git a/content/shell/test_runner/web_ax_object_proxy.cc b/content/shell/test_runner/web_ax_object_proxy.cc
index f185b2d..cc148f2c 100644
--- a/content/shell/test_runner/web_ax_object_proxy.cc
+++ b/content/shell/test_runner/web_ax_object_proxy.cc
@@ -744,7 +744,6 @@
       .SetMethod("boundsForRange", &WebAXObjectProxy::BoundsForRange)
       .SetMethod("childAtIndex", &WebAXObjectProxy::ChildAtIndex)
       .SetMethod("elementAtPoint", &WebAXObjectProxy::ElementAtPoint)
-      .SetMethod("tableHeader", &WebAXObjectProxy::TableHeader)
       .SetMethod("rowHeaderAtIndex", &WebAXObjectProxy::RowHeaderAtIndex)
       .SetMethod("columnHeaderAtIndex", &WebAXObjectProxy::ColumnHeaderAtIndex)
       .SetMethod("rowIndexRange", &WebAXObjectProxy::RowIndexRange)
@@ -1539,15 +1538,6 @@
   return factory_->GetOrCreate(obj);
 }
 
-v8::Local<v8::Object> WebAXObjectProxy::TableHeader() {
-  accessibility_object_.UpdateLayoutAndCheckValidity();
-  blink::WebAXObject obj = accessibility_object_.HeaderContainerObject();
-  if (obj.IsNull())
-    return v8::Local<v8::Object>();
-
-  return factory_->GetOrCreate(obj);
-}
-
 v8::Local<v8::Object> WebAXObjectProxy::RowHeaderAtIndex(unsigned index) {
   accessibility_object_.UpdateLayoutAndCheckValidity();
   blink::WebVector<blink::WebAXObject> headers;
diff --git a/content/test/data/service_worker/create_service_worker.html b/content/test/data/service_worker/create_service_worker.html
new file mode 100644
index 0000000..bf33568
--- /dev/null
+++ b/content/test/data/service_worker/create_service_worker.html
@@ -0,0 +1,8 @@
+<script>
+const params = new URLSearchParams(location.search);
+async function run() {
+  const reg = await navigator.serviceWorker.register(
+     params.get('worker_url'));
+}
+self.onload = run;
+</script>
diff --git a/content/test/data/service_worker/fetch_from_service_worker.html b/content/test/data/service_worker/fetch_from_service_worker.html
new file mode 100644
index 0000000..375b3d7
--- /dev/null
+++ b/content/test/data/service_worker/fetch_from_service_worker.html
@@ -0,0 +1,20 @@
+<script>
+async function run() {
+  const params = new URLSearchParams(location.search);
+  let reg = navigator.serviceWorker.register('fetch_from_service_worker.js');
+  if (!reg) {
+    document.body.innerText = 'Registration failed';
+    document.title = 'DONE';
+    return;
+  }
+  reg = await navigator.serviceWorker.ready;
+  const channel = new MessageChannel();
+  channel.port1.onmessage = e => {
+    document.body.innerText += e.data;
+    document.title = 'DONE';
+  };
+  reg.active.postMessage({url: params.get('url')}, [channel.port2]);
+}
+
+self.onload = run;
+</script>
diff --git a/content/test/data/service_worker/fetch_from_service_worker.js b/content/test/data/service_worker/fetch_from_service_worker.js
new file mode 100644
index 0000000..8fa001f
--- /dev/null
+++ b/content/test/data/service_worker/fetch_from_service_worker.js
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+async function MessageHandler(e) {
+  const response = await fetch(e.data.url);
+  if (!response.ok) {
+    e.ports[0].postMessage('bad response');
+    return;
+  }
+  const text = await response.text();
+  e.ports[0].postMessage(text);
+}
+
+self.addEventListener('message', e => {
+  e.waitUntil(MessageHandler(e));
+});
diff --git a/content/test/data/workers/create_shared_worker.html b/content/test/data/workers/create_shared_worker.html
new file mode 100644
index 0000000..6aa706d
--- /dev/null
+++ b/content/test/data/workers/create_shared_worker.html
@@ -0,0 +1,4 @@
+<script>
+const params = new URLSearchParams(location.search);
+const worker = new SharedWorker(params.get('worker_url'));
+</script>
diff --git a/content/test/data/workers/create_worker.html b/content/test/data/workers/create_worker.html
new file mode 100644
index 0000000..ca7f53f
--- /dev/null
+++ b/content/test/data/workers/create_worker.html
@@ -0,0 +1,4 @@
+<script>
+const params = new URLSearchParams(location.search);
+const worker = new Worker(params.get('worker_url'));
+</script>
diff --git a/content/test/data/workers/fetch_from_shared_worker.html b/content/test/data/workers/fetch_from_shared_worker.html
new file mode 100644
index 0000000..3d0a165c8
--- /dev/null
+++ b/content/test/data/workers/fetch_from_shared_worker.html
@@ -0,0 +1,10 @@
+<script>
+const params = new URLSearchParams(location.search);
+const worker = new SharedWorker(
+    `fetch_from_shared_worker.js?url=${params.get('url')}`);
+worker.port.onmessage = e => {
+  document.body.innerText += e.data;
+  document.title = 'DONE';
+};
+worker.port.start();
+</script>
diff --git a/content/test/data/workers/fetch_from_shared_worker.js b/content/test/data/workers/fetch_from_shared_worker.js
new file mode 100644
index 0000000..ce4d412a
--- /dev/null
+++ b/content/test/data/workers/fetch_from_shared_worker.js
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+self.onconnect = async e => {
+  const params = new URLSearchParams(location.search);
+  const response = await fetch(params.get('url'));
+  if (!response.ok) {
+    e.ports[0].postMessage(`Bad response: ${responses.statusText}`);
+    return;
+  }
+  const text = await response.text();
+  e.ports[0].postMessage(text);
+};
diff --git a/content/test/data/workers/fetch_from_worker.html b/content/test/data/workers/fetch_from_worker.html
new file mode 100644
index 0000000..b8a71e7d
--- /dev/null
+++ b/content/test/data/workers/fetch_from_worker.html
@@ -0,0 +1,8 @@
+<script>
+const params = new URLSearchParams(location.search);
+const worker = new Worker(`fetch_from_worker.js?url=${params.get('url')}`);
+worker.onmessage = e => {
+  document.body.innerText += e.data;
+  document.title = 'DONE';
+};
+</script>
diff --git a/content/test/data/workers/fetch_from_worker.js b/content/test/data/workers/fetch_from_worker.js
new file mode 100644
index 0000000..8568691
--- /dev/null
+++ b/content/test/data/workers/fetch_from_worker.js
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium 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 params = new URLSearchParams(location.search);
+
+async function run() {
+  const response = await fetch(params.get('url'));
+  if (!response.ok) {
+    self.postMessage('bad response');
+    return;
+  }
+  const text = await response.text();
+  self.postMessage(text);
+};
+
+run();
diff --git a/device/BUILD.gn b/device/BUILD.gn
index 1c0f140..1ddb4c35 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -294,6 +294,10 @@
       "bluetooth/test/fake_bluetooth_le_device_winrt.h",
       "bluetooth/test/fake_device_information_winrt.cc",
       "bluetooth/test/fake_device_information_winrt.h",
+      "bluetooth/test/fake_gatt_characteristic_winrt.cc",
+      "bluetooth/test/fake_gatt_characteristic_winrt.h",
+      "bluetooth/test/fake_gatt_characteristics_result_winrt.cc",
+      "bluetooth/test/fake_gatt_characteristics_result_winrt.h",
       "bluetooth/test/fake_gatt_device_service_winrt.cc",
       "bluetooth/test/fake_gatt_device_service_winrt.h",
       "bluetooth/test/fake_gatt_device_services_result_winrt.cc",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index d5f5233..1585804 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -244,6 +244,8 @@
       "bluetooth_device_winrt.h",
       "bluetooth_gatt_discoverer_winrt.cc",
       "bluetooth_gatt_discoverer_winrt.h",
+      "bluetooth_remote_gatt_characteristic_winrt.cc",
+      "bluetooth_remote_gatt_characteristic_winrt.h",
       "bluetooth_remote_gatt_service_winrt.cc",
       "bluetooth_remote_gatt_service_winrt.h",
       "event_utils_winrt.h",
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.cc
new file mode 100644
index 0000000..69562d1
--- /dev/null
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.cc
@@ -0,0 +1,91 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h"
+
+#include "base/logging.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+
+namespace device {
+
+BluetoothRemoteGattCharacteristicWinrt::
+    BluetoothRemoteGattCharacteristicWinrt() = default;
+
+BluetoothRemoteGattCharacteristicWinrt::
+    ~BluetoothRemoteGattCharacteristicWinrt() = default;
+
+std::string BluetoothRemoteGattCharacteristicWinrt::GetIdentifier() const {
+  NOTIMPLEMENTED();
+  return std::string();
+}
+
+BluetoothUUID BluetoothRemoteGattCharacteristicWinrt::GetUUID() const {
+  NOTIMPLEMENTED();
+  return BluetoothUUID();
+}
+
+BluetoothGattCharacteristic::Properties
+BluetoothRemoteGattCharacteristicWinrt::GetProperties() const {
+  NOTIMPLEMENTED();
+  return Properties();
+}
+
+BluetoothGattCharacteristic::Permissions
+BluetoothRemoteGattCharacteristicWinrt::GetPermissions() const {
+  NOTIMPLEMENTED();
+  return Permissions();
+}
+
+const std::vector<uint8_t>& BluetoothRemoteGattCharacteristicWinrt::GetValue()
+    const {
+  return value_;
+}
+
+BluetoothRemoteGattService* BluetoothRemoteGattCharacteristicWinrt::GetService()
+    const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+std::vector<BluetoothRemoteGattDescriptor*>
+BluetoothRemoteGattCharacteristicWinrt::GetDescriptors() const {
+  NOTIMPLEMENTED();
+  return {};
+}
+
+BluetoothRemoteGattDescriptor*
+BluetoothRemoteGattCharacteristicWinrt::GetDescriptor(
+    const std::string& identifier) const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void BluetoothRemoteGattCharacteristicWinrt::ReadRemoteCharacteristic(
+    const ValueCallback& callback,
+    const ErrorCallback& error_callback) {
+  NOTIMPLEMENTED();
+}
+
+void BluetoothRemoteGattCharacteristicWinrt::WriteRemoteCharacteristic(
+    const std::vector<uint8_t>& value,
+    const base::Closure& callback,
+    const ErrorCallback& error_callback) {
+  NOTIMPLEMENTED();
+}
+
+void BluetoothRemoteGattCharacteristicWinrt::SubscribeToNotifications(
+    BluetoothRemoteGattDescriptor* ccc_descriptor,
+    const base::Closure& callback,
+    const ErrorCallback& error_callback) {
+  NOTIMPLEMENTED();
+}
+
+void BluetoothRemoteGattCharacteristicWinrt::UnsubscribeFromNotifications(
+    BluetoothRemoteGattDescriptor* ccc_descriptor,
+    const base::Closure& callback,
+    const ErrorCallback& error_callback) {
+  NOTIMPLEMENTED();
+}
+
+}  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h
new file mode 100644
index 0000000..0c5de24
--- /dev/null
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h
@@ -0,0 +1,66 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_WINRT_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_WINRT_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
+
+namespace device {
+
+class BluetoothRemoteGattDescriptor;
+class BluetoothRemoteGattService;
+class BluetoothUUID;
+
+class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicWinrt
+    : public BluetoothRemoteGattCharacteristic {
+ public:
+  BluetoothRemoteGattCharacteristicWinrt();
+  ~BluetoothRemoteGattCharacteristicWinrt() override;
+
+  // BluetoothGattCharacteristic:
+  std::string GetIdentifier() const override;
+  BluetoothUUID GetUUID() const override;
+  Properties GetProperties() const override;
+  Permissions GetPermissions() const override;
+
+  // BluetoothRemoteGattCharacteristic:
+  const std::vector<uint8_t>& GetValue() const override;
+  BluetoothRemoteGattService* GetService() const override;
+  std::vector<BluetoothRemoteGattDescriptor*> GetDescriptors() const override;
+  BluetoothRemoteGattDescriptor* GetDescriptor(
+      const std::string& identifier) const override;
+  void ReadRemoteCharacteristic(const ValueCallback& callback,
+                                const ErrorCallback& error_callback) override;
+  void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
+                                 const base::Closure& callback,
+                                 const ErrorCallback& error_callback) override;
+
+ protected:
+  // BluetoothRemoteGattCharacteristic:
+  void SubscribeToNotifications(BluetoothRemoteGattDescriptor* ccc_descriptor,
+                                const base::Closure& callback,
+                                const ErrorCallback& error_callback) override;
+  void UnsubscribeFromNotifications(
+      BluetoothRemoteGattDescriptor* ccc_descriptor,
+      const base::Closure& callback,
+      const ErrorCallback& error_callback) override;
+
+ private:
+  std::vector<uint8_t> value_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicWinrt);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_WINRT_H_
diff --git a/device/bluetooth/test/fake_gatt_characteristic_winrt.cc b/device/bluetooth/test/fake_gatt_characteristic_winrt.cc
new file mode 100644
index 0000000..3e80c154
--- /dev/null
+++ b/device/bluetooth/test/fake_gatt_characteristic_winrt.cc
@@ -0,0 +1,135 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/test/fake_gatt_characteristic_winrt.h"
+
+namespace device {
+
+namespace {
+
+using ABI::Windows::Devices::Bluetooth::BluetoothCacheMode;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattCharacteristic;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattCharacteristic;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattCharacteristicProperties;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattClientCharacteristicConfigurationDescriptorValue;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattCommunicationStatus;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattDescriptor;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattPresentationFormat;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattProtectionLevel;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattReadClientCharacteristicConfigurationDescriptorResult;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattReadResult;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattValueChangedEventArgs;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattWriteOption;
+using ABI::Windows::Foundation::Collections::IVectorView;
+using ABI::Windows::Foundation::IAsyncOperation;
+using ABI::Windows::Foundation::ITypedEventHandler;
+using ABI::Windows::Storage::Streams::IBuffer;
+
+}  // namespace
+
+FakeGattCharacteristicWinrt::FakeGattCharacteristicWinrt() = default;
+
+FakeGattCharacteristicWinrt::~FakeGattCharacteristicWinrt() = default;
+
+HRESULT FakeGattCharacteristicWinrt::GetDescriptors(
+    GUID descriptor_uuid,
+    IVectorView<GattDescriptor*>** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::get_CharacteristicProperties(
+    GattCharacteristicProperties* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::get_ProtectionLevel(
+    GattProtectionLevel* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::put_ProtectionLevel(
+    GattProtectionLevel value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::get_UserDescription(HSTRING* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::get_Uuid(GUID* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::get_AttributeHandle(uint16_t* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::get_PresentationFormats(
+    IVectorView<GattPresentationFormat*>** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::ReadValueAsync(
+    IAsyncOperation<GattReadResult*>** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::ReadValueWithCacheModeAsync(
+    BluetoothCacheMode cache_mode,
+    IAsyncOperation<GattReadResult*>** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::WriteValueAsync(
+    IBuffer* value,
+    IAsyncOperation<GattCommunicationStatus>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::WriteValueWithOptionAsync(
+    IBuffer* value,
+    GattWriteOption write_option,
+    IAsyncOperation<GattCommunicationStatus>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::
+    ReadClientCharacteristicConfigurationDescriptorAsync(
+        IAsyncOperation<
+            GattReadClientCharacteristicConfigurationDescriptorResult*>**
+            async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::
+    WriteClientCharacteristicConfigurationDescriptorAsync(
+        GattClientCharacteristicConfigurationDescriptorValue
+            client_characteristic_configuration_descriptor_value,
+        IAsyncOperation<GattCommunicationStatus>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::add_ValueChanged(
+    ITypedEventHandler<GattCharacteristic*, GattValueChangedEventArgs*>*
+        value_changed_handler,
+    EventRegistrationToken* value_changed_event_cookie) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicWinrt::remove_ValueChanged(
+    EventRegistrationToken value_changed_event_cookie) {
+  return E_NOTIMPL;
+}
+
+}  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_characteristic_winrt.h b/device/bluetooth/test/fake_gatt_characteristic_winrt.h
new file mode 100644
index 0000000..c381d3ac
--- /dev/null
+++ b/device/bluetooth/test/fake_gatt_characteristic_winrt.h
@@ -0,0 +1,99 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_TEST_FAKE_GATT_CHARACTERISTIC_WINRT_H_
+#define DEVICE_BLUETOOTH_TEST_FAKE_GATT_CHARACTERISTIC_WINRT_H_
+
+#include <windows.devices.bluetooth.genericattributeprofile.h>
+#include <windows.foundation.collections.h>
+#include <wrl/implements.h>
+
+#include <stdint.h>
+
+#include "base/macros.h"
+
+namespace device {
+
+class FakeGattCharacteristicWinrt
+    : public Microsoft::WRL::RuntimeClass<
+          Microsoft::WRL::RuntimeClassFlags<
+              Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              IGattCharacteristic> {
+ public:
+  FakeGattCharacteristicWinrt();
+  ~FakeGattCharacteristicWinrt() override;
+
+  // IGattCharacteristic:
+  IFACEMETHODIMP GetDescriptors(
+      GUID descriptor_uuid,
+      ABI::Windows::Foundation::Collections::IVectorView<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattDescriptor*>** value) override;
+  IFACEMETHODIMP get_CharacteristicProperties(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+          GattCharacteristicProperties* value) override;
+  IFACEMETHODIMP get_ProtectionLevel(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+          GattProtectionLevel* value) override;
+  IFACEMETHODIMP put_ProtectionLevel(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+          GattProtectionLevel value) override;
+  IFACEMETHODIMP get_UserDescription(HSTRING* value) override;
+  IFACEMETHODIMP get_Uuid(GUID* value) override;
+  IFACEMETHODIMP get_AttributeHandle(uint16_t* value) override;
+  IFACEMETHODIMP get_PresentationFormats(
+      ABI::Windows::Foundation::Collections::IVectorView<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattPresentationFormat*>** value) override;
+  IFACEMETHODIMP ReadValueAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattReadResult*>** value) override;
+  IFACEMETHODIMP ReadValueWithCacheModeAsync(
+      ABI::Windows::Devices::Bluetooth::BluetoothCacheMode cache_mode,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattReadResult*>** value) override;
+  IFACEMETHODIMP WriteValueAsync(
+      ABI::Windows::Storage::Streams::IBuffer* value,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCommunicationStatus>** async_op) override;
+  IFACEMETHODIMP WriteValueWithOptionAsync(
+      ABI::Windows::Storage::Streams::IBuffer* value,
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattWriteOption
+          write_option,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCommunicationStatus>** async_op) override;
+  IFACEMETHODIMP ReadClientCharacteristicConfigurationDescriptorAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattReadClientCharacteristicConfigurationDescriptorResult*>**
+          async_op) override;
+  IFACEMETHODIMP WriteClientCharacteristicConfigurationDescriptorAsync(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+          GattClientCharacteristicConfigurationDescriptorValue
+              client_characteristic_configuration_descriptor_value,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCommunicationStatus>** async_op) override;
+  IFACEMETHODIMP add_ValueChanged(
+      ABI::Windows::Foundation::ITypedEventHandler<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCharacteristic*,
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattValueChangedEventArgs*>* value_changed_handler,
+      EventRegistrationToken* value_changed_event_cookie) override;
+  IFACEMETHODIMP remove_ValueChanged(
+      EventRegistrationToken value_changed_event_cookie) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeGattCharacteristicWinrt);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_BLUETOOTH_TEST_FAKE_GATT_CHARACTERISTIC_WINRT_H_
diff --git a/device/bluetooth/test/fake_gatt_characteristics_result_winrt.cc b/device/bluetooth/test/fake_gatt_characteristics_result_winrt.cc
new file mode 100644
index 0000000..86aa2f7
--- /dev/null
+++ b/device/bluetooth/test/fake_gatt_characteristics_result_winrt.cc
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/test/fake_gatt_characteristics_result_winrt.h"
+
+namespace device {
+
+namespace {
+
+using ABI::Windows::Foundation::Collections::IVectorView;
+using ABI::Windows::Foundation::IReference;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattCharacteristic;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattCommunicationStatus;
+
+}  // namespace
+
+FakeGattCharacteristicsResultWinrt::FakeGattCharacteristicsResultWinrt() =
+    default;
+
+FakeGattCharacteristicsResultWinrt::~FakeGattCharacteristicsResultWinrt() =
+    default;
+
+HRESULT FakeGattCharacteristicsResultWinrt::get_Status(
+    GattCommunicationStatus* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicsResultWinrt::get_ProtocolError(
+    IReference<uint8_t>** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattCharacteristicsResultWinrt::get_Characteristics(
+    IVectorView<GattCharacteristic*>** value) {
+  return E_NOTIMPL;
+}
+
+}  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_characteristics_result_winrt.h b/device/bluetooth/test/fake_gatt_characteristics_result_winrt.h
new file mode 100644
index 0000000..2156956
--- /dev/null
+++ b/device/bluetooth/test/fake_gatt_characteristics_result_winrt.h
@@ -0,0 +1,46 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_TEST_FAKE_GATT_CHARACTERISTICS_RESULT_WINRT_H_
+#define DEVICE_BLUETOOTH_TEST_FAKE_GATT_CHARACTERISTICS_RESULT_WINRT_H_
+
+#include <windows.devices.bluetooth.genericattributeprofile.h>
+#include <windows.foundation.collections.h>
+#include <windows.foundation.h>
+#include <wrl/implements.h>
+
+#include <stdint.h>
+
+#include "base/macros.h"
+
+namespace device {
+
+class FakeGattCharacteristicsResultWinrt
+    : public Microsoft::WRL::RuntimeClass<
+          Microsoft::WRL::RuntimeClassFlags<
+              Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              IGattCharacteristicsResult> {
+ public:
+  FakeGattCharacteristicsResultWinrt();
+  ~FakeGattCharacteristicsResultWinrt() override;
+
+  // IGattCharacteristicsResult:
+  IFACEMETHODIMP get_Status(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+          GattCommunicationStatus* value) override;
+  IFACEMETHODIMP get_ProtocolError(
+      ABI::Windows::Foundation::IReference<uint8_t>** value) override;
+  IFACEMETHODIMP get_Characteristics(
+      ABI::Windows::Foundation::Collections::IVectorView<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCharacteristic*>** value) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeGattCharacteristicsResultWinrt);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_BLUETOOTH_TEST_FAKE_GATT_CHARACTERISTICS_RESULT_WINRT_H_
diff --git a/device/bluetooth/test/fake_gatt_device_service_winrt.cc b/device/bluetooth/test/fake_gatt_device_service_winrt.cc
index f872d575..23ed356 100644
--- a/device/bluetooth/test/fake_gatt_device_service_winrt.cc
+++ b/device/bluetooth/test/fake_gatt_device_service_winrt.cc
@@ -15,11 +15,23 @@
 
 namespace {
 
+using ABI::Windows::Devices::Bluetooth::BluetoothCacheMode;
 using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
     GattCharacteristic;
 using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattCharacteristicsResult;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
     GattDeviceService;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattDeviceServicesResult;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattOpenStatus;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+    GattSharingMode;
+using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattSession;
+using ABI::Windows::Devices::Enumeration::DeviceAccessStatus;
+using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation;
 using ABI::Windows::Foundation::Collections::IVectorView;
+using ABI::Windows::Foundation::IAsyncOperation;
 
 }  // namespace
 
@@ -57,4 +69,77 @@
   return S_OK;
 }
 
+HRESULT FakeGattDeviceServiceWinrt::get_DeviceAccessInformation(
+    IDeviceAccessInformation** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::get_Session(IGattSession** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::get_SharingMode(GattSharingMode* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::RequestAccessAsync(
+    IAsyncOperation<DeviceAccessStatus>** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::OpenAsync(
+    GattSharingMode sharing_mode,
+    IAsyncOperation<GattOpenStatus>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::GetCharacteristicsAsync(
+    IAsyncOperation<GattCharacteristicsResult*>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::GetCharacteristicsWithCacheModeAsync(
+    BluetoothCacheMode cache_mode,
+    IAsyncOperation<GattCharacteristicsResult*>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::GetCharacteristicsForUuidAsync(
+    GUID characteristic_uuid,
+    IAsyncOperation<GattCharacteristicsResult*>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::GetCharacteristicsForUuidWithCacheModeAsync(
+    GUID characteristic_uuid,
+    BluetoothCacheMode cache_mode,
+    IAsyncOperation<GattCharacteristicsResult*>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::GetIncludedServicesAsync(
+    IAsyncOperation<GattDeviceServicesResult*>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::GetIncludedServicesWithCacheModeAsync(
+    BluetoothCacheMode cache_mode,
+    IAsyncOperation<GattDeviceServicesResult*>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeGattDeviceServiceWinrt::GetIncludedServicesForUuidAsync(
+    GUID service_uuid,
+    IAsyncOperation<GattDeviceServicesResult*>** operation) {
+  return E_NOTIMPL;
+}
+
+HRESULT
+FakeGattDeviceServiceWinrt::GetIncludedServicesForUuidWithCacheModeAsync(
+    GUID service_uuid,
+    BluetoothCacheMode cache_mode,
+    IAsyncOperation<GattDeviceServicesResult*>** operation) {
+  return E_NOTIMPL;
+}
+
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_device_service_winrt.h b/device/bluetooth/test/fake_gatt_device_service_winrt.h
index d6bbb18..bc53ffa 100644
--- a/device/bluetooth/test/fake_gatt_device_service_winrt.h
+++ b/device/bluetooth/test/fake_gatt_device_service_winrt.h
@@ -21,7 +21,9 @@
           Microsoft::WRL::RuntimeClassFlags<
               Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
           ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
-              IGattDeviceService> {
+              IGattDeviceService,
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              IGattDeviceService3> {
  public:
   FakeGattDeviceServiceWinrt(uint16_t attribute_handle, base::StringPiece uuid);
   ~FakeGattDeviceServiceWinrt() override;
@@ -41,6 +43,67 @@
   IFACEMETHODIMP get_Uuid(GUID* value) override;
   IFACEMETHODIMP get_AttributeHandle(uint16_t* value) override;
 
+  // IGattDeviceService3:
+  IFACEMETHODIMP get_DeviceAccessInformation(
+      ABI::Windows::Devices::Enumeration::IDeviceAccessInformation** value)
+      override;
+  IFACEMETHODIMP get_Session(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattSession**
+          value) override;
+  IFACEMETHODIMP get_SharingMode(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+          GattSharingMode* value) override;
+  IFACEMETHODIMP RequestAccessAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceAccessStatus>** value)
+      override;
+  IFACEMETHODIMP OpenAsync(
+      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattSharingMode
+          sharing_mode,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattOpenStatus>** operation) override;
+  IFACEMETHODIMP GetCharacteristicsAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCharacteristicsResult*>** operation) override;
+  IFACEMETHODIMP GetCharacteristicsWithCacheModeAsync(
+      ABI::Windows::Devices::Bluetooth::BluetoothCacheMode cache_mode,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCharacteristicsResult*>** operation) override;
+  IFACEMETHODIMP GetCharacteristicsForUuidAsync(
+      GUID characteristic_uuid,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCharacteristicsResult*>** operation) override;
+  IFACEMETHODIMP GetCharacteristicsForUuidWithCacheModeAsync(
+      GUID characteristic_uuid,
+      ABI::Windows::Devices::Bluetooth::BluetoothCacheMode cache_mode,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattCharacteristicsResult*>** operation) override;
+  IFACEMETHODIMP GetIncludedServicesAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattDeviceServicesResult*>** operation) override;
+  IFACEMETHODIMP GetIncludedServicesWithCacheModeAsync(
+      ABI::Windows::Devices::Bluetooth::BluetoothCacheMode cache_mode,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattDeviceServicesResult*>** operation) override;
+  IFACEMETHODIMP GetIncludedServicesForUuidAsync(
+      GUID service_uuid,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattDeviceServicesResult*>** operation) override;
+  IFACEMETHODIMP GetIncludedServicesForUuidWithCacheModeAsync(
+      GUID service_uuid,
+      ABI::Windows::Devices::Bluetooth::BluetoothCacheMode cache_mode,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
+              GattDeviceServicesResult*>** operation) override;
+
  private:
   uint16_t attribute_handle_;
   GUID uuid_;
diff --git a/docs/speed/bot_health_sheriffing/main.md b/docs/speed/bot_health_sheriffing/main.md
index 624e151d..f327ea85 100644
--- a/docs/speed/bot_health_sheriffing/main.md
+++ b/docs/speed/bot_health_sheriffing/main.md
@@ -32,7 +32,7 @@
 
 Incoming failures are shown in [Sheriff-o-matic](https://sheriff-o-matic.appspot.com/chromium.perf), which acts as a task management system for bot health sheriffs. Failures are divided into three groups on the dashboard:
 
-* **Infra failures** show general infrastructure problems that are affecting benchmarks.
+* **Infra failures** show general infrastructure problems that are affecting benchmarks.  Besides surfacing in Sheriff-o-matic, we also need to check for down bots in the lame duck pool.  Please file a ticket for any bots you see in [this list](https://chrome-swarming.appspot.com/botlist?c=id&c=os&c=task&c=status&c=os&c=task&c=status&c=pool&f=status%3Adead&f=pool%3Achrome.tests.perf&l=100&q=pool%3Achrome.tests.perf&s=id%3Aasc) or [this list for webview](https://chrome-swarming.appspot.com/botlist?c=id&c=os&c=task&c=status&c=os&c=task&c=status&c=pool&f=status%3Adead&f=pool%3Achrome.tests.perf-webview&l=100&q=pool%3Achrome.tests.perf&s=id%3Aasc) as they will not show up in Sheriff-o-matic.
 
 * **Consistent failures** show benchmarks that have been failing for a while.
 
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc
index 3126ae7..9ac31f5a 100644
--- a/extensions/browser/extension_prefs.cc
+++ b/extensions/browser/extension_prefs.cc
@@ -736,6 +736,10 @@
   int value = -1;
   if (ReadPrefAsInteger(extension_id, kPrefDisableReasons, &value) &&
       value >= 0) {
+    // TODO(crbug.com/860198): After we've gotten rid of the migration code for
+    // DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC, we should maybe filter it out here
+    // just to be sure:
+    // value = value & ~disable_reason::DEPRECATED_DISABLE_UNKNOWN_FROM_SYNC;
     return value;
   }
   return disable_reason::DISABLE_NONE;
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
index 59b8224..bd0fc15 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/guest_view/browser/test_guest_view_manager.h"
 #include "content/public/browser/browser_thread.h"
@@ -218,3 +219,14 @@
   extensions::ProcessManager::SetEventPageSuspendingTimeForTesting(1);
   RunTest("testBackgroundPage.csv");
 }
+
+IN_PROC_BROWSER_TEST_P(MimeHandlerViewTest, TargetBlankAnchor) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kDisablePopupBlocking);
+  RunTest("testTargetBlankAnchor.csv");
+  ASSERT_EQ(2, browser()->tab_strip_model()->count());
+  content::WaitForLoadStop(browser()->tab_strip_model()->GetWebContentsAt(1));
+  EXPECT_EQ(
+      GURL("about:blank"),
+      browser()->tab_strip_model()->GetWebContentsAt(1)->GetLastCommittedURL());
+}
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
index 5adcb21..a2a8e427 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -334,6 +334,27 @@
   return is_guest_fullscreen_;
 }
 
+bool MimeHandlerViewGuest::ShouldCreateWebContents(
+    content::WebContents* web_contents,
+    content::RenderFrameHost* opener,
+    content::SiteInstance* source_site_instance,
+    int32_t route_id,
+    int32_t main_frame_route_id,
+    int32_t main_frame_widget_route_id,
+    content::mojom::WindowContainerType window_container_type,
+    const GURL& opener_url,
+    const std::string& frame_name,
+    const GURL& target_url,
+    const std::string& partition_id,
+    content::SessionStorageNamespace* session_storage_namespace) {
+  embedder_web_contents()->GetDelegate()->OpenURLFromTab(
+      embedder_web_contents(),
+      content::OpenURLParams(target_url, content::Referrer(),
+                             WindowOpenDisposition::NEW_FOREGROUND_TAB,
+                             ui::PAGE_TRANSITION_LINK, true));
+  return false;
+}
+
 bool MimeHandlerViewGuest::SetFullscreenState(bool is_fullscreen) {
   // Disallow fullscreen for embedded plugins.
   if (!is_full_page_plugin() || is_fullscreen == is_guest_fullscreen_)
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
index adcb0864..2a74abb3 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -128,6 +128,19 @@
   void ExitFullscreenModeForTab(content::WebContents*) override;
   bool IsFullscreenForTabOrPending(
       const content::WebContents* web_contents) const override;
+  bool ShouldCreateWebContents(
+      content::WebContents* web_contents,
+      content::RenderFrameHost* opener,
+      content::SiteInstance* source_site_instance,
+      int32_t route_id,
+      int32_t main_frame_route_id,
+      int32_t main_frame_widget_route_id,
+      content::mojom::WindowContainerType window_container_type,
+      const GURL& opener_url,
+      const std::string& frame_name,
+      const GURL& target_url,
+      const std::string& partition_id,
+      content::SessionStorageNamespace* session_storage_namespace) override;
 
   // Updates the fullscreen state for the guest. Returns whether the change
   // needs to be propagated to the embedder.
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc
index ea241e8..1d61d20f 100644
--- a/extensions/common/url_pattern.cc
+++ b/extensions/common/url_pattern.cc
@@ -161,8 +161,13 @@
       match_effective_tld_(true),
       port_("*") {
   ParseResult result = Parse(pattern);
-  if (PARSE_SUCCESS != result)
+  if (PARSE_SUCCESS != result) {
+    // Temporarily add more logging to investigate why this code path is
+    // reached. For http://crbug.com/856948
+    LOG(ERROR) << "Invalid pattern was given " << pattern << " result "
+               << result;
     NOTREACHED() << "URLPattern invalid: " << pattern << " result " << result;
+  }
 }
 
 URLPattern::URLPattern(const URLPattern& other) = default;
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc
index 2e1a0b9..b5e473a 100644
--- a/headless/lib/browser/headless_web_contents_impl.cc
+++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -95,7 +95,7 @@
     auto* const headless_contents =
         HeadlessWebContentsImpl::From(browser(), source);
     DCHECK(headless_contents);
-    headless_contents->DelegateRequestsClose();
+    headless_contents->Close();
   }
 
   void AddNewContents(content::WebContents* source,
@@ -379,29 +379,9 @@
 
 void HeadlessWebContentsImpl::Close() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  if (quit_closure_)
-    return;
-
-  if (!render_process_exited_) {
-    web_contents_->ClosePage();
-    base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
-    quit_closure_ = run_loop.QuitClosure();
-    run_loop.Run();
-  }
-
   browser_context()->DestroyWebContents(this);
 }
 
-void HeadlessWebContentsImpl::DelegateRequestsClose() {
-  if (quit_closure_) {
-    quit_closure_.Run();
-    quit_closure_ = base::Closure();
-  } else {
-    browser_context()->DestroyWebContents(this);
-  }
-}
-
 std::string HeadlessWebContentsImpl::GetDevToolsAgentHostId() {
   return agent_host_->GetId();
 }
diff --git a/headless/lib/browser/headless_web_contents_impl.h b/headless/lib/browser/headless_web_contents_impl.h
index 7a010ee..7a0bb87 100644
--- a/headless/lib/browser/headless_web_contents_impl.h
+++ b/headless/lib/browser/headless_web_contents_impl.h
@@ -99,8 +99,6 @@
 
   void Close() override;
 
-  void DelegateRequestsClose();
-
   std::string GetDevToolsAgentHostId();
 
   HeadlessBrowserImpl* browser() const;
@@ -178,8 +176,6 @@
 
   base::ObserverList<HeadlessWebContents::Observer> observers_;
 
-  base::Closure quit_closure_;
-
   base::WeakPtrFactory<HeadlessWebContentsImpl> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(HeadlessWebContentsImpl);
diff --git a/headless/lib/headless_devtools_client_browsertest.cc b/headless/lib/headless_devtools_client_browsertest.cc
index 02cc620..a7bbb84 100644
--- a/headless/lib/headless_devtools_client_browsertest.cc
+++ b/headless/lib/headless_devtools_client_browsertest.cc
@@ -409,132 +409,6 @@
 
 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientExperimentalTest);
 
-class TargetDomainCreateAndDeletePageTest
-    : public HeadlessAsyncDevTooledBrowserTest {
-  void RunDevTooledTest() override {
-    EXPECT_TRUE(embedded_test_server()->Start());
-
-    EXPECT_EQ(1u, GetAllWebContents(browser()).size());
-
-    devtools_client_->GetTarget()->GetExperimental()->CreateTarget(
-        target::CreateTargetParams::Builder()
-            .SetUrl(embedded_test_server()->GetURL("/hello.html").spec())
-            .SetWidth(1)
-            .SetHeight(1)
-            .Build(),
-        base::BindOnce(
-            &TargetDomainCreateAndDeletePageTest::OnCreateTargetResult,
-            base::Unretained(this)));
-  }
-
-  void OnCreateTargetResult(
-      std::unique_ptr<target::CreateTargetResult> result) {
-    EXPECT_EQ(2u, GetAllWebContents(browser()).size());
-
-    HeadlessWebContentsImpl* contents = HeadlessWebContentsImpl::From(
-        browser()->GetWebContentsForDevToolsAgentHostId(result->GetTargetId()));
-    EXPECT_SIZE_EQ(gfx::Size(1, 1), contents->web_contents()
-                                        ->GetRenderWidgetHostView()
-                                        ->GetViewBounds()
-                                        .size());
-
-    devtools_client_->GetTarget()->GetExperimental()->CloseTarget(
-        target::CloseTargetParams::Builder()
-            .SetTargetId(result->GetTargetId())
-            .Build(),
-        base::BindOnce(
-            &TargetDomainCreateAndDeletePageTest::OnCloseTargetResult,
-            base::Unretained(this)));
-  }
-
-  void OnCloseTargetResult(std::unique_ptr<target::CloseTargetResult> result) {
-    EXPECT_TRUE(result->GetSuccess());
-    EXPECT_EQ(1u, GetAllWebContents(browser()).size());
-    FinishAsynchronousTest();
-  }
-};
-
-// Disabled due to flakes; see https://crbug.com/856720.
-DISABLED_HEADLESS_ASYNC_DEVTOOLED_TEST_F(TargetDomainCreateAndDeletePageTest);
-
-class TargetDomainCreateAndDeleteBrowserContextTest
-    : public HeadlessAsyncDevTooledBrowserTest {
-  void RunDevTooledTest() override {
-    EXPECT_TRUE(embedded_test_server()->Start());
-
-    EXPECT_EQ(1u, GetAllWebContents(browser()).size());
-
-    devtools_client_->GetTarget()->GetExperimental()->CreateBrowserContext(
-        target::CreateBrowserContextParams::Builder().Build(),
-        base::BindOnce(&TargetDomainCreateAndDeleteBrowserContextTest::
-                           OnCreateContextResult,
-                       base::Unretained(this)));
-  }
-
-  void OnCreateContextResult(
-      std::unique_ptr<target::CreateBrowserContextResult> result) {
-    browser_context_id_ = result->GetBrowserContextId();
-
-    devtools_client_->GetTarget()->GetExperimental()->CreateTarget(
-        target::CreateTargetParams::Builder()
-            .SetUrl(embedded_test_server()->GetURL("/hello.html").spec())
-            .SetBrowserContextId(result->GetBrowserContextId())
-            .SetWidth(1)
-            .SetHeight(1)
-            .Build(),
-        base::BindOnce(&TargetDomainCreateAndDeleteBrowserContextTest::
-                           OnCreateTargetResult,
-                       base::Unretained(this)));
-  }
-
-  void OnCreateTargetResult(
-      std::unique_ptr<target::CreateTargetResult> result) {
-    EXPECT_EQ(2u, GetAllWebContents(browser()).size());
-
-    devtools_client_->GetTarget()->GetExperimental()->CloseTarget(
-        target::CloseTargetParams::Builder()
-            .SetTargetId(result->GetTargetId())
-            .Build(),
-        base::BindOnce(
-            &TargetDomainCreateAndDeleteBrowserContextTest::OnCloseTargetResult,
-            base::Unretained(this)));
-  }
-
-  void OnCloseTargetResult(std::unique_ptr<target::CloseTargetResult> result) {
-    EXPECT_EQ(1u, GetAllWebContents(browser()).size());
-    EXPECT_TRUE(result->GetSuccess());
-
-    devtools_client_->GetTarget()->GetExperimental()->DisposeBrowserContext(
-        target::DisposeBrowserContextParams::Builder()
-            .SetBrowserContextId(browser_context_id_)
-            .Build(),
-        base::BindOnce(&TargetDomainCreateAndDeleteBrowserContextTest::
-                           OnDisposeBrowserContextResult,
-                       base::Unretained(this)));
-  }
-
-  void OnDisposeBrowserContextResult(
-      std::unique_ptr<target::DisposeBrowserContextResult> result) {
-    devtools_client_->GetTarget()->GetExperimental()->GetBrowserContexts(
-        target::GetBrowserContextsParams::Builder().Build(),
-        base::BindOnce(&TargetDomainCreateAndDeleteBrowserContextTest::
-                           OnGetBrowserContexts,
-                       base::Unretained(this)));
-  }
-
-  void OnGetBrowserContexts(
-      std::unique_ptr<target::GetBrowserContextsResult> result) {
-    const std::vector<std::string>* contexts = result->GetBrowserContextIds();
-    EXPECT_EQ(0u, contexts->size());
-    FinishAsynchronousTest();
-  }
-
- private:
-  std::string browser_context_id_;
-};
-
-HEADLESS_ASYNC_DEVTOOLED_TEST_F(TargetDomainCreateAndDeleteBrowserContextTest);
-
 class TargetDomainDisposeContextSucceedsIfInUse
     : public target::Observer,
       public HeadlessAsyncDevTooledBrowserTest {
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg
index 2fdd8e73..eec1b00 100644
--- a/infra/config/global/cr-buildbucket.cfg
+++ b/infra/config/global/cr-buildbucket.cfg
@@ -380,9 +380,9 @@
 builder_mixins {
   name: "xcode-10-caches"
   caches: {
-    # Cache for Xcode 10.0 beta 2 (build version 10L177m) needed for iOS builds.
-    name: "xcode_ios_10l177m"
-    path: "xcode_ios_10l177m.app"
+    # Cache for Xcode 10.0 beta 3 (build version 10L201y) needed for iOS builds.
+    name: "xcode_ios_10l201y"
+    path: "xcode_ios_10l201y.app"
   }
 }
 
diff --git a/ios/build/bots/chromium.fyi/ios12-beta-simulator.json b/ios/build/bots/chromium.fyi/ios12-beta-simulator.json
index c08256e..f016188 100644
--- a/ios/build/bots/chromium.fyi/ios12-beta-simulator.json
+++ b/ios/build/bots/chromium.fyi/ios12-beta-simulator.json
@@ -19,91 +19,91 @@
       "include": "common_tests.json",
       "device type": "iPhone X",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_cq_tests.json",
       "device type": "iPhone X",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_cq_tests.json",
       "device type": "iPhone 6 Plus",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_cq_tests.json",
       "device type": "iPhone 5s",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_cq_tests.json",
       "device type": "iPad Pro",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_tests.json",
       "device type": "iPhone X",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_tests.json",
       "device type": "iPhone 6 Plus",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_tests.json",
       "device type": "iPad Air",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "eg_tests.json",
       "device type": "iPhone 5s",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "screen_size_dependent_tests.json",
       "device type": "iPhone 6s Plus",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "screen_size_dependent_tests.json",
       "device type": "iPhone X",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "screen_size_dependent_tests.json",
       "device type": "iPhone 5s",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     },
     {
       "include": "screen_size_dependent_tests.json",
       "device type": "iPad Air 2",
       "os": "12.0",
-      "xcode build version": "10l177m",
+      "xcode build version": "10L201y",
       "host os": "Mac-10.13.5"
     }
   ]
diff --git a/ios/build/bots/chromium.fyi/ios12-sdk-device.json b/ios/build/bots/chromium.fyi/ios12-sdk-device.json
index fe425c8..5fdafba 100644
--- a/ios/build/bots/chromium.fyi/ios12-sdk-device.json
+++ b/ios/build/bots/chromium.fyi/ios12-sdk-device.json
@@ -4,7 +4,7 @@
     "Build is performed with gn+ninja.",
     "If modified, please change chromium.fyi/ios-device-goma-canary-clobber.json too."
   ],
-  "xcode build version": "10l177m",
+  "xcode build version": "10L201y",
   "gn_args": [
     "additional_target_cpus=[ \"arm64\" ]",
     "goma_dir=\"$(goma_dir)\"",
diff --git a/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json b/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json
index 5830d7d..665888a 100644
--- a/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json
+++ b/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json
@@ -4,7 +4,7 @@
     "on iPad, iPhone, @3x, and @2x on main and CQ ios12-beta-simulator.",
     "Note: Xcode 10.3 requires Mac OS 10.13.X or higher, hence 'host os'."
   ],
-  "xcode build version": "10l177m",
+  "xcode build version": "10L201y",
   "gn_args": [
     "additional_target_cpus=[\"x86\"]",
     "goma_dir=\"$(goma_dir)\"",
diff --git a/ios/build/bots/chromium.fyi/ios12-sdk-xcode-clang.json b/ios/build/bots/chromium.fyi/ios12-sdk-xcode-clang.json
index c0f9e02..66c94e9c 100644
--- a/ios/build/bots/chromium.fyi/ios12-sdk-xcode-clang.json
+++ b/ios/build/bots/chromium.fyi/ios12-sdk-xcode-clang.json
@@ -3,7 +3,7 @@
     "Tests for super-fat iOS 12.0.",
     "Build is performed with gn+ninja."
   ],
-  "xcode build version": "10l177m",
+  "xcode build version": "10L201y",
   "use xcode build version": true,
   "gn_args": [
     "additional_target_cpus=[\"x86\"]",
diff --git a/ios/build/bots/chromium.mac/ios12-sdk-simulator.json b/ios/build/bots/chromium.mac/ios12-sdk-simulator.json
index 8672ce3..f4c275f 100644
--- a/ios/build/bots/chromium.mac/ios12-sdk-simulator.json
+++ b/ios/build/bots/chromium.mac/ios12-sdk-simulator.json
@@ -4,7 +4,7 @@
     "on iPad, iPhone, @3x, and @2x on main and CQ ios12-beta-simulator.",
     "Note: Xcode 10.3 requires Mac OS 10.13.X or higher, hence 'host os'."
   ],
-  "xcode build version": "10l177m",
+  "xcode build version": "10L201y",
   "gn_args": [
     "additional_target_cpus=[\"x86\"]",
     "goma_dir=\"$(goma_dir)\"",
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS
index 631c02e..298ad23 100644
--- a/ios/chrome/browser/DEPS
+++ b/ios/chrome/browser/DEPS
@@ -3,6 +3,7 @@
   "+components/autofill/core/browser",
   "+components/autofill/core/common",
   "+components/autofill/ios/browser",
+  "+components/autofill/ios/form_util",
   "+components/bookmarks",
   "+components/browser_sync",
   "+components/browsing_data/core",
diff --git a/ios/chrome/browser/passwords/BUILD.gn b/ios/chrome/browser/passwords/BUILD.gn
index 7aaac65..d40cf0b7 100644
--- a/ios/chrome/browser/passwords/BUILD.gn
+++ b/ios/chrome/browser/passwords/BUILD.gn
@@ -190,7 +190,7 @@
     "resources/password_controller.js",
   ]
   js_modules = [
-    "//components/autofill/ios/fill/resources/form.js",
-    "//components/autofill/ios/fill/resources/fill.js",
+    "//components/autofill/ios/form_util/resources/form.js",
+    "//components/autofill/ios/form_util/resources/fill.js",
   ]
 }
diff --git a/ios/chrome/browser/reading_list/reading_list_web_state_observer.h b/ios/chrome/browser/reading_list/reading_list_web_state_observer.h
index 2fe8a005..1074cd2 100644
--- a/ios/chrome/browser/reading_list/reading_list_web_state_observer.h
+++ b/ios/chrome/browser/reading_list/reading_list_web_state_observer.h
@@ -80,7 +80,7 @@
   web::WebState* web_state_ = nullptr;
 
   ReadingListModel* reading_list_model_;
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::RepeatingTimer> timer_;
   GURL pending_url_;
   int try_number_;
   bool last_load_was_offline_;
diff --git a/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm b/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm
index 8dbde9b..41ca1ac 100644
--- a/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm
+++ b/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm
@@ -160,7 +160,7 @@
     return;
   }
   try_number_ = 0;
-  timer_.reset(new base::Timer(false, true));
+  timer_.reset(new base::RepeatingTimer());
   const base::TimeDelta kDelayUntilLoadingProgressIsChecked =
       base::TimeDelta::FromMilliseconds(1500);
   timer_->Start(
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm
index 8f980b2..d010ddc 100644
--- a/ios/chrome/browser/signin/authentication_service_unittest.mm
+++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -314,8 +314,8 @@
       .WillOnce(Invoke(
           sync_setup_service_mock_,
           &SyncSetupServiceMock::SyncSetupServiceHasFinishedInitialSetup));
-  EXPECT_CALL(*profile_sync_service_mock_, CanSyncStart())
-      .WillOnce(Return(false));
+  EXPECT_CALL(*profile_sync_service_mock_, GetDisableReasons())
+      .WillOnce(Return(syncer::SyncService::DISABLE_REASON_USER_CHOICE));
 
   CreateAuthenticationService();
 
diff --git a/ios/chrome/browser/ssl/BUILD.gn b/ios/chrome/browser/ssl/BUILD.gn
index 2f48086..fadf89e7 100644
--- a/ios/chrome/browser/ssl/BUILD.gn
+++ b/ios/chrome/browser/ssl/BUILD.gn
@@ -26,6 +26,7 @@
     ":feature_flags",
     "//base",
     "//base:i18n",
+    "//components/autofill/ios/form_util",
     "//components/captive_portal",
     "//components/security_interstitials/core",
     "//components/security_state/core",
diff --git a/ios/chrome/browser/ssl/insecure_input_tab_helper.h b/ios/chrome/browser/ssl/insecure_input_tab_helper.h
index 650c423..ce1ecf7 100644
--- a/ios/chrome/browser/ssl/insecure_input_tab_helper.h
+++ b/ios/chrome/browser/ssl/insecure_input_tab_helper.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/macros.h"
+#include "components/autofill/ios/form_util/form_activity_observer.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 #import "ios/web/public/web_state/web_state_user_data.h"
 
@@ -16,6 +17,7 @@
 // input events. Such events may change the page's Security Level.
 class InsecureInputTabHelper
     : public web::WebStateObserver,
+      public autofill::FormActivityObserver,
       public web::WebStateUserData<InsecureInputTabHelper> {
  public:
   ~InsecureInputTabHelper() override;
@@ -39,9 +41,10 @@
   friend class web::WebStateUserData<InsecureInputTabHelper>;
   explicit InsecureInputTabHelper(web::WebState* web_state);
 
+  // FormActivityObserver implementation.
+  void OnFormActivity(web::WebState* web_state,
+                      const web::FormActivityParams& params) override;
   // WebStateObserver implementation.
-  void FormActivityRegistered(web::WebState* web_state,
-                              const web::FormActivityParams& params) override;
   void WebStateDestroyed(web::WebState* web_state) override;
 
   // The WebState this instance is observing. Will be null after
diff --git a/ios/chrome/browser/ssl/insecure_input_tab_helper.mm b/ios/chrome/browser/ssl/insecure_input_tab_helper.mm
index b1d9e8ed..06d0a1f 100644
--- a/ios/chrome/browser/ssl/insecure_input_tab_helper.mm
+++ b/ios/chrome/browser/ssl/insecure_input_tab_helper.mm
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "base/logging.h"
+#include "components/autofill/ios/form_util/form_activity_tab_helper.h"
 #include "components/security_state/ios/ssl_status_input_event_data.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
@@ -115,9 +116,11 @@
 InsecureInputTabHelper::InsecureInputTabHelper(web::WebState* web_state)
     : web_state_(web_state) {
   web_state_->AddObserver(this);
+  autofill::FormActivityTabHelper::GetOrCreateForWebState(web_state)
+      ->AddObserver(this);
 }
 
-void InsecureInputTabHelper::FormActivityRegistered(
+void InsecureInputTabHelper::OnFormActivity(
     web::WebState* web_state,
     const web::FormActivityParams& params) {
   DCHECK_EQ(web_state_, web_state);
@@ -129,6 +132,8 @@
 
 void InsecureInputTabHelper::WebStateDestroyed(web::WebState* web_state) {
   DCHECK_EQ(web_state_, web_state);
+  autofill::FormActivityTabHelper::GetOrCreateForWebState(web_state)
+      ->RemoveObserver(this);
   web_state_->RemoveObserver(this);
   web_state_ = nullptr;
 }
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
index 7843380..1e239dd 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -73,7 +73,7 @@
   __weak id<AuthenticationFlowPerformerDelegate> _delegate;
   AlertCoordinator* _alertCoordinator;
   SettingsNavigationController* _navigationController;
-  std::unique_ptr<base::Timer> _watchdogTimer;
+  std::unique_ptr<base::OneShotTimer> _watchdogTimer;
 }
 
 - (id<AuthenticationFlowPerformerDelegate>)delegate {
@@ -116,11 +116,11 @@
                                      userInfo:nil];
     [strongSelf->_delegate didFailFetchManagedStatus:error];
   };
-  _watchdogTimer.reset(new base::Timer(false, false));
+  _watchdogTimer.reset(new base::OneShotTimer());
   _watchdogTimer->Start(
       FROM_HERE,
       base::TimeDelta::FromSeconds(kAuthenticationFlowTimeoutSeconds),
-      base::BindRepeating(onTimeout));
+      base::Bind(onTimeout));
 }
 
 - (BOOL)stopWatchdogTimer {
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
index 4e73e93b..0d5e50b 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -179,7 +179,7 @@
   // Signin pending state.
   AuthenticationState _activityIndicatorNextState;
   std::unique_ptr<base::ElapsedTimer> _pendingStateTimer;
-  std::unique_ptr<base::Timer> _leavingPendingStateTimer;
+  std::unique_ptr<base::OneShotTimer> _leavingPendingStateTimer;
 
   // Identity selected state.
   SigninConfirmationViewController* _confirmationVC;
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm
index 6652d826..de6ff7f 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm
@@ -60,7 +60,7 @@
 const CGFloat kSelectionDownScale = 0.1875;
 
 // The final scale of the selection bubble when the threshold is met.
-const CGFloat kSelectionAnimationScale = 23;
+const CGFloat kSelectionAnimationScale = 26;
 
 // The duration of the animations played when the threshold is met.
 const CGFloat kSelectionAnimationDuration = 0.5;
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index de3436f..0fb7907 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -124,7 +124,7 @@
 js_compile_bundle("chrome_bundle_all_frames") {
   closure_entry_point = "__crWeb.chromeBundleAllFrames"
   sources = [
-    "//components/autofill/ios/fill/resources/form.js",
+    "//components/autofill/ios/form_util/resources/form.js",
     "resources/accessibility.js",
     "resources/chrome_bundle_all_frames.js",
   ]
@@ -134,7 +134,7 @@
   closure_entry_point = "__crWeb.chromeBundleMainFrame"
   sources = [
     "//components/autofill/ios/browser/resources/autofill_controller.js",
-    "//components/autofill/ios/fill/resources/fill.js",
+    "//components/autofill/ios/form_util/resources/fill.js",
     "//ios/chrome/browser/passwords/resources/password_controller.js",
     "resources/chrome_bundle_main_frame.js",
     "resources/print.js",
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index 65ded46..8f96b72 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -380,8 +380,8 @@
   closure_entry_point = "__crWeb.webViewBundle"
   sources = [
     "//components/autofill/ios/browser/resources/autofill_controller.js",
-    "//components/autofill/ios/fill/resources/fill.js",
-    "//components/autofill/ios/fill/resources/form.js",
+    "//components/autofill/ios/form_util/resources/fill.js",
+    "//components/autofill/ios/form_util/resources/form.js",
     "//ios/chrome/browser/passwords/resources/password_controller.js",
     "resources/web_view_bundle.js",
   ]
diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc
index bb2e6766..5c0f5f4 100644
--- a/media/audio/audio_output_resampler.cc
+++ b/media/audio/audio_output_resampler.cc
@@ -262,8 +262,7 @@
       reinitialize_timer_(FROM_HERE,
                           close_delay_,
                           base::Bind(&AudioOutputResampler::Reinitialize,
-                                     base::Unretained(this)),
-                          false),
+                                     base::Unretained(this))),
       register_debug_recording_source_callback_(
           register_debug_recording_source_callback),
       weak_factory_(this) {
diff --git a/media/audio/audio_output_resampler.h b/media/audio/audio_output_resampler.h
index ac59d5b4..556d9e3 100644
--- a/media/audio/audio_output_resampler.h
+++ b/media/audio/audio_output_resampler.h
@@ -98,7 +98,7 @@
   // states by clearing the dispatcher if all proxies have been closed and none
   // have been created within |close_delay_|.  Without this, audio may be lost
   // to a fake stream indefinitely for transient errors.
-  base::Timer reinitialize_timer_;
+  base::RetainingOneShotTimer reinitialize_timer_;
 
   // Callback for registering a debug recording source.
   RegisterDebugRecordingSourceCallback
diff --git a/media/base/test_helpers.cc b/media/base/test_helpers.cc
index 36e6965..7e07d924 100644
--- a/media/base/test_helpers.cc
+++ b/media/base/test_helpers.cc
@@ -98,7 +98,7 @@
   }
 
   run_loop_.reset(new base::RunLoop());
-  base::Timer timer(false, false);
+  base::OneShotTimer timer;
   timer.Start(
       FROM_HERE, timeout_,
       base::Bind(&WaitableMessageLoopEvent::OnTimeout, base::Unretained(this)));
diff --git a/media/blink/video_frame_compositor.cc b/media/blink/video_frame_compositor.cc
index b71fbc5..99c2fb99 100644
--- a/media/blink/video_frame_compositor.cc
+++ b/media/blink/video_frame_compositor.cc
@@ -30,9 +30,7 @@
           FROM_HERE,
           base::TimeDelta::FromMilliseconds(kBackgroundRenderingTimeoutMs),
           base::Bind(&VideoFrameCompositor::BackgroundRender,
-                     base::Unretained(this)),
-          // Task is not repeating, CallRender() will reset the task as needed.
-          false),
+                     base::Unretained(this))),
       client_(nullptr),
       rendering_(false),
       rendered_last_frame_(false),
diff --git a/media/blink/video_frame_compositor.h b/media/blink/video_frame_compositor.h
index 108aff59..f0b49b5 100644
--- a/media/blink/video_frame_compositor.h
+++ b/media/blink/video_frame_compositor.h
@@ -190,7 +190,7 @@
   // Manages UpdateCurrentFrame() callbacks if |client_| has stopped sending
   // them for various reasons.  Runs on |task_runner_| and is reset
   // after each successful UpdateCurrentFrame() call.
-  base::Timer background_rendering_timer_;
+  base::RetainingOneShotTimer background_rendering_timer_;
 
   // These values are only set and read on the compositor thread.
   cc::VideoFrameProvider::Client* client_;
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc
index d76b06d..4849ff1a 100644
--- a/media/gpu/video_encode_accelerator_unittest.cc
+++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -2181,7 +2181,7 @@
  private:
   // The timer used to monitor the encoder doesn't return an output buffer in
   // a period of time.
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
 };
 
 VEANoInputClient::VEANoInputClient(ClientStateNotification<ClientState>* note)
@@ -2202,12 +2202,10 @@
                                                output_size);
 
   // Timer is used to make sure there is no output frame in 100ms.
-  timer_.reset(
-      new base::Timer(FROM_HERE, base::TimeDelta::FromMilliseconds(100),
-                      base::BindRepeating(&VEANoInputClient::SetState,
-                                          base::Unretained(this), CS_FINISHED),
-                      false));
-  timer_->Reset();
+  timer_.reset(new base::OneShotTimer());
+  timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(100),
+                base::Bind(&VEANoInputClient::SetState, base::Unretained(this),
+                           CS_FINISHED));
 }
 
 void VEANoInputClient::BitstreamBufferReady(int32_t bitstream_buffer_id,
diff --git a/net/base/network_throttle_manager_impl.cc b/net/base/network_throttle_manager_impl.cc
index cd62444..d5500fa 100644
--- a/net/base/network_throttle_manager_impl.cc
+++ b/net/base/network_throttle_manager_impl.cc
@@ -153,9 +153,7 @@
 NetworkThrottleManagerImpl::NetworkThrottleManagerImpl()
     : lifetime_median_estimate_(PercentileEstimator::kMedianPercentile,
                                 kInitialMedianInMs),
-      outstanding_recomputation_timer_(
-          std::make_unique<base::Timer>(false /* retain_user_task */,
-                                        false /* is_repeating */)),
+      outstanding_recomputation_timer_(std::make_unique<base::OneShotTimer>()),
       tick_clock_(base::DefaultTickClock::GetInstance()),
       weak_ptr_factory_(this) {}
 
@@ -191,8 +189,8 @@
     const base::TickClock* tick_clock) {
   tick_clock_ = tick_clock;
   DCHECK(!outstanding_recomputation_timer_->IsRunning());
-  outstanding_recomputation_timer_ = std::make_unique<base::Timer>(
-      false /* retain_user_task */, false /* is_repeating */, tick_clock_);
+  outstanding_recomputation_timer_ =
+      std::make_unique<base::OneShotTimer>(tick_clock_);
 }
 
 bool NetworkThrottleManagerImpl::ConditionallyTriggerTimerForTesting() {
diff --git a/net/base/network_throttle_manager_impl.h b/net/base/network_throttle_manager_impl.h
index cb1bfe4b..04960fd9 100644
--- a/net/base/network_throttle_manager_impl.h
+++ b/net/base/network_throttle_manager_impl.h
@@ -129,7 +129,7 @@
   // throttles are outstanding.  This guarantees that the class will
   // eventually detect aging out of outstanding throttles and unblock
   // throttles blocked on those outstanding throttles.
-  std::unique_ptr<base::Timer> outstanding_recomputation_timer_;
+  std::unique_ptr<base::OneShotTimer> outstanding_recomputation_timer_;
 
   // FIFO of OUTSTANDING throttles (ordered by time of entry into the
   // OUTSTANDING state).
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
index 9873ff3..45d1755 100644
--- a/net/dns/BUILD.gn
+++ b/net/dns/BUILD.gn
@@ -1,6 +1,6 @@
 # Copyright 2018 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.

+# found in the LICENSE file.
 
 import("//testing/libfuzzer/fuzzer_test.gni")
 import("//net/features.gni")
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc
index 62028b0..6c8c942 100644
--- a/net/dns/mdns_client_impl.cc
+++ b/net/dns/mdns_client_impl.cc
@@ -196,11 +196,10 @@
   delegate_->HandlePacket(response, bytes_read);
 }
 
-MDnsClientImpl::Core::Core(base::Clock* clock, base::Timer* timer)
+MDnsClientImpl::Core::Core(base::Clock* clock, base::OneShotTimer* timer)
     : clock_(clock),
       cleanup_timer_(timer),
-      connection_(new MDnsConnection(this)) {
-}
+      connection_(new MDnsConnection(this)) {}
 
 MDnsClientImpl::Core::~Core() = default;
 
@@ -418,10 +417,10 @@
 
 MDnsClientImpl::MDnsClientImpl()
     : clock_(base::DefaultClock::GetInstance()),
-      cleanup_timer_(new base::Timer(false, false)) {}
+      cleanup_timer_(new base::OneShotTimer()) {}
 
 MDnsClientImpl::MDnsClientImpl(base::Clock* clock,
-                               std::unique_ptr<base::Timer> timer)
+                               std::unique_ptr<base::OneShotTimer> timer)
     : clock_(clock), cleanup_timer_(std::move(timer)) {}
 
 MDnsClientImpl::~MDnsClientImpl() = default;
diff --git a/net/dns/mdns_client_impl.h b/net/dns/mdns_client_impl.h
index c35aaa8b..fad0d9b9 100644
--- a/net/dns/mdns_client_impl.h
+++ b/net/dns/mdns_client_impl.h
@@ -29,7 +29,7 @@
 
 namespace base {
 class Clock;
-class Timer;
+class OneShotTimer;
 }  // namespace base
 
 namespace net {
@@ -121,7 +121,7 @@
   // invalidate the core.
   class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate {
    public:
-    Core(base::Clock* clock, base::Timer* timer);
+    Core(base::Clock* clock, base::OneShotTimer* timer);
     ~Core() override;
 
     // Initialize the core. Returns true on success.
@@ -176,7 +176,7 @@
     MDnsCache cache_;
 
     base::Clock* clock_;
-    base::Timer* cleanup_timer_;
+    base::OneShotTimer* cleanup_timer_;
     base::Time scheduled_cleanup_;
 
     std::unique_ptr<MDnsConnection> connection_;
@@ -210,11 +210,11 @@
 
   // Test constructor, takes a mock clock and mock timer.
   MDnsClientImpl(base::Clock* clock,
-                 std::unique_ptr<base::Timer> cleanup_timer);
+                 std::unique_ptr<base::OneShotTimer> cleanup_timer);
 
   std::unique_ptr<Core> core_;
   base::Clock* clock_;
-  std::unique_ptr<base::Timer> cleanup_timer_;
+  std::unique_ptr<base::OneShotTimer> cleanup_timer_;
 
   DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl);
 };
diff --git a/net/dns/mdns_client_unittest.cc b/net/dns/mdns_client_unittest.cc
index 6256a45a..ef8a7e93 100644
--- a/net/dns/mdns_client_unittest.cc
+++ b/net/dns/mdns_client_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
 #include "base/timer/mock_timer.h"
+#include "net/base/completion_repeating_callback.h"
 #include "net/base/ip_address.h"
 #include "net/base/rand_callback.h"
 #include "net/base/test_completion_callback.h"
@@ -1158,9 +1159,9 @@
 
 TEST_F(MDnsConnectionTest, ReceiveSynchronous) {
   socket_ipv6_->SetResponsePacket(sample_packet_);
-  EXPECT_CALL(*socket_ipv4_, RecvFrom(_, _, _, _))
+  EXPECT_CALL(*socket_ipv4_, RecvFromInternal(_, _, _, _))
       .WillOnce(Return(ERR_IO_PENDING));
-  EXPECT_CALL(*socket_ipv6_, RecvFrom(_, _, _, _))
+  EXPECT_CALL(*socket_ipv6_, RecvFromInternal(_, _, _, _))
       .WillOnce(
           Invoke(socket_ipv6_, &MockMDnsDatagramServerSocket::HandleRecvNow))
       .WillOnce(Return(ERR_IO_PENDING));
@@ -1172,12 +1173,12 @@
 TEST_F(MDnsConnectionTest, ReceiveAsynchronous) {
   socket_ipv6_->SetResponsePacket(sample_packet_);
 
-  EXPECT_CALL(*socket_ipv4_, RecvFrom(_, _, _, _))
+  EXPECT_CALL(*socket_ipv4_, RecvFromInternal(_, _, _, _))
       .WillOnce(Return(ERR_IO_PENDING));
-  EXPECT_CALL(*socket_ipv6_, RecvFrom(_, _, _, _))
+  EXPECT_CALL(*socket_ipv6_, RecvFromInternal(_, _, _, _))
       .Times(2)
       .WillOnce(
-           Invoke(socket_ipv6_, &MockMDnsDatagramServerSocket::HandleRecvLater))
+          Invoke(socket_ipv6_, &MockMDnsDatagramServerSocket::HandleRecvLater))
       .WillOnce(Return(ERR_IO_PENDING));
 
   ASSERT_TRUE(InitConnection());
@@ -1188,11 +1189,11 @@
 }
 
 TEST_F(MDnsConnectionTest, Error) {
-  CompletionCallback callback;
+  CompletionRepeatingCallback callback;
 
-  EXPECT_CALL(*socket_ipv4_, RecvFrom(_, _, _, _))
+  EXPECT_CALL(*socket_ipv4_, RecvFromInternal(_, _, _, _))
       .WillOnce(Return(ERR_IO_PENDING));
-  EXPECT_CALL(*socket_ipv6_, RecvFrom(_, _, _, _))
+  EXPECT_CALL(*socket_ipv6_, RecvFromInternal(_, _, _, _))
       .WillOnce(DoAll(SaveArg<3>(&callback), Return(ERR_IO_PENDING)));
 
   ASSERT_TRUE(InitConnection());
@@ -1206,9 +1207,9 @@
  protected:
   void SetUp() override {
     MDnsConnectionTest::SetUp();
-    EXPECT_CALL(*socket_ipv4_, RecvFrom(_, _, _, _))
+    EXPECT_CALL(*socket_ipv4_, RecvFromInternal(_, _, _, _))
         .WillOnce(Return(ERR_IO_PENDING));
-    EXPECT_CALL(*socket_ipv6_, RecvFrom(_, _, _, _))
+    EXPECT_CALL(*socket_ipv6_, RecvFromInternal(_, _, _, _))
         .WillOnce(Return(ERR_IO_PENDING));
     EXPECT_TRUE(InitConnection());
   }
@@ -1224,13 +1225,11 @@
 }
 
 TEST_F(MDnsConnectionSendTest, SendError) {
-  CompletionCallback callback;
-
   EXPECT_CALL(*socket_ipv4_,
               SendToInternal(sample_packet_, "224.0.0.251:5353", _));
   EXPECT_CALL(*socket_ipv6_,
               SendToInternal(sample_packet_, "[ff02::fb]:5353", _))
-      .WillOnce(DoAll(SaveArg<2>(&callback), Return(ERR_SOCKET_NOT_CONNECTED)));
+      .WillOnce(Return(ERR_SOCKET_NOT_CONNECTED));
 
   connection_.Send(sample_buffer_, sample_packet_.size());
   EXPECT_CALL(delegate_, OnConnectionError(ERR_SOCKET_NOT_CONNECTED));
@@ -1244,7 +1243,7 @@
       .Times(2)
       .WillRepeatedly(Return(OK));
 
-  CompletionCallback callback;
+  CompletionRepeatingCallback callback;
   // Delay sending data. Only the first call should be made.
   EXPECT_CALL(*socket_ipv6_,
               SendToInternal(sample_packet_, "[ff02::fb]:5353", _))
@@ -1253,11 +1252,11 @@
   connection_.Send(sample_buffer_, sample_packet_.size());
   connection_.Send(sample_buffer_, sample_packet_.size());
 
-  // The second IPv6 packed is not sent yet.
+  // The second IPv6 packet is not sent yet.
   EXPECT_CALL(*socket_ipv4_,
               SendToInternal(sample_packet_, "224.0.0.251:5353", _))
       .Times(0);
-  // Expect call for the second IPv6 packed.
+  // Expect call for the second IPv6 packet.
   EXPECT_CALL(*socket_ipv6_,
               SendToInternal(sample_packet_, "[ff02::fb]:5353", _))
       .WillOnce(Return(OK));
diff --git a/net/dns/mock_mdns_socket_factory.cc b/net/dns/mock_mdns_socket_factory.cc
index 8c067b8b..809ed15 100644
--- a/net/dns/mock_mdns_socket_factory.cc
+++ b/net/dns/mock_mdns_socket_factory.cc
@@ -25,11 +25,20 @@
 
 MockMDnsDatagramServerSocket::~MockMDnsDatagramServerSocket() = default;
 
-int MockMDnsDatagramServerSocket::SendTo(IOBuffer* buf, int buf_len,
+int MockMDnsDatagramServerSocket::SendTo(IOBuffer* buf,
+                                         int buf_len,
                                          const IPEndPoint& address,
-                                         const CompletionCallback& callback) {
+                                         CompletionOnceCallback callback) {
   return SendToInternal(std::string(buf->data(), buf_len), address.ToString(),
-                        callback);
+                        base::AdaptCallbackForRepeating(std::move(callback)));
+}
+
+int MockMDnsDatagramServerSocket::RecvFrom(IOBuffer* buffer,
+                                           int size,
+                                           IPEndPoint* address,
+                                           CompletionOnceCallback callback) {
+  return RecvFromInternal(buffer, size, address,
+                          base::AdaptCallbackForRepeating(std::move(callback)));
 }
 
 int MockMDnsDatagramServerSocket::GetLocalAddress(IPEndPoint* address) const {
@@ -43,8 +52,10 @@
 }
 
 int MockMDnsDatagramServerSocket::HandleRecvNow(
-    IOBuffer* buffer, int size, IPEndPoint* address,
-    const CompletionCallback& callback) {
+    IOBuffer* buffer,
+    int size,
+    IPEndPoint* address,
+    CompletionRepeatingCallback callback) {
   int size_returned =
       std::min(response_packet_.size(), static_cast<size_t>(size));
   memcpy(buffer->data(), response_packet_.data(), size_returned);
@@ -52,11 +63,13 @@
 }
 
 int MockMDnsDatagramServerSocket::HandleRecvLater(
-    IOBuffer* buffer, int size, IPEndPoint* address,
-    const CompletionCallback& callback) {
+    IOBuffer* buffer,
+    int size,
+    IPEndPoint* address,
+    CompletionRepeatingCallback callback) {
   int rv = HandleRecvNow(buffer, size, address, callback);
   base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                base::Bind(callback, rv));
+                                                base::BindOnce(callback, rv));
   return ERR_IO_PENDING;
 }
 
@@ -81,10 +94,8 @@
           this,
           &MockMDnsSocketFactory::SendToInternal));
 
-  ON_CALL(*new_socket, RecvFrom(_, _, _, _))
-      .WillByDefault(Invoke(
-          this,
-          &MockMDnsSocketFactory::RecvFromInternal));
+  ON_CALL(*new_socket, RecvFromInternal(_, _, _, _))
+      .WillByDefault(Invoke(this, &MockMDnsSocketFactory::RecvFromInternal));
 
   sockets->push_back(std::move(new_socket));
 }
@@ -99,18 +110,19 @@
 }
 
 int MockMDnsSocketFactory::RecvFromInternal(
-    IOBuffer* buffer, int size,
+    IOBuffer* buffer,
+    int size,
     IPEndPoint* address,
-    const CompletionCallback& callback) {
-    recv_buffer_ = buffer;
-    recv_buffer_size_ = size;
-    recv_callback_ = callback;
-    return ERR_IO_PENDING;
+    CompletionRepeatingCallback callback) {
+  recv_buffer_ = buffer;
+  recv_buffer_size_ = size;
+  recv_callback_ = callback;
+  return ERR_IO_PENDING;
 }
 
-int MockMDnsSocketFactory::SendToInternal(
-    const std::string& packet, const std::string& address,
-    const CompletionCallback& callback) {
+int MockMDnsSocketFactory::SendToInternal(const std::string& packet,
+                                          const std::string& address,
+                                          CompletionOnceCallback callback) {
   OnSendTo(packet);
   return packet.size();
 }
diff --git a/net/dns/mock_mdns_socket_factory.h b/net/dns/mock_mdns_socket_factory.h
index 05224de..b48b3af 100644
--- a/net/dns/mock_mdns_socket_factory.h
+++ b/net/dns/mock_mdns_socket_factory.h
@@ -11,6 +11,8 @@
 #include <string>
 #include <vector>
 
+#include "net/base/completion_once_callback.h"
+#include "net/base/completion_repeating_callback.h"
 #include "net/dns/mdns_client_impl.h"
 #include "net/log/net_log_with_source.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -27,20 +29,28 @@
   // DatagramServerSocket implementation:
   MOCK_METHOD1(Listen, int(const IPEndPoint& address));
 
-  MOCK_METHOD1(ListenInternal, int(const std::string& address));
+  // GMock cannot handle move-only types like CompletionOnceCallback, so it
+  // needs to be converted into the copyable type CompletionRepeatingCallback.
+  int RecvFrom(IOBuffer* buffer,
+               int size,
+               IPEndPoint* address,
+               CompletionOnceCallback callback) override;
 
-  MOCK_METHOD4(RecvFrom, int(IOBuffer* buffer, int size,
-                             IPEndPoint* address,
-                             const CompletionCallback& callback));
+  MOCK_METHOD4(RecvFromInternal,
+               int(IOBuffer* buffer,
+                   int size,
+                   IPEndPoint* address,
+                   CompletionRepeatingCallback callback));
 
   int SendTo(IOBuffer* buf,
              int buf_len,
              const IPEndPoint& address,
-             const CompletionCallback& callback) override;
+             CompletionOnceCallback callback) override;
 
-  MOCK_METHOD3(SendToInternal, int(const std::string& packet,
-                                   const std::string address,
-                                   const CompletionCallback& callback));
+  MOCK_METHOD3(SendToInternal,
+               int(const std::string& packet,
+                   const std::string address,
+                   CompletionRepeatingCallback callback));
 
   MOCK_METHOD1(SetReceiveBufferSize, int(int32_t size));
   MOCK_METHOD1(SetSendBufferSize, int(int32_t size));
@@ -73,11 +83,15 @@
 
   void SetResponsePacket(const std::string& response_packet);
 
-  int HandleRecvNow(IOBuffer* buffer, int size, IPEndPoint* address,
-                    const CompletionCallback& callback);
+  int HandleRecvNow(IOBuffer* buffer,
+                    int size,
+                    IPEndPoint* address,
+                    CompletionRepeatingCallback callback);
 
-  int HandleRecvLater(IOBuffer* buffer, int size, IPEndPoint* address,
-                      const CompletionCallback& callback);
+  int HandleRecvLater(IOBuffer* buffer,
+                      int size,
+                      IPEndPoint* address,
+                      CompletionRepeatingCallback callback);
 
  private:
   std::string response_packet_;
@@ -97,14 +111,16 @@
   MOCK_METHOD1(OnSendTo, void(const std::string&));
 
  private:
-  int SendToInternal(const std::string& packet, const std::string& address,
-                     const CompletionCallback& callback);
+  int SendToInternal(const std::string& packet,
+                     const std::string& address,
+                     CompletionOnceCallback callback);
 
   // The latest receive callback is always saved, since the MDnsConnection
   // does not care which socket a packet is received on.
-  int RecvFromInternal(IOBuffer* buffer, int size,
+  int RecvFromInternal(IOBuffer* buffer,
+                       int size,
                        IPEndPoint* address,
-                       const CompletionCallback& callback);
+                       CompletionRepeatingCallback callback);
 
   void CreateSocket(
       AddressFamily address_family,
@@ -112,7 +128,7 @@
 
   scoped_refptr<IOBuffer> recv_buffer_;
   int recv_buffer_size_;
-  CompletionCallback recv_callback_;
+  CompletionRepeatingCallback recv_callback_;
 };
 
 }  // namespace net
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc
index 11c6a84..e033260 100644
--- a/net/http/bidirectional_stream.cc
+++ b/net/http/bidirectional_stream.cc
@@ -73,14 +73,14 @@
                           session,
                           send_request_headers_automatically,
                           delegate,
-                          std::make_unique<base::Timer>(false, false)) {}
+                          std::make_unique<base::OneShotTimer>()) {}
 
 BidirectionalStream::BidirectionalStream(
     std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
     HttpNetworkSession* session,
     bool send_request_headers_automatically,
     Delegate* delegate,
-    std::unique_ptr<base::Timer> timer)
+    std::unique_ptr<base::OneShotTimer> timer)
     : request_info_(std::move(request_info)),
       net_log_(NetLogWithSource::Make(session->net_log(),
                                       NetLogSourceType::BIDIRECTIONAL_STREAM)),
diff --git a/net/http/bidirectional_stream.h b/net/http/bidirectional_stream.h
index bf0f323..61fa08c 100644
--- a/net/http/bidirectional_stream.h
+++ b/net/http/bidirectional_stream.h
@@ -22,6 +22,10 @@
 #include "net/http/http_stream_request.h"
 #include "net/log/net_log_with_source.h"
 
+namespace base {
+class OneShotTimer;
+}  // namespace base
+
 namespace spdy {
 class SpdyHeaderBlock;
 }  // namespace spdy
@@ -120,7 +124,7 @@
       HttpNetworkSession* session,
       bool send_request_headers_automatically,
       Delegate* delegate,
-      std::unique_ptr<base::Timer> timer);
+      std::unique_ptr<base::OneShotTimer> timer);
 
   // Cancels |stream_request_| or |stream_impl_| if applicable.
   // |this| should not be destroyed during Delegate::OnHeadersSent or
@@ -240,7 +244,7 @@
 
   // Timer used to buffer data received in short time-spans and send a single
   // read completion notification.
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
   // HttpStreamRequest used to request a BidirectionalStreamImpl. This is NULL
   // if the request has been canceled or completed.
   std::unique_ptr<HttpStreamRequest> stream_request_;
diff --git a/net/http/bidirectional_stream_impl.h b/net/http/bidirectional_stream_impl.h
index 6b22fe2..2a3306f 100644
--- a/net/http/bidirectional_stream_impl.h
+++ b/net/http/bidirectional_stream_impl.h
@@ -18,7 +18,7 @@
 #include "net/traffic_annotation/network_traffic_annotation.h"
 
 namespace base {
-class Timer;
+class OneShotTimer;
 }  // namespace base
 
 namespace spdy {
@@ -108,7 +108,7 @@
                      const NetLogWithSource& net_log,
                      bool send_request_headers_automatically,
                      BidirectionalStreamImpl::Delegate* delegate,
-                     std::unique_ptr<base::Timer> timer,
+                     std::unique_ptr<base::OneShotTimer> timer,
                      const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
 
   // Sends request headers to server.
diff --git a/net/http/bidirectional_stream_unittest.cc b/net/http/bidirectional_stream_unittest.cc
index 7186dfb8..8e46dab 100644
--- a/net/http/bidirectional_stream_unittest.cc
+++ b/net/http/bidirectional_stream_unittest.cc
@@ -94,11 +94,11 @@
   TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
       : TestDelegateBase(read_buf,
                          read_buf_len,
-                         std::make_unique<base::Timer>(false, false)) {}
+                         std::make_unique<base::OneShotTimer>()) {}
 
   TestDelegateBase(IOBuffer* read_buf,
                    int read_buf_len,
-                   std::unique_ptr<base::Timer> timer)
+                   std::unique_ptr<base::OneShotTimer> timer)
       : read_buf_(read_buf),
         read_buf_len_(read_buf_len),
         timer_(std::move(timer)),
@@ -286,7 +286,7 @@
   std::unique_ptr<BidirectionalStream> stream_;
   scoped_refptr<IOBuffer> read_buf_;
   int read_buf_len_;
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
   std::string data_received_;
   std::unique_ptr<base::RunLoop> loop_;
   spdy::SpdyHeaderBlock response_headers_;
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index cd6128c..2dc46777 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -270,9 +270,6 @@
   bool has_pins = false;
   bool expect_ct = false;
   uint32_t expect_ct_report_uri_id = 0;
-  bool expect_staple = false;
-  bool expect_staple_include_subdomains = false;
-  uint32_t expect_staple_report_uri_id = 0;
 };
 
 using net::extras::PreloadDecoder;
@@ -325,24 +322,13 @@
         if (!reader->Read(4, &tmp.expect_ct_report_uri_id))
           return false;
       }
-
-      if (!reader->Next(&tmp.expect_staple))
-        return false;
-      tmp.expect_staple_include_subdomains = false;
-      if (tmp.expect_staple) {
-        if (!reader->Next(&tmp.expect_staple_include_subdomains))
-          return false;
-        if (!reader->Read(4, &tmp.expect_staple_report_uri_id))
-          return false;
-      }
     }
 
     tmp.hostname_offset = current_search_offset;
 
     if (current_search_offset == 0 ||
         search[current_search_offset - 1] == '.') {
-      *out_found = tmp.sts_include_subdomains || tmp.pkp_include_subdomains ||
-                   tmp.expect_staple_include_subdomains;
+      *out_found = tmp.sts_include_subdomains || tmp.pkp_include_subdomains;
 
       result_ = tmp;
 
@@ -405,85 +391,6 @@
   return found;
 }
 
-// Serializes an OCSPVerifyResult::ResponseStatus to a string enum, suitable for
-// the |response-status| field in an Expect-Staple report.
-std::string SerializeExpectStapleResponseStatus(
-    OCSPVerifyResult::ResponseStatus status) {
-  switch (status) {
-    case OCSPVerifyResult::NOT_CHECKED:
-      // Reports shouldn't be sent for this response status.
-      NOTREACHED();
-      return "NOT_CHECKED";
-    case OCSPVerifyResult::MISSING:
-      return "MISSING";
-    case OCSPVerifyResult::PROVIDED:
-      return "PROVIDED";
-    case OCSPVerifyResult::ERROR_RESPONSE:
-      return "ERROR_RESPONSE";
-    case OCSPVerifyResult::BAD_PRODUCED_AT:
-      return "BAD_PRODUCED_AT";
-    case OCSPVerifyResult::NO_MATCHING_RESPONSE:
-      return "NO_MATCHING_RESPONSE";
-    case OCSPVerifyResult::INVALID_DATE:
-      return "INVALID_DATE";
-    case OCSPVerifyResult::PARSE_RESPONSE_ERROR:
-      return "PARSE_RESPONSE_ERROR";
-    case OCSPVerifyResult::PARSE_RESPONSE_DATA_ERROR:
-      return "PARSE_RESPONSE_DATA_ERROR";
-  }
-  NOTREACHED();
-  return std::string();
-}
-
-// Serializes an OCSPRevocationStatus to a string enum, suitable for the
-// |cert-status| field in an Expect-Staple report.
-std::string SerializeExpectStapleRevocationStatus(
-    const OCSPRevocationStatus& status) {
-  switch (status) {
-    case OCSPRevocationStatus::GOOD:
-      return "GOOD";
-    case OCSPRevocationStatus::REVOKED:
-      return "REVOKED";
-    case OCSPRevocationStatus::UNKNOWN:
-      return "UNKNOWN";
-  }
-  return std::string();
-}
-
-bool SerializeExpectStapleReport(const HostPortPair& host_port_pair,
-                                 const SSLInfo& ssl_info,
-                                 base::StringPiece ocsp_response,
-                                 std::string* out_serialized_report) {
-  DCHECK(ssl_info.is_issued_by_known_root);
-  base::DictionaryValue report;
-  report.SetString("date-time", base::TimeToISO8601(base::Time::Now()));
-  report.SetString("hostname", host_port_pair.host());
-  report.SetInteger("port", host_port_pair.port());
-  report.SetString("response-status",
-                   SerializeExpectStapleResponseStatus(
-                       ssl_info.ocsp_result.response_status));
-
-  if (!ocsp_response.empty()) {
-    std::string encoded_ocsp_response;
-    base::Base64Encode(ocsp_response, &encoded_ocsp_response);
-    report.SetString("ocsp-response", encoded_ocsp_response);
-  }
-  if (ssl_info.ocsp_result.response_status == OCSPVerifyResult::PROVIDED) {
-    report.SetString("cert-status",
-                     SerializeExpectStapleRevocationStatus(
-                         ssl_info.ocsp_result.revocation_status));
-  }
-
-  report.Set("served-certificate-chain",
-             GetPEMEncodedChainAsList(ssl_info.unverified_cert.get()));
-  report.Set("validated-certificate-chain",
-             GetPEMEncodedChainAsList(ssl_info.cert.get()));
-
-  if (!base::JSONWriter::Write(report, out_serialized_report))
-    return false;
-  return true;
-}
-
 }  // namespace
 
 // static
@@ -498,7 +405,6 @@
 TransportSecurityState::TransportSecurityState()
     : enable_static_pins_(true),
       enable_static_expect_ct_(true),
-      enable_static_expect_staple_(true),
       enable_pkp_bypass_for_local_trust_anchors_(true),
       sent_hpkp_reports_cache_(kMaxReportCacheEntries),
       sent_expect_ct_reports_cache_(kMaxReportCacheEntries) {
@@ -554,44 +460,6 @@
   return pin_validity;
 }
 
-void TransportSecurityState::CheckExpectStaple(
-    const HostPortPair& host_port_pair,
-    const SSLInfo& ssl_info,
-    base::StringPiece ocsp_response) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  if (!enable_static_expect_staple_ || !report_sender_ ||
-      !ssl_info.is_issued_by_known_root) {
-    return;
-  }
-
-  // Determine if the host is on the Expect-Staple preload list. If the build is
-  // not timely (i.e. the preload list is not fresh), this will fail and return
-  // false.
-  ExpectStapleState expect_staple_state;
-  if (!GetStaticExpectStapleState(host_port_pair.host(), &expect_staple_state))
-    return;
-
-  // No report needed if OCSP details were not checked on this connection.
-  if (ssl_info.ocsp_result.response_status == OCSPVerifyResult::NOT_CHECKED)
-    return;
-
-  // No report needed if a stapled OCSP response was provided and it was valid.
-  if (ssl_info.ocsp_result.response_status == OCSPVerifyResult::PROVIDED &&
-      ssl_info.ocsp_result.revocation_status == OCSPRevocationStatus::GOOD) {
-    return;
-  }
-
-  std::string serialized_report;
-  if (!SerializeExpectStapleReport(host_port_pair, ssl_info, ocsp_response,
-                                   &serialized_report)) {
-    return;
-  }
-  report_sender_->Send(expect_staple_state.report_uri,
-                       "application/json; charset=utf-8", serialized_report,
-                       base::Callback<void()>(),
-                       base::Bind(RecordUMAForHPKPReportFailure));
-}
-
 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
   PKPState pkp_state;
   return GetPKPState(host, &pkp_state) && pkp_state.HasPublicKeyPins();
@@ -990,30 +858,6 @@
       served_certificate_chain, signed_certificate_timestamps);
 }
 
-bool TransportSecurityState::GetStaticExpectStapleState(
-    const std::string& host,
-    ExpectStapleState* expect_staple_state) const {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  if (!IsBuildTimely())
-    return false;
-
-  PreloadResult result;
-  if (!DecodeHSTSPreload(host, &result))
-    return false;
-
-  if (!enable_static_expect_staple_ || !result.expect_staple)
-    return false;
-
-  expect_staple_state->domain = host.substr(result.hostname_offset);
-  expect_staple_state->include_subdomains =
-      result.expect_staple_include_subdomains;
-  expect_staple_state->report_uri =
-      GURL(g_hsts_source
-               ->expect_staple_report_uris[result.expect_staple_report_uri_id]);
-  return true;
-}
-
 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
@@ -1571,11 +1415,6 @@
 TransportSecurityState::ExpectCTStateIterator::~ExpectCTStateIterator() =
     default;
 
-TransportSecurityState::ExpectStapleState::ExpectStapleState()
-    : include_subdomains(false) {}
-
-TransportSecurityState::ExpectStapleState::~ExpectStapleState() = default;
-
 bool TransportSecurityState::PKPState::CheckPublicKeyPins(
     const HashValueVector& hashes,
     std::string* failure_log) const {
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index 5f7873f..9c65b59 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -271,23 +271,6 @@
     std::map<std::string, ExpectCTState>::const_iterator end_;
   };
 
-  // An ExpectStapleState describes a site that expects valid OCSP information
-  // to be stapled to its certificate on every connection.
-  class NET_EXPORT ExpectStapleState {
-   public:
-    ExpectStapleState();
-    ~ExpectStapleState();
-
-    // The domain which matched during a search for this Expect-Staple entry
-    std::string domain;
-
-    // The URI reports are sent to if a valid OCSP response is not stapled
-    GURL report_uri;
-
-    // True if subdomains are subject to this policy
-    bool include_subdomains;
-  };
-
   // An interface for asynchronously sending HPKP violation reports.
   class NET_EXPORT ReportSenderInterface {
    public:
@@ -379,21 +362,6 @@
       std::string* failure_log);
   bool HasPublicKeyPins(const std::string& host);
 
-  // Sends an Expect-Staple report containing the raw |ocsp_response| for
-  // |host_port_pair| if the following conditions are true:
-  // 1. Sending Expect-Staple reports is enabled (via
-  //    |enable_static_expect_staple_|)
-  // 2. A report sender was provided via SetReportSender().
-  // 3. The build is timely (i.e. the preload list is fresh).
-  // 4. The given host is present on the Expect-Staple preload list.
-  // 5. |ssl_info| indicates the connection did not provide an OCSP response
-  //    indicating a revocation status of GOOD.
-  // 6. The certificate chain in |ssl_info| chains to a known root. Reports
-  //    for OCSP responses behind MITM proxies are not useful to site owners.
-  void CheckExpectStaple(const HostPortPair& host_port_pair,
-                         const SSLInfo& ssl_info,
-                         base::StringPiece ocsp_response);
-
   // Returns CT_REQUIREMENTS_NOT_MET if a connection violates CT policy
   // requirements: that is, if a connection to |host|, using the validated
   // certificate |validated_certificate_chain|, is expected to be accompanied
@@ -680,14 +648,6 @@
   bool GetStaticExpectCTState(const std::string& host,
                               ExpectCTState* expect_ct_result) const;
 
-  // Returns true and updates |*expect_staple_result| iff there is a static
-  // (built-in) state for |host| with expect_staple=true, or if |host| is a
-  // subdomain of another domain with expect_staple=true and
-  // include_subdomains_for_expect_staple=true.
-  bool GetStaticExpectStapleState(
-      const std::string& host,
-      ExpectStapleState* expect_staple_result) const;
-
   void MaybeNotifyExpectCTFailed(
       const HostPortPair& host_port_pair,
       const GURL& report_uri,
@@ -716,9 +676,6 @@
   // True if static expect-CT state should be used.
   bool enable_static_expect_ct_;
 
-  // True if static expect-staple state should be used.
-  bool enable_static_expect_staple_;
-
   // True if public key pinning bypass is enabled for local trust anchors.
   bool enable_pkp_bypass_for_local_trust_anchors_;
 
diff --git a/net/http/transport_security_state_source.h b/net/http/transport_security_state_source.h
index 2c065db..9a6f5ef 100644
--- a/net/http/transport_security_state_source.h
+++ b/net/http/transport_security_state_source.h
@@ -28,7 +28,6 @@
   size_t preloaded_bits;
   size_t root_position;
   const char* const* expect_ct_report_uris;
-  const char* const* expect_staple_report_uris;
   const Pinset* pinsets;
   size_t pinsets_count;
 };
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index 7102e3e..8836bb6 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -27,8 +27,7 @@
 //       preload list. This field is used for list maintenance.
 //         - test: test domains.
 //         - google: Google-owned sites.
-//         - custom: entries without includeSubdomains or with HPKP, Expect-CT,
-//           or Expect-Staple.
+//         - custom: entries without includeSubdomains or with HPKP/Expect-CT.
 //         - bulk-legacy: bulk entries preloaded before Chrome 50.
 //         - bulk-18-weeks: bulk entries with max-age >= 18 weeks (Chrome 50-63).
 //         - bulk-1-year: bulk entries with max-age >= 1 year (after Chrome 63).
@@ -51,12 +50,6 @@
 //       URI to which reports should be sent when valid Certificate
 //       Transparency information is not present.
 //
-//   expect_staple: (optional boolean) true if the site expects responses to
-//       contain stapled OCSP responses.
-//   expect_staple_report_uri: (optional string) if expect_staple is true, the
-//       URI to which expect_staple reports should be sent.
-//   include_subdomains_for_expect_staple: (optional boolean) whether subdomains
-//       of |name| are also covered for |expect_staple|.
 
 {
   "pinsets": [
@@ -266,16 +259,6 @@
       "expect_ct": true,
       "expect_ct_report_uri": "https://clients3.google.com/ct_upload"
     },
-    {
-      "name": "preloaded-expect-staple.badssl.com", "policy": "test",
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://report.badssl.com/expect-staple"
-    },
-    {
-      "name": "preloaded-expect-staple-include-subdomains.badssl.com", "policy": "test",
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://report.badssl.com/expect-staple"
-    },
 
     // gTLDs and eTLDs are welcome to preload if they are interested.
     { "name": "android", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
@@ -923,9 +906,7 @@
     },
     {
       "name": "www.dropbox.com", "policy": "custom",
-      "mode": "force-https", "include_subdomains": true, "pins": "dropbox",
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://log.getdropbox.com/log/ocsp_expect_staple"
+      "mode": "force-https", "include_subdomains": true, "pins": "dropbox"
     },
     {
       "name": "dropboxstatic.com", "policy": "custom",
@@ -53522,7 +53503,7 @@
     { "name": "trinity.fr.eu.org", "policy": "custom", "mode": "force-https", "include_subdomains": true },
     { "name": "mysa.is", "policy": "custom", "mode": "force-https", "include_subdomains": true },
     { "name": "vensl.org", "policy": "custom", "mode": "force-https", "include_subdomains": true },
-    // Expect-CT/Expect-Staple
+    // Expect-CT
     {
       "name": "crt.sh", "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
@@ -53530,11 +53511,6 @@
       "expect_ct_report_uri": "https://clients3.google.com/ct_upload"
     },
     {
-      "name": "caddyserver.com", "policy": "custom",
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://reporting.caddyserver.com/expect-staple"
-    },
-    {
       "name": "crypto.is", "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
       "expect_ct": true,
@@ -53543,16 +53519,12 @@
     {
       "name": "ritter.vg", "policy": "custom",
       "expect_ct": true,
-      "expect_ct_report_uri": "https://clients3.google.com/ct_upload",
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://asac.casa/expectstaple.jsp"
+      "expect_ct_report_uri": "https://clients3.google.com/ct_upload"
     },
     {
       "name": "scotthelme.co.uk",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://scotthelme.report-uri.com/r/d/staple/reportOnly",
       "expect_ct": true,
       "expect_ct_report_uri": "https://scotthelme.report-uri.com/r/d/ct/reportOnly"
     },
@@ -53560,31 +53532,23 @@
       "name": "matteomarescotti.it",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://matteomarescotti.report-uri.com/r/d/staple/reportOnly",
       "expect_ct": true,
       "expect_ct_report_uri": "https://matteomarescotti.report-uri.com/r/d/ct/reportOnly"
     },
     {
       "name": "alessandroz.pro",
       "policy": "custom",
-      "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://azreport.report-uri.com/r/d/staple/reportOnly"
+      "mode": "force-https", "include_subdomains": true
     },
     {
       "name": "minecraftforum.de",
       "policy": "custom",
-      "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://minecraft.report-uri.com/r/d/staple/reportOnly"
+      "mode": "force-https", "include_subdomains": true
     },
     {
       "name": "tobiassachs.de",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://tobiassachs.report-uri.com/r/d/staple/reportOnly",
       "expect_ct": true,
       "expect_ct_report_uri": "https://tobiassachs.report-uri.com/r/d/ct/reportOnly"
     },
@@ -53592,8 +53556,6 @@
       "name": "gc-mc.de",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://tobiassachs.report-uri.com/r/d/staple/reportOnly",
       "expect_ct": true,
       "expect_ct_report_uri": "https://tobiassachs.report-uri.com/r/d/ct/reportOnly"
     },
@@ -53601,8 +53563,6 @@
       "name": "knightsblog.de",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://tobiassachs.report-uri.com/r/d/staple/reportOnly",
       "expect_ct": true,
       "expect_ct_report_uri": "https://tobiassachs.report-uri.com/r/d/ct/reportOnly"
     },
@@ -53610,33 +53570,25 @@
       "name": "cloudflare.com",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://report-uri.cloudflare.com/expect-staple",
       "expect_ct": true,
       "expect_ct_report_uri": "https://report-uri.cloudflare.com/expect-ct"
     },
     {
       "name": "weeblrpress.com",
       "policy": "custom",
-      "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://weeblr.report-uri.com/r/d/staple/reportOnly"
+      "mode": "force-https", "include_subdomains": true
     },
     {
       "name": "0.me.uk",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true, "pins": "ncsccs",
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://log.ncsccs.com/report/expectstaple",
       "expect_ct": true,
       "expect_ct_report_uri": "https://log.ncsccs.com/report/expectct"
     },
     {
       "name": "photistic.org",
       "policy": "custom",
-      "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://photistic.report-uri.com/r/d/staple/reportOnly"
+      "mode": "force-https", "include_subdomains": true
     },
     {
       "name": "www.tumblr.com",
@@ -53648,8 +53600,6 @@
       "name": "history.pe",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://history.report-uri.com/r/d/staple/reportOnly",
       "expect_ct": true,
       "expect_ct_report_uri": "https://history.report-uri.com/r/d/ct/reportOnly"
     },
@@ -53657,17 +53607,13 @@
       "name": "sirburton.com",
       "policy": "custom",
       "mode": "force-https", "include_subdomains": true, "pins": "ncsccs",
-      "expect_staple": true, "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://log.ncsccs.com/report/expectstaple",
       "expect_ct": true,
       "expect_ct_report_uri": "https://log.ncsccs.com/report/expectct"
     },
     {
       "name": "cortis-consulting.ch",
       "policy": "custom",
-      "mode": "force-https", "include_subdomains": true,
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://cortisconsultingch.report-uri.com/r/d/staple/reportOnly"
+      "mode": "force-https", "include_subdomains": true
     },
     // END OF MANUAL CUSTOM ENTRIES
 
diff --git a/net/http/transport_security_state_static.template b/net/http/transport_security_state_static.template
index 6ec865c5..fc5d6673 100644
--- a/net/http/transport_security_state_static.template
+++ b/net/http/transport_security_state_static.template
@@ -17,8 +17,6 @@
 
 static const char* const kExpectCTReportURIs[] = [[EXPECT_CT_REPORT_URIS]];
 
-static const char* const kExpectStapleReportURIs[] = [[EXPECT_STAPLE_REPORT_URIS]];
-
 // kNoRejectedPublicKeys is a placeholder for when no public keys are rejected.
 static const char* const kNoRejectedPublicKeys[] = {
     nullptr,
@@ -47,7 +45,6 @@
   kPreloadedHSTSBits,
   kHSTSRootPosition,
   kExpectCTReportURIs,
-  kExpectStapleReportURIs,
   kPinsets,
   arraysize(kPinsets)
 };
diff --git a/net/http/transport_security_state_static_fuzzer.cc b/net/http/transport_security_state_static_fuzzer.cc
index b7b9b5f7d..af5d1ef 100644
--- a/net/http/transport_security_state_static_fuzzer.cc
+++ b/net/http/transport_security_state_static_fuzzer.cc
@@ -24,13 +24,6 @@
     TransportSecurityState::ExpectCTState result;
     return state->GetStaticExpectCTState(input, &result);
   }
-
-  bool FuzzStaticExpectStapleState(TransportSecurityState* state,
-                                   const std::string& input) {
-    state->enable_static_expect_staple_ = true;
-    TransportSecurityState::ExpectStapleState result;
-    return state->GetStaticExpectStapleState(input, &result);
-  }
 };
 
 }  // namespace net
@@ -43,7 +36,6 @@
 
   helper.FuzzStaticDomainState(&state, input);
   helper.FuzzStaticExpectCTState(&state, input);
-  helper.FuzzStaticExpectStapleState(&state, input);
 
   return 0;
 }
diff --git a/net/http/transport_security_state_static_unittest.template b/net/http/transport_security_state_static_unittest.template
index 633ec78b..6978227c 100644
--- a/net/http/transport_security_state_static_unittest.template
+++ b/net/http/transport_security_state_static_unittest.template
@@ -14,8 +14,6 @@
 
 static const char* const kExpectCTReportURIs[] = [[EXPECT_CT_REPORT_URIS]];
 
-static const char* const kExpectStapleReportURIs[] = [[EXPECT_STAPLE_REPORT_URIS]];
-
 static const char* const kNoRejectedPublicKeys[] = {
     NULL,
 };
@@ -38,7 +36,6 @@
   kPreloadedHSTSBits,
   kHSTSRootPosition,
   kExpectCTReportURIs,
-  kExpectStapleReportURIs,
   kPinsets,
   arraysize(kPinsets)
 };
diff --git a/net/http/transport_security_state_static_unittest2.json b/net/http/transport_security_state_static_unittest2.json
index 9188200..6b5bd8d 100644
--- a/net/http/transport_security_state_static_unittest2.json
+++ b/net/http/transport_security_state_static_unittest2.json
@@ -40,12 +40,6 @@
       "expect_ct": true,
       "expect_ct_report_uri": "https://report.example.com/ct-upload"
     }, {
-      "name": "expect-staple.example.com",
-      "policy": "test",
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://report.example.com/staple-upload",
-      "include_subdomains_for_expect_staple": false
-    }, {
       "name": "mix.example.com",
       "policy": "test",
       "mode": "force-https",
@@ -53,10 +47,7 @@
       "pins": "test2",
       "include_subdomains_for_pinning": true,
       "expect_ct": true,
-      "expect_ct_report_uri": "https://report.example.com/ct-upload-alt",
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://report.example.com/staple-upload-alt",
-      "include_subdomains_for_expect_staple": true
+      "expect_ct_report_uri": "https://report.example.com/ct-upload-alt"
     }
   ]
 }
diff --git a/net/http/transport_security_state_static_unittest3.json b/net/http/transport_security_state_static_unittest3.json
index b4bbfdb9..f798181 100644
--- a/net/http/transport_security_state_static_unittest3.json
+++ b/net/http/transport_security_state_static_unittest3.json
@@ -29,9 +29,7 @@
       "name": "example.com",
       "policy": "test",
       "mode": "force-https",
-      "include_subdomains": true,
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://report.example.com/staple-upload"
+      "include_subdomains": true
     }, {
       "name": "hpkp.example.com",
       "policy": "test",
@@ -47,10 +45,7 @@
       "name": "badssl.com",
       "policy": "test",
       "include_subdomains": true,
-      "pins": "test1",
-      "expect_staple": true,
-      "expect_staple_report_uri": "https://report.badssl.com/staple-upload",
-      "include_subdomains_for_expect_staple": true
+      "pins": "test1"
     }, {
       "name": "mix.badssl.com",
       "policy": "test",
@@ -59,10 +54,7 @@
       "pins": "test2",
       "include_subdomains_for_pinning": true,
       "expect_ct": true,
-      "expect_ct_report_uri": "https://report.example.com/ct-upload",
-      "expect_staple": true,
-      "include_subdomains_for_expect_staple": true,
-      "expect_staple_report_uri": "https://report.badssl.com/staple-upload"
+      "expect_ct_report_uri": "https://report.example.com/ct-upload"
     }, {
       // Keep this a simple entry in the context of TrieWriter::IsSimpleEntry().
       "name": "simple-entry.example.com",
diff --git a/net/http/transport_security_state_static_unittest_default.json b/net/http/transport_security_state_static_unittest_default.json
index ff6181e9..47b552fc 100644
--- a/net/http/transport_security_state_static_unittest_default.json
+++ b/net/http/transport_security_state_static_unittest_default.json
@@ -42,10 +42,6 @@
 
     { "name": "hsts-hpkp-preloaded.test", "policy": "test", "mode": "force-https", "pins": "withoutRejectedPins" },
 
-    { "name": "expect-ct.preloaded.test", "policy": "test", "expect_ct": true, "expect_ct_report_uri": "http://report-uri.preloaded.test/expect-ct" },
-
-    { "name": "expect-staple.preloaded.test", "policy": "test", "expect_staple": true, "expect_staple_report_uri": "http://report-uri.preloaded.test/expect-staple" },
-    { "name": "include-subdomains-expect-staple.preloaded.test", "policy": "test", "expect_staple": true, "include_subdomains_for_expect_staple": true, "expect_staple_report_uri": "http://report-uri.preloaded.test/expect-staple" }
+    { "name": "expect-ct.preloaded.test", "policy": "test", "expect_ct": true, "expect_ct_report_uri": "http://report-uri.preloaded.test/expect-ct" }
   ]
 }
-
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 508e9fc..a0c43edd 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -65,11 +65,6 @@
 const char kExpectCTStaticHostname[] = "expect-ct.preloaded.test";
 const char kExpectCTStaticReportURI[] =
     "http://report-uri.preloaded.test/expect-ct";
-const char kExpectStapleStaticHostname[] = "expect-staple.preloaded.test";
-const char kExpectStapleStaticReportURI[] =
-    "http://report-uri.preloaded.test/expect-staple";
-const char kExpectStapleStaticIncludeSubdomainsHostname[] =
-    "include-subdomains-expect-staple.preloaded.test";
 
 const char* const kGoodPath[] = {
     "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
@@ -291,110 +286,6 @@
       validated_certificate_chain, report_validated_certificate_chain));
 }
 
-// Checks the following hold for |report| such that it is a valid Expect-Staple
-// report:
-// 1. |report| is a JSON dictionary.
-// 2. The "hostname" and "port" fields match |host_port_pair|.
-// 3. The "response-status" field matches |response_status|
-// 4. The "ocsp-response" field is a base64-encoded verson of |ocsp_response|,
-//    and is not present when |ocsp_response| is empty.
-// 5. The "cert-status" field matches |cert_status|, and is not present when
-//    |cert_status| is empty.
-// 6. The "validated-chain" and "serverd-chain" fields match those in
-//    |ssl_info|.
-void CheckSerializedExpectStapleReport(const std::string& report,
-                                       const HostPortPair& host_port_pair,
-                                       const SSLInfo& ssl_info,
-                                       const std::string& ocsp_response,
-                                       const std::string& response_status,
-                                       const std::string& cert_status) {
-  std::unique_ptr<base::Value> value(base::JSONReader::Read(report));
-  ASSERT_TRUE(value);
-  ASSERT_TRUE(value->is_dict());
-
-  base::DictionaryValue* report_dict;
-  ASSERT_TRUE(value->GetAsDictionary(&report_dict));
-
-  std::string report_hostname;
-  EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname));
-  EXPECT_EQ(host_port_pair.host(), report_hostname);
-
-  int report_port;
-  EXPECT_TRUE(report_dict->GetInteger("port", &report_port));
-  EXPECT_EQ(host_port_pair.port(), report_port);
-
-  std::string report_response_status;
-  EXPECT_TRUE(
-      report_dict->GetString("response-status", &report_response_status));
-  EXPECT_EQ(response_status, report_response_status);
-
-  std::string report_ocsp_response;
-  bool has_ocsp_response =
-      report_dict->GetString("ocsp-response", &report_ocsp_response);
-
-  if (!ocsp_response.empty()) {
-    EXPECT_TRUE(has_ocsp_response);
-    std::string decoded_ocsp_response;
-    EXPECT_TRUE(
-        base::Base64Decode(report_ocsp_response, &decoded_ocsp_response));
-    EXPECT_EQ(ocsp_response, decoded_ocsp_response);
-  } else {
-    EXPECT_FALSE(has_ocsp_response);
-  }
-
-  std::string report_cert_status;
-  bool has_cert_status =
-      report_dict->GetString("cert-status", &report_cert_status);
-  if (!cert_status.empty()) {
-    EXPECT_TRUE(has_cert_status);
-    EXPECT_EQ(cert_status, report_cert_status);
-  } else {
-    EXPECT_FALSE(has_cert_status);
-  }
-
-  base::ListValue* report_served_certificate_chain;
-  bool has_served_chain = report_dict->GetList(
-      "served-certificate-chain", &report_served_certificate_chain);
-
-  base::ListValue* report_validated_certificate_chain;
-  bool has_validated_chain = report_dict->GetList(
-      "validated-certificate-chain", &report_validated_certificate_chain);
-
-  EXPECT_TRUE(has_served_chain);
-  EXPECT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
-      ssl_info.unverified_cert, report_served_certificate_chain));
-
-  EXPECT_TRUE(has_validated_chain);
-  EXPECT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
-      ssl_info.cert, report_validated_certificate_chain));
-}
-
-// Set up |state| for ExpectStaple, call CheckExpectStaple(), and verify the
-// serialized report caught by |reporter|.
-void CheckExpectStapleReport(TransportSecurityState* state,
-                             MockCertificateReportSender* reporter,
-                             const SSLInfo& ssl_info,
-                             const std::string& ocsp_response,
-                             const std::string& response_status,
-                             const std::string& cert_status) {
-  // Expect-Staple is preload list based, so we use the baked-in test hostname
-  // from the list ("preloaded-expect-staple.badssl.com").
-  HostPortPair host_port(kExpectStapleStaticHostname, 443);
-  state->SetReportSender(reporter);
-  state->CheckExpectStaple(host_port, ssl_info, ocsp_response);
-  if (!ssl_info.is_issued_by_known_root) {
-    EXPECT_EQ(GURL(), reporter->latest_report_uri());
-    EXPECT_EQ(std::string(), reporter->latest_report());
-    return;
-  }
-  EXPECT_EQ(GURL(kExpectStapleStaticReportURI), reporter->latest_report_uri());
-  EXPECT_EQ("application/json; charset=utf-8", reporter->latest_content_type());
-  std::string serialized_report = reporter->latest_report();
-  EXPECT_NO_FATAL_FAILURE(CheckSerializedExpectStapleReport(
-      serialized_report, host_port, ssl_info, ocsp_response, response_status,
-      cert_status));
-}
-
 bool operator==(const TransportSecurityState::STSState& lhs,
                 const TransportSecurityState::STSState& rhs) {
   return lhs.last_observed == rhs.last_observed && lhs.expiry == rhs.expiry &&
@@ -440,11 +331,6 @@
     state->enable_static_expect_ct_ = true;
   }
 
-  static void SetEnableStaticExpectStaple(TransportSecurityState* state,
-                                          bool enabled) {
-    state->enable_static_expect_staple_ = enabled;
-  }
-
   static HashValueVector GetSampleSPKIHashes() {
     HashValueVector spki_hashes;
     HashValue hash(HASH_VALUE_SHA256);
@@ -472,12 +358,6 @@
                         TransportSecurityState::ExpectCTState* result) {
     return state->GetStaticExpectCTState(host, result);
   }
-
-  bool GetExpectStapleState(TransportSecurityState* state,
-                            const std::string& host,
-                            TransportSecurityState::ExpectStapleState* result) {
-    return state->GetStaticExpectStapleState(host, result);
-  }
 };
 
 TEST_F(TransportSecurityStateTest, DomainNameOddities) {
@@ -1061,39 +941,6 @@
       GetExpectCTState(&state, "hsts-preloaded.test", &expect_ct_state));
 }
 
-// Tests that static (preloaded) expect staple state is read correctly.
-TEST_F(TransportSecurityStateTest, PreloadedExpectStaple) {
-  TransportSecurityState state;
-  TransportSecurityState::ExpectStapleState expect_staple_state;
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, false);
-  EXPECT_FALSE(GetExpectStapleState(&state, kExpectStapleStaticHostname,
-                                    &expect_staple_state));
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
-  EXPECT_TRUE(GetExpectStapleState(&state, kExpectStapleStaticHostname,
-                                   &expect_staple_state));
-  EXPECT_EQ(kExpectStapleStaticHostname, expect_staple_state.domain);
-  EXPECT_EQ(GURL(kExpectStapleStaticReportURI), expect_staple_state.report_uri);
-  EXPECT_FALSE(expect_staple_state.include_subdomains);
-  EXPECT_FALSE(GetExpectStapleState(&state, "hsts-preloaded.test",
-                                    &expect_staple_state));
-  std::string subdomain = "subdomain.";
-  subdomain += kExpectStapleStaticHostname;
-  EXPECT_FALSE(GetExpectStapleState(&state, subdomain, &expect_staple_state));
-}
-
-TEST_F(TransportSecurityStateTest, PreloadedExpectStapleIncludeSubdomains) {
-  TransportSecurityState state;
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
-  TransportSecurityState::ExpectStapleState expect_staple_state;
-  std::string subdomain = "subdomain.";
-  subdomain += kExpectStapleStaticIncludeSubdomainsHostname;
-  EXPECT_TRUE(GetExpectStapleState(&state, subdomain, &expect_staple_state));
-  EXPECT_EQ(kExpectStapleStaticIncludeSubdomainsHostname,
-            expect_staple_state.domain);
-  EXPECT_TRUE(expect_staple_state.include_subdomains);
-  EXPECT_EQ(GURL(kExpectStapleStaticReportURI), expect_staple_state.report_uri);
-}
-
 // Tests that the Expect CT reporter is not notified for invalid or absent
 // header values.
 TEST_F(TransportSecurityStateTest, InvalidExpectCTHeader) {
@@ -1388,14 +1235,13 @@
 // Simple test for the HSTS preload process. The trie (generated from
 // transport_security_state_static_unittest1.json) contains 1 entry. Test that
 // the lookup methods can find the entry and correctly decode the different
-// preloaded states (HSTS, HPKP, Expect-CT, and Expect-Staple).
+// preloaded states (HSTS, HPKP, and Expect-CT).
 TEST_F(TransportSecurityStateTest, DecodePreloadedSingle) {
   SetTransportSecurityStateSourceForTesting(&test1::kHSTSSource);
 
   TransportSecurityState state;
   TransportSecurityStateTest::EnableStaticPins(&state);
   TransportSecurityStateTest::EnableStaticExpectCT(&state);
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
 
   TransportSecurityState::STSState sts_state;
   TransportSecurityState::PKPState pkp_state;
@@ -1413,28 +1259,23 @@
 
   TransportSecurityState::ExpectCTState ct_state;
   EXPECT_FALSE(GetExpectCTState(&state, "hsts.example.com", &ct_state));
-
-  TransportSecurityState::ExpectStapleState staple_state;
-  EXPECT_FALSE(GetExpectStapleState(&state, "hsts.example.com", &staple_state));
 }
 
 // More advanced test for the HSTS preload process where the trie (generated
 // from transport_security_state_static_unittest2.json) contains multiple
 // entries with a common prefix. Test that the lookup methods can find all
 // entries and correctly decode the different preloaded states (HSTS, HPKP,
-// Expect-CT, and Expect-Staple) for each entry.
+// and Expect-CT) for each entry.
 TEST_F(TransportSecurityStateTest, DecodePreloadedMultiplePrefix) {
   SetTransportSecurityStateSourceForTesting(&test2::kHSTSSource);
 
   TransportSecurityState state;
   TransportSecurityStateTest::EnableStaticPins(&state);
   TransportSecurityStateTest::EnableStaticExpectCT(&state);
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
 
   TransportSecurityState::STSState sts_state;
   TransportSecurityState::PKPState pkp_state;
   TransportSecurityState::ExpectCTState ct_state;
-  TransportSecurityState::ExpectStapleState staple_state;
 
   EXPECT_TRUE(
       GetStaticDomainState(&state, "hsts.example.com", &sts_state, &pkp_state));
@@ -1443,12 +1284,10 @@
             sts_state.upgrade_mode);
   EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
   EXPECT_FALSE(GetExpectCTState(&state, "hsts.example.com", &ct_state));
-  EXPECT_FALSE(GetExpectStapleState(&state, "hsts.example.com", &staple_state));
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
   EXPECT_TRUE(
       GetStaticDomainState(&state, "hpkp.example.com", &sts_state, &pkp_state));
   EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
@@ -1459,41 +1298,20 @@
   EXPECT_EQ(pkp_state.spki_hashes[0], GetSampleSPKIHash(0x1));
   EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
   EXPECT_FALSE(GetExpectCTState(&state, "hpkp.example.com", &ct_state));
-  EXPECT_FALSE(GetExpectStapleState(&state, "hpkp.example.com", &staple_state));
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
   EXPECT_TRUE(GetStaticDomainState(&state, "expect-ct.example.com", &sts_state,
                                    &pkp_state));
   EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
   EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
   EXPECT_TRUE(GetExpectCTState(&state, "expect-ct.example.com", &ct_state));
   EXPECT_EQ(GURL("https://report.example.com/ct-upload"), ct_state.report_uri);
-  EXPECT_FALSE(
-      GetExpectStapleState(&state, "expect-ct.example.com", &staple_state));
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
-  EXPECT_TRUE(GetStaticDomainState(&state, "expect-staple.example.com",
-                                   &sts_state, &pkp_state));
-  EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
-  EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
-  EXPECT_FALSE(
-      GetExpectCTState(&state, "expect-staple.example.com", &ct_state));
-  EXPECT_TRUE(
-      GetExpectStapleState(&state, "expect-staple.example.com", &staple_state));
-  EXPECT_FALSE(staple_state.include_subdomains);
-  EXPECT_EQ(GURL("https://report.example.com/staple-upload"),
-            staple_state.report_uri);
-
-  sts_state = TransportSecurityState::STSState();
-  pkp_state = TransportSecurityState::PKPState();
-  ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
   EXPECT_TRUE(
       GetStaticDomainState(&state, "mix.example.com", &sts_state, &pkp_state));
   EXPECT_FALSE(sts_state.include_subdomains);
@@ -1508,10 +1326,6 @@
   EXPECT_TRUE(GetExpectCTState(&state, "mix.example.com", &ct_state));
   EXPECT_EQ(GURL("https://report.example.com/ct-upload-alt"),
             ct_state.report_uri);
-  EXPECT_TRUE(GetExpectStapleState(&state, "mix.example.com", &staple_state));
-  EXPECT_TRUE(staple_state.include_subdomains);
-  EXPECT_EQ(GURL("https://report.example.com/staple-upload-alt"),
-            staple_state.report_uri);
 }
 
 // More advanced test for the HSTS preload process where the trie (generated
@@ -1520,19 +1334,17 @@
 // preloaded state while others share no prefix. This results in a trie with
 // several different internal structures. Test that the lookup methods can find
 // all entries and correctly decode the different preloaded states (HSTS, HPKP,
-// Expect-CT, and Expect-Staple) for each entry.
+// and Expect-CT) for each entry.
 TEST_F(TransportSecurityStateTest, DecodePreloadedMultipleMix) {
   SetTransportSecurityStateSourceForTesting(&test3::kHSTSSource);
 
   TransportSecurityState state;
   TransportSecurityStateTest::EnableStaticPins(&state);
   TransportSecurityStateTest::EnableStaticExpectCT(&state);
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
 
   TransportSecurityState::STSState sts_state;
   TransportSecurityState::PKPState pkp_state;
   TransportSecurityState::ExpectCTState ct_state;
-  TransportSecurityState::ExpectStapleState staple_state;
 
   EXPECT_TRUE(
       GetStaticDomainState(&state, "example.com", &sts_state, &pkp_state));
@@ -1542,15 +1354,10 @@
   EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
   EXPECT_FALSE(GetExpectCTState(&state, "example.com", &ct_state));
   EXPECT_EQ(GURL(), ct_state.report_uri);
-  EXPECT_TRUE(GetExpectStapleState(&state, "example.com", &staple_state));
-  EXPECT_FALSE(staple_state.include_subdomains);
-  EXPECT_EQ(GURL("https://report.example.com/staple-upload"),
-            staple_state.report_uri);
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
   EXPECT_TRUE(
       GetStaticDomainState(&state, "hpkp.example.com", &sts_state, &pkp_state));
   EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
@@ -1562,14 +1369,10 @@
   EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
   EXPECT_FALSE(GetExpectCTState(&state, "hpkp.example.com", &ct_state));
   EXPECT_EQ(GURL(), ct_state.report_uri);
-  EXPECT_FALSE(GetExpectStapleState(&state, "hpkp.example.com", &staple_state));
-  EXPECT_FALSE(staple_state.include_subdomains);
-  EXPECT_EQ(GURL(), staple_state.report_uri);
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
   EXPECT_TRUE(
       GetStaticDomainState(&state, "example.org", &sts_state, &pkp_state));
   EXPECT_FALSE(sts_state.include_subdomains);
@@ -1578,14 +1381,10 @@
   EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
   EXPECT_TRUE(GetExpectCTState(&state, "example.org", &ct_state));
   EXPECT_EQ(GURL("https://report.example.org/ct-upload"), ct_state.report_uri);
-  EXPECT_FALSE(GetExpectStapleState(&state, "example.org", &staple_state));
-  EXPECT_FALSE(staple_state.include_subdomains);
-  EXPECT_EQ(GURL(), staple_state.report_uri);
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
   EXPECT_TRUE(
       GetStaticDomainState(&state, "badssl.com", &sts_state, &pkp_state));
   EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
@@ -1597,15 +1396,10 @@
   EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
   EXPECT_FALSE(GetExpectCTState(&state, "badssl.com", &ct_state));
   EXPECT_EQ(GURL(), ct_state.report_uri);
-  EXPECT_TRUE(GetExpectStapleState(&state, "badssl.com", &staple_state));
-  EXPECT_TRUE(staple_state.include_subdomains);
-  EXPECT_EQ(GURL("https://report.badssl.com/staple-upload"),
-            staple_state.report_uri);
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
   EXPECT_TRUE(
       GetStaticDomainState(&state, "mix.badssl.com", &sts_state, &pkp_state));
   EXPECT_FALSE(sts_state.include_subdomains);
@@ -1619,15 +1413,10 @@
   EXPECT_EQ(pkp_state.bad_spki_hashes[0], GetSampleSPKIHash(0x1));
   EXPECT_TRUE(GetExpectCTState(&state, "mix.badssl.com", &ct_state));
   EXPECT_EQ(GURL("https://report.example.com/ct-upload"), ct_state.report_uri);
-  EXPECT_TRUE(GetExpectStapleState(&state, "mix.badssl.com", &staple_state));
-  EXPECT_TRUE(staple_state.include_subdomains);
-  EXPECT_EQ(GURL("https://report.badssl.com/staple-upload"),
-            staple_state.report_uri);
 
   sts_state = TransportSecurityState::STSState();
   pkp_state = TransportSecurityState::PKPState();
   ct_state = TransportSecurityState::ExpectCTState();
-  staple_state = TransportSecurityState::ExpectStapleState();
 
   // This should be a simple entry in the context of
   // TrieWriter::IsSimpleEntry().
@@ -1638,199 +1427,6 @@
             sts_state.upgrade_mode);
   EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
   EXPECT_FALSE(GetExpectCTState(&state, "simple-entry.example.com", &ct_state));
-  EXPECT_FALSE(
-      GetExpectStapleState(&state, "simple-entry.example.com", &staple_state));
-}
-
-static const struct ExpectStapleErrorResponseData {
-  OCSPVerifyResult::ResponseStatus response_status;
-  std::string response_status_string;
-} kExpectStapleReportData[] = {
-    {OCSPVerifyResult::MISSING, "MISSING"},
-    {OCSPVerifyResult::ERROR_RESPONSE, "ERROR_RESPONSE"},
-    {OCSPVerifyResult::BAD_PRODUCED_AT, "BAD_PRODUCED_AT"},
-    {OCSPVerifyResult::NO_MATCHING_RESPONSE, "NO_MATCHING_RESPONSE"},
-    {OCSPVerifyResult::INVALID_DATE, "INVALID_DATE"},
-    {OCSPVerifyResult::PARSE_RESPONSE_ERROR, "PARSE_RESPONSE_ERROR"},
-    {OCSPVerifyResult::PARSE_RESPONSE_DATA_ERROR, "PARSE_RESPONSE_DATA_ERROR"},
-};
-
-class ExpectStapleErrorResponseTest
-    : public TransportSecurityStateTest,
-      public testing::WithParamInterface<ExpectStapleErrorResponseData> {};
-
-// For every |response_status| indicating an OCSP response was provided, but had
-// some sort of parsing/validation error, test that the ExpectStaple report is
-// serialized correctly.
-TEST_P(ExpectStapleErrorResponseTest, CheckResponseStatusSerialization) {
-  TransportSecurityState state;
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
-  MockCertificateReportSender reporter;
-  ExpectStapleErrorResponseData test = GetParam();
-
-  std::string ocsp_response;
-  if (test.response_status != OCSPVerifyResult::MISSING)
-    ocsp_response = "dummy_response";
-
-  // Two dummy certs to use as the server-sent and validated chains. The
-  // contents don't matter.
-  scoped_refptr<X509Certificate> cert1 =
-      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-  ASSERT_TRUE(cert1);
-  scoped_refptr<X509Certificate> cert2 =
-      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
-  ASSERT_TRUE(cert2);
-
-  SSLInfo ssl_info;
-  ssl_info.cert = cert1;
-  ssl_info.unverified_cert = cert2;
-  ssl_info.ocsp_result.response_status = test.response_status;
-
-  // Reports should only be sent when |is_issued_by_known_root| is true.
-  ssl_info.is_issued_by_known_root = true;
-  ASSERT_NO_FATAL_FAILURE(
-      CheckExpectStapleReport(&state, &reporter, ssl_info, ocsp_response,
-                              test.response_status_string, std::string()));
-  reporter.Clear();
-
-  // No report should be sent.
-  ssl_info.is_issued_by_known_root = false;
-  ASSERT_NO_FATAL_FAILURE(
-      CheckExpectStapleReport(&state, &reporter, ssl_info, ocsp_response,
-                              test.response_status_string, std::string()));
-}
-
-INSTANTIATE_TEST_CASE_P(ExpectStaple,
-                        ExpectStapleErrorResponseTest,
-                        testing::ValuesIn(kExpectStapleReportData));
-
-static const struct ExpectStapleErrorCertStatusData {
-  OCSPRevocationStatus revocation_status;
-  std::string cert_status_string;
-} kExpectStapleErrorCertStatusData[] = {
-    {OCSPRevocationStatus::REVOKED, "REVOKED"},
-    {OCSPRevocationStatus::UNKNOWN, "UNKNOWN"},
-};
-
-class ExpectStapleErrorCertStatusTest
-    : public TransportSecurityStateTest,
-      public testing::WithParamInterface<ExpectStapleErrorCertStatusData> {};
-
-// Test that |revocation_status| is serialized into the |cert-status| field of
-// the Expect-Staple report whenever |response_status| is PROVIDED and
-// |revocation_status| != GOOD.
-TEST_P(ExpectStapleErrorCertStatusTest, CheckCertStatusSerialization) {
-  TransportSecurityState state;
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
-  MockCertificateReportSender reporter;
-  ExpectStapleErrorCertStatusData test = GetParam();
-  std::string ocsp_response = "dummy_response";
-
-  // Two dummy certs to use as the server-sent and validated chains. The
-  // contents don't matter.
-  scoped_refptr<X509Certificate> cert1 =
-      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-  ASSERT_TRUE(cert1);
-  scoped_refptr<X509Certificate> cert2 =
-      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
-  ASSERT_TRUE(cert2);
-
-  SSLInfo ssl_info;
-  ssl_info.cert = cert1;
-  ssl_info.unverified_cert = cert2;
-  // |response_status| must be set to PROVIDED for |revocation_status| to have
-  // meaning.
-  ssl_info.ocsp_result.response_status = OCSPVerifyResult::PROVIDED;
-  ssl_info.ocsp_result.revocation_status = test.revocation_status;
-
-  // Reports should only be sent when |is_issued_by_known_root| is true.
-  ssl_info.is_issued_by_known_root = true;
-  ASSERT_NO_FATAL_FAILURE(CheckExpectStapleReport(&state, &reporter, ssl_info,
-                                                  ocsp_response, "PROVIDED",
-                                                  test.cert_status_string));
-  reporter.Clear();
-
-  ssl_info.is_issued_by_known_root = false;
-  ASSERT_NO_FATAL_FAILURE(CheckExpectStapleReport(&state, &reporter, ssl_info,
-                                                  ocsp_response, "PROVIDED",
-                                                  test.cert_status_string));
-};
-
-INSTANTIATE_TEST_CASE_P(ExpectStaple,
-                        ExpectStapleErrorCertStatusTest,
-                        testing::ValuesIn(kExpectStapleErrorCertStatusData));
-
-TEST_F(TransportSecurityStateTest, ExpectStapleDoesNotReportValidStaple) {
-  TransportSecurityState state;
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
-  MockCertificateReportSender reporter;
-  state.SetReportSender(&reporter);
-
-  // Baked-in preloaded Expect-Staple test hosts.
-  HostPortPair host_port(kExpectStapleStaticHostname, 443);
-
-  // Two dummy certs to use as the server-sent and validated chains. The
-  // contents don't matter.
-  scoped_refptr<X509Certificate> cert1 =
-      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-  ASSERT_TRUE(cert1);
-  scoped_refptr<X509Certificate> cert2 =
-      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
-  ASSERT_TRUE(cert2);
-
-  SSLInfo ssl_info;
-  ssl_info.cert = cert1;
-  ssl_info.unverified_cert = cert2;
-  ssl_info.ocsp_result.response_status = OCSPVerifyResult::PROVIDED;
-  ssl_info.ocsp_result.revocation_status = OCSPRevocationStatus::GOOD;
-
-  std::string ocsp_response = "dummy response";
-
-  ssl_info.is_issued_by_known_root = true;
-  state.CheckExpectStaple(host_port, ssl_info, ocsp_response);
-  EXPECT_EQ(GURL(), reporter.latest_report_uri());
-  EXPECT_TRUE(reporter.latest_report().empty());
-
-  ssl_info.is_issued_by_known_root = false;
-  state.CheckExpectStaple(host_port, ssl_info, ocsp_response);
-  EXPECT_EQ(GURL(), reporter.latest_report_uri());
-  EXPECT_TRUE(reporter.latest_report().empty());
-}
-
-TEST_F(TransportSecurityStateTest, ExpectStapleRequiresPreload) {
-  TransportSecurityState state;
-  TransportSecurityStateTest::SetEnableStaticExpectStaple(&state, true);
-  MockCertificateReportSender reporter;
-  state.SetReportSender(&reporter);
-
-  HostPortPair host_port("not-preloaded.host.example", 443);
-
-  // Two dummy certs to use as the server-sent and validated chains. The
-  // contents don't matter.
-  scoped_refptr<X509Certificate> cert1 =
-      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-  ASSERT_TRUE(cert1);
-  scoped_refptr<X509Certificate> cert2 =
-      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
-  ASSERT_TRUE(cert2);
-
-  SSLInfo ssl_info;
-  ssl_info.cert = cert1;
-  ssl_info.unverified_cert = cert2;
-  ssl_info.ocsp_result.response_status = OCSPVerifyResult::MISSING;
-
-  // Empty response
-  std::string ocsp_response;
-
-  ssl_info.is_issued_by_known_root = true;
-  state.CheckExpectStaple(host_port, ssl_info, ocsp_response);
-  EXPECT_EQ(GURL(), reporter.latest_report_uri());
-  EXPECT_TRUE(reporter.latest_report().empty());
-
-  ssl_info.is_issued_by_known_root = false;
-  state.CheckExpectStaple(host_port, ssl_info, ocsp_response);
-  EXPECT_EQ(GURL(), reporter.latest_report_uri());
-  EXPECT_TRUE(reporter.latest_report().empty());
 }
 
 // Tests that TransportSecurityState always consults the RequireCTDelegate,
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl.cc b/net/quic/chromium/bidirectional_stream_quic_impl.cc
index e151b4a..fd1ef48d 100644
--- a/net/quic/chromium/bidirectional_stream_quic_impl.cc
+++ b/net/quic/chromium/bidirectional_stream_quic_impl.cc
@@ -69,7 +69,7 @@
     const NetLogWithSource& net_log,
     bool send_request_headers_automatically,
     BidirectionalStreamImpl::Delegate* delegate,
-    std::unique_ptr<base::Timer> timer,
+    std::unique_ptr<base::OneShotTimer> timer,
     const NetworkTrafficAnnotationTag& traffic_annotation) {
   ScopedBoolSaver saver(&may_invoke_callbacks_, false);
   DCHECK(!stream_);
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl.h b/net/quic/chromium/bidirectional_stream_quic_impl.h
index 1c49ab9..148513e 100644
--- a/net/quic/chromium/bidirectional_stream_quic_impl.h
+++ b/net/quic/chromium/bidirectional_stream_quic_impl.h
@@ -20,7 +20,7 @@
 #include "net/third_party/spdy/core/spdy_header_block.h"
 
 namespace base {
-class Timer;
+class OneShotTimer;
 }  // namespace base
 
 namespace net {
@@ -41,7 +41,7 @@
              const NetLogWithSource& net_log,
              bool send_request_headers_automatically,
              BidirectionalStreamImpl::Delegate* delegate,
-             std::unique_ptr<base::Timer> timer,
+             std::unique_ptr<base::OneShotTimer> timer,
              const NetworkTrafficAnnotationTag& traffic_annotation) override;
   void SendRequestHeaders() override;
   int ReadData(IOBuffer* buffer, int buffer_len) override;
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
index 4843bf9..d943b472 100644
--- a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
@@ -79,11 +79,11 @@
   TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
       : TestDelegateBase(read_buf,
                          read_buf_len,
-                         std::make_unique<base::Timer>(false, false)) {}
+                         std::make_unique<base::OneShotTimer>()) {}
 
   TestDelegateBase(IOBuffer* read_buf,
                    int read_buf_len,
-                   std::unique_ptr<base::Timer> timer)
+                   std::unique_ptr<base::OneShotTimer> timer)
       : read_buf_(read_buf),
         read_buf_len_(read_buf_len),
         timer_(std::move(timer)),
@@ -293,7 +293,7 @@
   std::unique_ptr<BidirectionalStreamQuicImpl> stream_;
   scoped_refptr<IOBuffer> read_buf_;
   int read_buf_len_;
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
   std::string data_received_;
   std::unique_ptr<base::RunLoop> loop_;
   spdy::SpdyHeaderBlock response_headers_;
diff --git a/net/socket/datagram_server_socket.h b/net/socket/datagram_server_socket.h
index fd791a74..9793af3 100644
--- a/net/socket/datagram_server_socket.h
+++ b/net/socket/datagram_server_socket.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/net_export.h"
 #include "net/socket/datagram_socket.h"
 #include "net/socket/diff_serv_code_point.h"
@@ -40,7 +40,7 @@
   virtual int RecvFrom(IOBuffer* buf,
                        int buf_len,
                        IPEndPoint* address,
-                       const CompletionCallback& callback) = 0;
+                       CompletionOnceCallback callback) = 0;
 
   // Send to a socket with a particular destination.
   // |buf| is the buffer to send.
@@ -53,7 +53,7 @@
   virtual int SendTo(IOBuffer* buf,
                      int buf_len,
                      const IPEndPoint& address,
-                     const CompletionCallback& callback) = 0;
+                     CompletionOnceCallback callback) = 0;
 
   // Set the receive buffer size (in bytes) for the socket.
   // Returns a net error code.
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index c9dde2cc..c933a63e 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1237,15 +1237,6 @@
     bool ok = GetSSLInfo(&ssl_info);
     DCHECK(ok);
 
-    const uint8_t* ocsp_response_raw;
-    size_t ocsp_response_len;
-    SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
-    base::StringPiece ocsp_response(
-        reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len);
-
-    transport_security_state_->CheckExpectStaple(host_and_port_, ssl_info,
-                                                 ocsp_response);
-
     // See how feasible enforcing RSA key usage would be. See
     // https://crbug.com/795089.
     RSAKeyUsage rsa_key_usage = CheckRSAKeyUsage(
diff --git a/net/socket/udp_server_socket.cc b/net/socket/udp_server_socket.cc
index d2f18f4f..aae96ac 100644
--- a/net/socket/udp_server_socket.cc
+++ b/net/socket/udp_server_socket.cc
@@ -4,6 +4,8 @@
 
 #include "net/socket/udp_server_socket.h"
 
+#include <utility>
+
 #include "net/base/net_errors.h"
 
 namespace net {
@@ -43,15 +45,15 @@
 int UDPServerSocket::RecvFrom(IOBuffer* buf,
                               int buf_len,
                               IPEndPoint* address,
-                              const CompletionCallback& callback) {
-  return socket_.RecvFrom(buf, buf_len, address, callback);
+                              CompletionOnceCallback callback) {
+  return socket_.RecvFrom(buf, buf_len, address, std::move(callback));
 }
 
 int UDPServerSocket::SendTo(IOBuffer* buf,
                             int buf_len,
                             const IPEndPoint& address,
-                            const CompletionCallback& callback) {
-  return socket_.SendTo(buf, buf_len, address, callback);
+                            CompletionOnceCallback callback) {
+  return socket_.SendTo(buf, buf_len, address, std::move(callback));
 }
 
 int UDPServerSocket::SetReceiveBufferSize(int32_t size) {
diff --git a/net/socket/udp_server_socket.h b/net/socket/udp_server_socket.h
index 0d2dc7e3..a2e9a178 100644
--- a/net/socket/udp_server_socket.h
+++ b/net/socket/udp_server_socket.h
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
 #include "net/base/net_export.h"
 #include "net/socket/datagram_server_socket.h"
 #include "net/socket/udp_socket.h"
@@ -31,11 +31,11 @@
   int RecvFrom(IOBuffer* buf,
                int buf_len,
                IPEndPoint* address,
-               const CompletionCallback& callback) override;
+               CompletionOnceCallback callback) override;
   int SendTo(IOBuffer* buf,
              int buf_len,
              const IPEndPoint& address,
-             const CompletionCallback& callback) override;
+             CompletionOnceCallback callback) override;
   int SetReceiveBufferSize(int32_t size) override;
   int SetSendBufferSize(int32_t size) override;
   int SetDoNotFragment() override;
diff --git a/net/spdy/bidirectional_stream_spdy_impl.cc b/net/spdy/bidirectional_stream_spdy_impl.cc
index 55181874..ddabbdb 100644
--- a/net/spdy/bidirectional_stream_spdy_impl.cc
+++ b/net/spdy/bidirectional_stream_spdy_impl.cc
@@ -58,7 +58,7 @@
     const NetLogWithSource& net_log,
     bool /*send_request_headers_automatically*/,
     BidirectionalStreamImpl::Delegate* delegate,
-    std::unique_ptr<base::Timer> timer,
+    std::unique_ptr<base::OneShotTimer> timer,
     const NetworkTrafficAnnotationTag& traffic_annotation) {
   DCHECK(!stream_);
   DCHECK(timer);
diff --git a/net/spdy/bidirectional_stream_spdy_impl.h b/net/spdy/bidirectional_stream_spdy_impl.h
index 89586ae..7266e66 100644
--- a/net/spdy/bidirectional_stream_spdy_impl.h
+++ b/net/spdy/bidirectional_stream_spdy_impl.h
@@ -24,7 +24,7 @@
 #include "net/spdy/spdy_stream.h"
 
 namespace base {
-class Timer;
+class OneShotTimer;
 }  // namespace base
 
 namespace spdy {
@@ -50,7 +50,7 @@
              const NetLogWithSource& net_log,
              bool send_request_headers_automatically,
              BidirectionalStreamImpl::Delegate* delegate,
-             std::unique_ptr<base::Timer> timer,
+             std::unique_ptr<base::OneShotTimer> timer,
              const NetworkTrafficAnnotationTag& traffic_annotation) override;
   void SendRequestHeaders() override;
   int ReadData(IOBuffer* buf, int buf_len) override;
@@ -90,7 +90,7 @@
   const base::WeakPtr<SpdySession> spdy_session_;
   const BidirectionalStreamRequestInfo* request_info_;
   BidirectionalStreamImpl::Delegate* delegate_;
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
   SpdyStreamRequest stream_request_;
   base::WeakPtr<SpdyStream> stream_;
   const NetLogSource source_dependency_;
diff --git a/net/spdy/bidirectional_stream_spdy_impl_unittest.cc b/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
index 27f3aa4..96d89d9 100644
--- a/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
+++ b/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
@@ -138,7 +138,7 @@
              const NetLogWithSource& net_log) {
     stream_->Start(request, net_log,
                    /*send_request_headers_automatically=*/false, this,
-                   std::make_unique<base::Timer>(false, false),
+                   std::make_unique<base::OneShotTimer>(),
                    TRAFFIC_ANNOTATION_FOR_TESTS);
     not_expect_callback_ = false;
   }
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender.cc b/net/third_party/quic/core/congestion_control/bbr_sender.cc
index 7bd00e7..6d0f3ce0 100644
--- a/net/third_party/quic/core/congestion_control/bbr_sender.cc
+++ b/net/third_party/quic/core/congestion_control/bbr_sender.cc
@@ -24,8 +24,12 @@
 // Does not inflate the pacing rate.
 const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
 
-// The gain used for the slow start, equal to 2/ln(2).
+// The gain used for the STARTUP, equal to 2/ln(2).
 const float kDefaultHighGain = 2.885f;
+// The newly derived gain for STARTUP, equal to 4 * ln(2)
+const float kDerivedHighGain = 2.773f;
+// The newly derived CWND gain for STARTUP, 2.
+const float kDerivedHighCWNDGain = 2.773f;
 // The gain used in STARTUP after loss has been detected.
 // 1.5 is enough to allow for 25% exogenous loss and still observe a 25% growth
 // in measured bandwidth.
@@ -98,6 +102,7 @@
       max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
       min_congestion_window_(kDefaultMinimumCongestionWindow),
       high_gain_(kDefaultHighGain),
+      high_cwnd_gain_(kDefaultHighGain),
       drain_gain_(1.f / kDefaultHighGain),
       pacing_rate_(QuicBandwidth::Zero()),
       pacing_gain_(1),
@@ -123,6 +128,7 @@
       slower_startup_(false),
       rate_based_startup_(false),
       initial_conservation_in_startup_(CONSERVATION),
+      enable_ack_aggregation_during_startup_(false),
       drain_to_target_(false),
       probe_rtt_based_on_bdp_(false),
       probe_rtt_skipped_if_similar_rtt_(false),
@@ -252,6 +258,28 @@
     QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_less_probe_rtt, 3, 3);
     probe_rtt_disabled_if_app_limited_ = true;
   }
+  if (GetQuicReloadableFlag(quic_bbr_slower_startup3) &&
+      config.HasClientRequestedIndependentOption(kBBQ1, perspective)) {
+    QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slower_startup3, 1, 4);
+    set_high_gain(kDerivedHighGain);
+    set_high_cwnd_gain(kDerivedHighGain);
+    set_drain_gain(1.f / kDerivedHighGain);
+  }
+  if (GetQuicReloadableFlag(quic_bbr_slower_startup3) &&
+      config.HasClientRequestedIndependentOption(kBBQ2, perspective)) {
+    QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slower_startup3, 2, 4);
+    set_high_cwnd_gain(kDerivedHighCWNDGain);
+  }
+  if (GetQuicReloadableFlag(quic_bbr_slower_startup3) &&
+      config.HasClientRequestedIndependentOption(kBBQ3, perspective)) {
+    QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slower_startup3, 3, 4);
+    enable_ack_aggregation_during_startup_ = true;
+  }
+  if (GetQuicReloadableFlag(quic_bbr_slower_startup3) &&
+      config.HasClientRequestedIndependentOption(kBBQ4, perspective)) {
+    QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_slower_startup3, 4, 4);
+    set_drain_gain(kModerateProbeRttMultiplier);
+  }
   if (config.HasClientRequestedIndependentOption(kMIN1, perspective)) {
     min_congestion_window_ = kMaxSegmentSize;
   }
@@ -280,6 +308,7 @@
   DiscardLostPackets(lost_packets);
 
   // Input the new data into the BBR model of the connection.
+  QuicByteCount excess_acked = 0;
   if (!acked_packets.empty()) {
     QuicPacketNumber last_acked_packet = acked_packets.rbegin()->packet_number;
     is_round_start = UpdateRoundTripCounter(last_acked_packet);
@@ -290,7 +319,7 @@
     const QuicByteCount bytes_acked =
         sampler_->total_bytes_acked() - total_bytes_acked_before;
 
-    UpdateAckAggregationBytes(event_time, bytes_acked);
+    excess_acked = UpdateAckAggregationBytes(event_time, bytes_acked);
   }
 
   // Handle logic specific to PROBE_BW mode.
@@ -318,7 +347,7 @@
   // After the model is updated, recalculate the pacing rate and congestion
   // window.
   CalculatePacingRate();
-  CalculateCongestionWindow(bytes_acked);
+  CalculateCongestionWindow(bytes_acked, excess_acked);
   CalculateRecoveryWindow(bytes_acked, bytes_lost);
 
   // Cleanup internal state.
@@ -355,7 +384,7 @@
 void BbrSender::EnterStartupMode() {
   mode_ = STARTUP;
   pacing_gain_ = high_gain_;
-  congestion_window_gain_ = high_gain_;
+  congestion_window_gain_ = high_cwnd_gain_;
 }
 
 void BbrSender::EnterProbeBandwidthMode(QuicTime now) {
@@ -523,7 +552,7 @@
   if (mode_ == STARTUP && is_at_full_bandwidth_) {
     mode_ = DRAIN;
     pacing_gain_ = drain_gain_;
-    congestion_window_gain_ = high_gain_;
+    congestion_window_gain_ = high_cwnd_gain_;
   }
   if (mode_ == DRAIN &&
       unacked_packets_->bytes_in_flight() <= GetTargetCongestionWindow(1)) {
@@ -625,8 +654,9 @@
 }
 
 // TODO(ianswett): Move this logic into BandwidthSampler.
-void BbrSender::UpdateAckAggregationBytes(QuicTime ack_time,
-                                          QuicByteCount newly_acked_bytes) {
+QuicByteCount BbrSender::UpdateAckAggregationBytes(
+    QuicTime ack_time,
+    QuicByteCount newly_acked_bytes) {
   // Compute how many bytes are expected to be delivered, assuming max bandwidth
   // is correct.
   QuicByteCount expected_bytes_acked =
@@ -637,7 +667,7 @@
     // Reset to start measuring a new aggregation epoch.
     aggregation_epoch_bytes_ = newly_acked_bytes;
     aggregation_epoch_start_time_ = ack_time;
-    return;
+    return 0;
   }
 
   // Compute how many extra bytes were delivered vs max bandwidth.
@@ -645,6 +675,7 @@
   aggregation_epoch_bytes_ += newly_acked_bytes;
   max_ack_height_.Update(aggregation_epoch_bytes_ - expected_bytes_acked,
                          round_trip_count_);
+  return aggregation_epoch_bytes_ - expected_bytes_acked;
 }
 
 void BbrSender::CalculatePacingRate() {
@@ -677,7 +708,8 @@
   pacing_rate_ = std::max(pacing_rate_, target_rate);
 }
 
-void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked) {
+void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked,
+                                          QuicByteCount excess_acked) {
   if (mode_ == PROBE_RTT) {
     return;
   }
@@ -687,6 +719,10 @@
   if (is_at_full_bandwidth_) {
     // Add the max recently measured ack aggregation to CWND.
     target_window += max_ack_height_.GetBest();
+  } else if (enable_ack_aggregation_during_startup_) {
+    // Add the most recent excess acked.  Because CWND never decreases in
+    // STARTUP, this will automatically create a very localized max filter.
+    target_window += excess_acked;
   }
 
   // Instead of immediately setting the target CWND as the new one, BBR grows
@@ -739,10 +775,15 @@
     recovery_window_ += bytes_acked / 2;
   }
 
-  // Sanity checks.  Ensure that we always allow to send at least
-  // |bytes_acked| in response.
+  // Sanity checks.  Ensure that we always allow to send at least an MSS or
+  // |bytes_acked| in response, whichever is larger.
   recovery_window_ = std::max(
       recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked);
+  if (GetQuicReloadableFlag(quic_bbr_one_mss_conservation)) {
+    recovery_window_ =
+        std::max(recovery_window_,
+                 unacked_packets_->bytes_in_flight() + kMaxSegmentSize);
+  }
   recovery_window_ = std::max(min_congestion_window_, recovery_window_);
 }
 
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender.h b/net/third_party/quic/core/congestion_control/bbr_sender.h
index ee2bae7..5017c9ee 100644
--- a/net/third_party/quic/core/congestion_control/bbr_sender.h
+++ b/net/third_party/quic/core/congestion_control/bbr_sender.h
@@ -139,10 +139,22 @@
     return has_non_app_limited_sample_;
   }
 
-  // Sets the pacing and CWND gain used in STARTUP.  Must be greater than 1.
+  // Sets the pacing gain used in STARTUP.  Must be greater than 1.
   void set_high_gain(float high_gain) {
     DCHECK_LT(1.0f, high_gain);
     high_gain_ = high_gain;
+    if (mode_ == STARTUP) {
+      pacing_gain_ = high_gain;
+    }
+  }
+
+  // Sets the CWND gain used in STARTUP.  Must be greater than 1.
+  void set_high_cwnd_gain(float high_cwnd_gain) {
+    DCHECK_LT(1.0f, high_cwnd_gain);
+    high_cwnd_gain_ = high_cwnd_gain;
+    if (mode_ == STARTUP) {
+      congestion_window_gain_ = high_cwnd_gain;
+    }
   }
 
   // Sets the gain used in DRAIN.  Must be less than 1.
@@ -215,13 +227,16 @@
                            bool is_round_start);
 
   // Updates the ack aggregation max filter in bytes.
-  void UpdateAckAggregationBytes(QuicTime ack_time,
-                                 QuicByteCount newly_acked_bytes);
+  // Returns the most recent addition to the filter, or |newly_acked_bytes| if
+  // nothing was fed in to the filter.
+  QuicByteCount UpdateAckAggregationBytes(QuicTime ack_time,
+                                          QuicByteCount newly_acked_bytes);
 
   // Determines the appropriate pacing rate for the connection.
   void CalculatePacingRate();
   // Determines the appropriate congestion window for the connection.
-  void CalculateCongestionWindow(QuicByteCount bytes_acked);
+  void CalculateCongestionWindow(QuicByteCount bytes_acked,
+                                 QuicByteCount excess_acked);
   // Determines the approriate window that constrains the in-flight during
   // recovery.
   void CalculateRecoveryWindow(QuicByteCount bytes_acked,
@@ -275,9 +290,12 @@
   // The smallest value the |congestion_window_| can achieve.
   QuicByteCount min_congestion_window_;
 
-  // The pacing and CWND gain applied during the STARTUP phase.
+  // The pacing gain applied during the STARTUP phase.
   float high_gain_;
 
+  // The CWND gain applied during the STARTUP phase.
+  float high_cwnd_gain_;
+
   // The pacing gain applied during the DRAIN phase.
   float drain_gain_;
 
@@ -344,6 +362,8 @@
   bool rate_based_startup_;
   // Used as the initial packet conservation mode when first entering recovery.
   RecoveryState initial_conservation_in_startup_;
+  // When true, add the most recent ack aggregation measurement during STARTUP.
+  bool enable_ack_aggregation_during_startup_;
 
   // If true, will not exit low gain mode until bytes_in_flight drops below BDP
   // or it's time for high gain mode.
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender_test.cc b/net/third_party/quic/core/congestion_control/bbr_sender_test.cc
index c173686..600a9db 100644
--- a/net/third_party/quic/core/congestion_control/bbr_sender_test.cc
+++ b/net/third_party/quic/core/congestion_control/bbr_sender_test.cc
@@ -620,6 +620,74 @@
       timeout);
   ASSERT_TRUE(simulator_result);
   ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  ExpectApproxEq(sender_->BandwidthEstimate() * (1 / 2.885f),
+                 sender_->PacingRate(0), 0.01f);
+  // BBR uses CWND gain of 2.88 during STARTUP, hence it will fill the buffer
+  // with approximately 1.88 BDPs.  Here, we use 1.5 to give some margin for
+  // error.
+  EXPECT_GE(queue->bytes_queued(), 1.5 * kTestBdp);
+
+  // Observe increased RTT due to bufferbloat.
+  const QuicTime::Delta queueing_delay =
+      kTestLinkBandwidth.TransferTime(queue->bytes_queued());
+  ExpectApproxEq(kTestRtt + queueing_delay, rtt_stats_->latest_rtt(), 0.1f);
+
+  // Transition to the drain phase and verify that it makes the queue
+  // have at most a BDP worth of packets.
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().mode != BbrSender::DRAIN; },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+  EXPECT_LE(queue->bytes_queued(), kTestBdp);
+
+  // Wait for a few round trips and ensure we're in appropriate phase of gain
+  // cycling before taking an RTT measurement.
+  const QuicRoundTripCount start_round_trip =
+      sender_->ExportDebugState().round_trip_count;
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this, start_round_trip]() {
+        QuicRoundTripCount rounds_passed =
+            sender_->ExportDebugState().round_trip_count - start_round_trip;
+        return rounds_passed >= 4 &&
+               sender_->ExportDebugState().gain_cycle_index == 7;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Observe the bufferbloat go away.
+  ExpectApproxEq(kTestRtt, rtt_stats_->smoothed_rtt(), 0.1f);
+}
+
+// Verify that the DRAIN phase works correctly.
+TEST_F(BbrSenderTest, ShallowDrain) {
+  SetQuicReloadableFlag(quic_bbr_slower_startup3, true);
+  // Disable Ack Decimation on the receiver, because it can increase srtt.
+  QuicConnectionPeer::SetAckMode(receiver_.connection(),
+                                 QuicConnection::AckMode::TCP_ACKING);
+
+  CreateDefaultSetup();
+  // BBQ4 increases the pacing gain in DRAIN to 0.75
+  SetConnectionOption(kBBQ4);
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
+  // Get the queue at the bottleneck, which is the outgoing queue at the port to
+  // which the receiver is connected.
+  const simulator::Queue* queue = switch_->port_queue(2);
+  bool simulator_result;
+
+  // We have no intention of ever finishing this transfer.
+  bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+  // Run the startup, and verify that it fills up the queue.
+  ASSERT_EQ(BbrSender::STARTUP, sender_->ExportDebugState().mode);
+  simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() {
+        return sender_->ExportDebugState().mode != BbrSender::STARTUP;
+      },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+  ASSERT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(0.75 * sender_->BandwidthEstimate(), sender_->PacingRate(0));
   // BBR uses CWND gain of 2.88 during STARTUP, hence it will fill the buffer
   // with approximately 1.88 BDPs.  Here, we use 1.5 to give some margin for
   // error.
@@ -1046,6 +1114,96 @@
   EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
 }
 
+TEST_F(BbrSenderTest, DerivedPacingGainStartup) {
+  SetQuicReloadableFlag(quic_bbr_slower_startup3, true);
+  CreateDefaultSetup();
+
+  SetConnectionOption(kBBQ1);
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.773 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  ExpectApproxEq(expected_pacing_rate.ToBitsPerSecond(),
+                 sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  ExpectApproxEq(kTestLinkBandwidth, sender_->ExportDebugState().max_bandwidth,
+                 0.01f);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+TEST_F(BbrSenderTest, DerivedCWNDGainStartup) {
+  SetQuicReloadableFlag(quic_bbr_slower_startup3, true);
+  CreateDefaultSetup();
+
+  SetConnectionOption(kBBQ2);
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  ExpectApproxEq(expected_pacing_rate.ToBitsPerSecond(),
+                 sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  ExpectApproxEq(kTestLinkBandwidth, sender_->ExportDebugState().max_bandwidth,
+                 0.01f);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+  // Expect an SRTT less than 2.7 * Min RTT on exit from STARTUP.
+  EXPECT_GT(kTestRtt * 2.7, rtt_stats_->smoothed_rtt());
+}
+
+TEST_F(BbrSenderTest, AckAggregationInStartup) {
+  SetQuicReloadableFlag(quic_bbr_slower_startup3, true);
+  // Disable Ack Decimation on the receiver to avoid loss and make results
+  // consistent.
+  QuicConnectionPeer::SetAckMode(receiver_.connection(),
+                                 QuicConnection::AckMode::TCP_ACKING);
+  CreateDefaultSetup();
+
+  SetConnectionOption(kBBQ3);
+  EXPECT_EQ(3u, sender_->num_startup_rtts());
+  // Verify that Sender is in slow start.
+  EXPECT_TRUE(sender_->InSlowStart());
+  // Verify that pacing rate is based on the initial RTT.
+  QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
+      2.885 * kDefaultWindowTCP, rtt_stats_->initial_rtt());
+  ExpectApproxEq(expected_pacing_rate.ToBitsPerSecond(),
+                 sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return sender_->ExportDebugState().is_at_full_bandwidth; },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(3u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  ExpectApproxEq(kTestLinkBandwidth, sender_->ExportDebugState().max_bandwidth,
+                 0.01f);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
 // Test that two BBR flows started slightly apart from each other terminate.
 TEST_F(BbrSenderTest, SimpleCompetition) {
   const QuicByteCount transfer_size = 10 * 1024 * 1024;
diff --git a/net/third_party/quic/core/congestion_control/pacing_sender.h b/net/third_party/quic/core/congestion_control/pacing_sender.h
index df7da8b..f8eddcd 100644
--- a/net/third_party/quic/core/congestion_control/pacing_sender.h
+++ b/net/third_party/quic/core/congestion_control/pacing_sender.h
@@ -92,6 +92,8 @@
   uint32_t lumpy_tokens_;
 
   // If the next send time is within alarm_granularity_, send immediately.
+  // TODO(fayang): Remove alarm_granularity_ when deprecating
+  // FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2.
   QuicTime::Delta alarm_granularity_;
 
   // Indicates whether pacing throttles the sending. If true, make up for lost
diff --git a/net/third_party/quic/core/crypto/crypto_protocol.h b/net/third_party/quic/core/crypto/crypto_protocol.h
index 886697cd..cee3d2e 100644
--- a/net/third_party/quic/core/crypto/crypto_protocol.h
+++ b/net/third_party/quic/core/crypto/crypto_protocol.h
@@ -100,6 +100,13 @@
                                                  // recently app-limited
 const QuicTag kBBRS = TAG('B', 'B', 'R', 'S');   // Use 1.5x pacing in startup
                                                  // after a loss has occurred.
+const QuicTag kBBQ1 = TAG('B', 'B', 'Q', '1');   // BBR with lower 2.77 STARTUP
+                                                 // pacing and CWND gain.
+const QuicTag kBBQ2 = TAG('B', 'B', 'Q', '2');   // BBR with lower 2.0 STARTUP
+                                                 // CWND gain.
+const QuicTag kBBQ3 = TAG('B', 'B', 'Q', '3');   // BBR with ack aggregation
+                                                 // compensation in STARTUP.
+const QuicTag kBBQ4 = TAG('B', 'B', 'Q', '4');   // Drain gain of 0.75.
 const QuicTag kRENO = TAG('R', 'E', 'N', 'O');   // Reno Congestion Control
 const QuicTag kTPCC = TAG('P', 'C', 'C', '\0');  // Performance-Oriented
                                                  // Congestion Control
diff --git a/net/third_party/quic/core/quic_connection.cc b/net/third_party/quic/core/quic_connection.cc
index 4f6f81a5..3011d90 100644
--- a/net/third_party/quic/core/quic_connection.cc
+++ b/net/third_party/quic/core/quic_connection.cc
@@ -72,6 +72,9 @@
 // the message as being too big.
 const int kMessageTooBigErrorCode = net::ERR_MSG_TOO_BIG;
 
+// The minimum release time into future in ms.
+const int kMinReleaseTimeIntoFutureMs = 1;
+
 bool Near(QuicPacketNumber a, QuicPacketNumber b) {
   QuicPacketNumber delta = (a > b) ? a - b : b - a;
   return delta <= kMaxPacketGap;
@@ -315,8 +318,7 @@
       is_path_degrading_(false),
       processing_ack_frame_(false),
       supports_release_time_(writer->SupportsReleaseTime()),
-      pace_time_into_future_(QuicTime::Delta::FromMilliseconds(
-          GetQuicFlag(FLAGS_quic_pace_time_into_future_ms))),
+      release_time_into_future_(QuicTime::Delta::Zero()),
       deprecate_scheduler_(
           GetQuicReloadableFlag(quic_deprecate_scoped_scheduler2)),
       add_to_blocked_list_if_writer_blocked_(
@@ -339,10 +341,13 @@
   // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
   // and make it required non-null, because it's always used.
   sent_packet_manager_.SetNetworkChangeVisitor(this);
-  if (supports_release_time_) {
-    // When offloading pacing, set alarm granularity to 0 to achieve more
-    // accurate pacing.
+  if (GetQuicRestartFlag(quic_offload_pacing_to_usps2)) {
     sent_packet_manager_.SetPacingAlarmGranularity(QuicTime::Delta::Zero());
+    release_time_into_future_ =
+        QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs);
+  }
+  if (supports_release_time_) {
+    UpdateReleaseTimeIntoFuture();
   }
   // Allow the packet writer to potentially reduce the packet size to a value
   // even smaller than kDefaultMaxPacketSize.
@@ -944,6 +949,10 @@
   if (send_alarm_->IsSet()) {
     send_alarm_->Cancel();
   }
+  if (supports_release_time_) {
+    // Update pace time into future because smoothed RTT is likely updated.
+    UpdateReleaseTimeIntoFuture();
+  }
   largest_seen_packet_with_ack_ = last_header_.packet_number;
   // If the incoming ack's packets set expresses missing packets: peer is still
   // waiting for a packet lower than a packet that we are no longer planning to
@@ -1987,12 +1996,11 @@
 
   // Scheduler requires a delay.
   if (!delay.IsZero()) {
-    if (supports_release_time_ && delay <= pace_time_into_future_) {
-      // Offload pacing to the writer, send packet now.
+    if (delay <= release_time_into_future_) {
+      // Required delay is within pace time into future, send now.
       return true;
     }
-    // Cannot send packet now because either the pacing cannot be offloaded or
-    // the delay is too far in the future.
+    // Cannot send packet now because delay is too far in the future.
     send_alarm_->Update(now + delay, QuicTime::Delta::FromMilliseconds(1));
     QUIC_DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds()
                   << "ms";
@@ -2947,13 +2955,6 @@
     return true;
   }
 
-  if (GetQuicReloadableFlag(
-          quic_clear_queued_packets_before_sending_connectivity_probing)) {
-    QUIC_FLAG_COUNT(
-        quic_reloadable_flag_quic_clear_queued_packets_before_sending_connectivity_probing);  // NOLINT
-    ClearQueuedPackets();
-  }
-
   QUIC_DLOG(INFO) << ENDPOINT << "Sending connectivity probing packet for "
                   << "connection_id = " << connection_id_;
 
@@ -3278,5 +3279,17 @@
       QuicTime::Delta::Zero());
 }
 
+void QuicConnection::UpdateReleaseTimeIntoFuture() {
+  DCHECK(supports_release_time_);
+
+  release_time_into_future_ = std::max(
+      QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs),
+      std::min(
+          QuicTime::Delta::FromMilliseconds(
+              GetQuicFlag(FLAGS_quic_max_pace_time_into_future_ms)),
+          sent_packet_manager_.GetRttStats()->SmoothedOrInitialRtt() *
+              GetQuicFlag(FLAGS_quic_pace_time_into_future_srtt_fraction)));
+}
+
 #undef ENDPOINT  // undef for jumbo builds
 }  // namespace quic
diff --git a/net/third_party/quic/core/quic_connection.h b/net/third_party/quic/core/quic_connection.h
index 5d7dd67d..9d5975c 100644
--- a/net/third_party/quic/core/quic_connection.h
+++ b/net/third_party/quic/core/quic_connection.h
@@ -416,7 +416,7 @@
 
   // Called when an error occurs while attempting to write a packet to the
   // network.
-  virtual void OnWriteError(int error_code);
+  void OnWriteError(int error_code);
 
   // Whether |result| represents a MSG TOO BIG write error.
   bool IsMsgTooBig(const WriteResult& result);
@@ -1005,6 +1005,9 @@
   // |acked_new_packet| is true if a previously-unacked packet was acked.
   void PostProcessAfterAckFrame(bool send_stop_waiting, bool acked_new_packet);
 
+  // Updates the release time into the future.
+  void UpdateReleaseTimeIntoFuture();
+
   QuicFramer framer_;
 
   // Contents received in the current packet, especially used to identify
@@ -1309,9 +1312,8 @@
   // True if the writer supports release timestamp.
   const bool supports_release_time_;
 
-  // Latched value of FLAGS_quic_pace_time_into_future_ms. Only used when
-  // supports_release_time_ is true.
-  const QuicTime::Delta pace_time_into_future_;
+  // Time this connection can release packets into the future.
+  QuicTime::Delta release_time_into_future_;
 
   // Latched value of quic_reloadable_flag_quic_deprecate_scoped_scheduler2.
   // TODO(fayang): Remove ScopedRetransmissionScheduler when deprecating
diff --git a/net/third_party/quic/core/quic_connection_test.cc b/net/third_party/quic/core/quic_connection_test.cc
index f41f6fc..c8be24e 100644
--- a/net/third_party/quic/core/quic_connection_test.cc
+++ b/net/third_party/quic/core/quic_connection_test.cc
@@ -1535,19 +1535,12 @@
   connection_.SendConnectivityProbingPacket(writer_.get(),
                                             connection_.peer_address());
 
-  if (GetQuicReloadableFlag(
-          quic_clear_queued_packets_before_sending_connectivity_probing)) {
-    EXPECT_EQ(0u, connection_.NumQueuedPackets());
-    connection_.OnCanWrite();
-    EXPECT_TRUE(connection_.connected());
-  } else {
-    EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INTERNAL_ERROR,
-                                             "Packet written out of order.",
-                                             ConnectionCloseSource::FROM_SELF));
-    EXPECT_QUIC_BUG(connection_.OnCanWrite(),
-                    "Attempt to write packet:1 after:2");
-    EXPECT_FALSE(connection_.connected());
-  }
+  EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INTERNAL_ERROR,
+                                           "Packet written out of order.",
+                                           ConnectionCloseSource::FROM_SELF));
+  EXPECT_QUIC_BUG(connection_.OnCanWrite(),
+                  "Attempt to write packet:1 after:2");
+  EXPECT_FALSE(connection_.connected());
 }
 
 TEST_P(QuicConnectionTest, DiscardQueuedPacketsAfterConnectionClose) {
diff --git a/net/third_party/quic/core/quic_flags_list.h b/net/third_party/quic/core/quic_flags_list.h
index 3940e15..9abcf0ca 100644
--- a/net/third_party/quic/core/quic_flags_list.h
+++ b/net/third_party/quic/core/quic_flags_list.h
@@ -93,16 +93,7 @@
 // If true, enable QUIC v99.
 QUIC_FLAG(bool, FLAGS_quic_enable_version_99, false)
 
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_41_2, false)
-
-// If this flag and
-// FLAGS_quic_reloadable_flag_quic_fix_write_out_of_order_queued_packet_crash
-// are both ture, QUIC will clear queued packets before sending connectivity
-// probing packets.
-QUIC_FLAG(
-    bool,
-    FLAGS_quic_reloadable_flag_quic_clear_queued_packets_before_sending_connectivity_probing,
-    false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_41_2, true)
 
 // When true, set the initial congestion control window from connection options
 // in QuicSentPacketManager rather than TcpCubicSenderBytes.
@@ -121,11 +112,11 @@
 
 // Enables the 1RTO connection option which only sends one packet on QUIC
 // retransmission timeout, instead of 2.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_one_rto, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_one_rto, true)
 
 // When true, the NRTT QUIC connection option causes receivers to ignore
 // incoming initial RTT values.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_no_irtt, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_no_irtt, true)
 
 // If true, put ScopedRetransmissionScheduler's functionality to
 // ScopedPacketFlusher.
@@ -135,15 +126,16 @@
 
 // If it's been more than SRTT since receiving a packet, set the ack alarm for
 // 1ms instead of the standard delayed ack timer.
-QUIC_FLAG(bool,
-          FLAGS_quic_reloadable_flag_quic_fast_ack_after_quiescence,
-          false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fast_ack_after_quiescence, true)
 
 // If true, QUIC offload pacing when using USPS as egress method.
-QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_offload_pacing_to_usps, false)
+QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2, false)
 
-// Time that QUIC can pace packets into the future in ms.
-QUIC_FLAG(int32_t, FLAGS_quic_pace_time_into_future_ms, 10)
+// Max time that QUIC can pace packets into the future in ms.
+QUIC_FLAG(int32_t, FLAGS_quic_max_pace_time_into_future_ms, 10)
+
+// Smoothed RTT fraction that a connection can pace packets into the future.
+QUIC_FLAG(double, FLAGS_quic_pace_time_into_future_srtt_fraction, 0.125f)
 
 // If true, enable QUIC v44.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_44, true)
@@ -163,32 +155,32 @@
 // largest sent packet.
 QUIC_FLAG(bool,
           FLAGS_quic_reloadable_flag_quic_validate_ack_largest_observed,
-          false)
+          true)
 
 // If true, QuicConnection::ProcessPacket will add the connection to write
 // blocked list if it is write blocked, and will not attempt to write before the
 // writer unblocks.
 QUIC_FLAG(bool,
           FLAGS_quic_reloadable_flag_quic_add_to_blocked_list_if_writer_blocked,
-          false)
+          true)
 
 // Only send an ack immediately when a previously missing packet is received if
 // an ack with a larger largest acked has already been sent.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_ack_reordered_packets, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_ack_reordered_packets, true)
 
 // If true, QuicWriteBlockedList will use StaticStreamCollection to speed up
 // operations on static streams.
 QUIC_FLAG(
     bool,
     FLAGS_quic_reloadable_flag_quic_use_static_stream_collection_in_write_blocked_list,
-    false)
+    true)
 
 // If true, disables QUIC v42.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_42, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_42, true)
 
 // Stop checking QuicUnackedPacketMap::HasUnackedRetransmittableFrames and
 // instead rely on the existing check that bytes_in_flight > 0
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_optimize_inflight_check, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_optimize_inflight_check, true)
 
 // When you\'re app-limited entering recovery, stay app-limited until you exit
 // recovery in QUIC BBR.
@@ -198,7 +190,7 @@
 // retransmisssions and we then become congestion control blocked.
 QUIC_FLAG(bool,
           FLAGS_quic_reloadable_flag_quic_retransmissions_app_limited,
-          false)
+          true)
 
 // If true, stop resetting ideal_next_packet_send_time_ in pacing sender.
 QUIC_FLAG(
@@ -208,3 +200,14 @@
 
 // If true, enable experiment for testing PCC congestion-control.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_pcc3, false)
+
+// If true, fix potential crashes in QuicSession::RetransmitLostData.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_retransmit_lost_data, true)
+
+// When true, ensure BBR allows at least one MSS to be sent in response to an
+// ACK in packet conservation.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_one_mss_conservation, false)
+
+// Add 3 connection options to decrease the pacing and CWND gain in QUIC BBR
+// STARTUP.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_slower_startup3, false)
diff --git a/net/third_party/quic/core/quic_session.cc b/net/third_party/quic/core/quic_session.cc
index 5c4701e..41a1d65 100644
--- a/net/third_party/quic/core/quic_session.cc
+++ b/net/third_party/quic/core/quic_session.cc
@@ -1164,8 +1164,8 @@
       break;
     }
     // Retransmit lost data on headers and data streams.
-    QuicStream* stream =
-        GetStream(streams_with_pending_retransmission_.begin()->first);
+    const QuicStreamId id = streams_with_pending_retransmission_.begin()->first;
+    QuicStream* stream = GetStream(id);
     if (stream != nullptr) {
       SetTransmissionType(LOSS_RETRANSMISSION);
       stream->OnCanWrite();
@@ -1174,7 +1174,18 @@
         // Connection is write blocked.
         break;
       } else {
-        streams_with_pending_retransmission_.pop_front();
+        if (GetQuicReloadableFlag(quic_fix_retransmit_lost_data)) {
+          QUIC_FLAG_COUNT(quic_reloadable_flag_quic_fix_retransmit_lost_data);
+          if (!streams_with_pending_retransmission_.empty() &&
+              streams_with_pending_retransmission_.begin()->first == id) {
+            // Retransmit lost data may cause connection close. If this stream
+            // has not yet sent fin, a RST_STREAM will be sent and it will be
+            // removed from streams_with_pending_retransmission_.
+            streams_with_pending_retransmission_.pop_front();
+          }
+        } else {
+          streams_with_pending_retransmission_.pop_front();
+        }
       }
     } else {
       QUIC_BUG << "Try to retransmit data of a closed stream";
diff --git a/net/third_party/quic/core/quic_session_test.cc b/net/third_party/quic/core/quic_session_test.cc
index 14c4d6e..d6a8874 100644
--- a/net/third_party/quic/core/quic_session_test.cc
+++ b/net/third_party/quic/core/quic_session_test.cc
@@ -1404,6 +1404,29 @@
   session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
 }
 
+// Regression test of b/110082001.
+TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
+  // This test mimics the scenario when a dynamic stream retransmits lost data
+  // and causes connection close.
+  QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
+  TestStream* stream = session_.CreateOutgoingDynamicStream();
+  QuicStreamFrame frame(stream->id(), false, 0, 9);
+
+  EXPECT_CALL(*stream, HasPendingRetransmission())
+      .Times(2)
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  session_.OnFrameLost(QuicFrame(&frame));
+  // Retransmit stream data causes connection close. Stream has not sent fin
+  // yet, so an RST is sent.
+  EXPECT_CALL(*stream, OnCanWrite())
+      .WillOnce(Invoke(stream, &QuicStream::OnClose));
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+  EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+  session_.OnCanWrite();
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic
diff --git a/net/third_party/quic/core/quic_versions_test.cc b/net/third_party/quic/core/quic_versions_test.cc
index 0f68492..112929e 100644
--- a/net/third_party/quic/core/quic_versions_test.cc
+++ b/net/third_party/quic/core/quic_versions_test.cc
@@ -343,6 +343,7 @@
 TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo99) {
   QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
   SetQuicReloadableFlag(quic_disable_version_41_2, false);
+  SetQuicReloadableFlag(quic_disable_version_42, false);
   SetQuicReloadableFlag(quic_enable_version_43, true);
   SetQuicReloadableFlag(quic_enable_version_44, true);
   SetQuicFlag(&FLAGS_quic_enable_version_99, false);
@@ -366,6 +367,7 @@
 TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo44) {
   QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
   SetQuicReloadableFlag(quic_disable_version_41_2, false);
+  SetQuicReloadableFlag(quic_disable_version_42, false);
   SetQuicReloadableFlag(quic_enable_version_43, true);
   SetQuicReloadableFlag(quic_enable_version_44, false);
   SetQuicFlag(&FLAGS_quic_enable_version_99, false);
@@ -386,6 +388,29 @@
   ASSERT_EQ(expected_parsed_versions, FilterSupportedVersions(parsed_versions));
 }
 
+TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo43) {
+  QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
+  SetQuicReloadableFlag(quic_disable_version_41_2, false);
+  SetQuicReloadableFlag(quic_disable_version_42, false);
+  SetQuicReloadableFlag(quic_enable_version_43, false);
+  SetQuicReloadableFlag(quic_enable_version_44, false);
+  SetQuicFlag(&FLAGS_quic_enable_version_99, false);
+  ParsedQuicVersionVector parsed_versions;
+  for (QuicTransportVersion version : all_versions) {
+    parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version));
+  }
+  QuicTransportVersionVector expected_versions = {
+      QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39, QUIC_VERSION_35};
+  ParsedQuicVersionVector expected_parsed_versions;
+  for (QuicTransportVersion version : expected_versions) {
+    expected_parsed_versions.push_back(
+        ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version));
+  }
+
+  ASSERT_EQ(expected_versions, FilterSupportedTransportVersions(all_versions));
+  ASSERT_EQ(expected_parsed_versions, FilterSupportedVersions(parsed_versions));
+}
+
 TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo42) {
   QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
   SetQuicReloadableFlag(quic_disable_version_41_2, false);
diff --git a/net/third_party/quic/quartc/quartc_factory.cc b/net/third_party/quic/quartc/quartc_factory.cc
index a1cf7f5..0dc5d2e 100644
--- a/net/third_party/quic/quartc/quartc_factory.cc
+++ b/net/third_party/quic/quartc/quartc_factory.cc
@@ -125,6 +125,10 @@
   // This flag must be set before quic connection is created.
   SetQuicReloadableFlag(quic_deprecate_scoped_scheduler2, true);
 
+  // ACK less aggressively when reordered packets are present.
+  // Must be set before the connection is created.
+  SetQuicReloadableFlag(quic_ack_reordered_packets, true);
+
   std::unique_ptr<QuicConnection> quic_connection =
       CreateQuicConnection(perspective, writer.get());
 
diff --git a/net/third_party/quic/test_tools/simulator/quic_endpoint_test.cc b/net/third_party/quic/test_tools/simulator/quic_endpoint_test.cc
index 7a4295a..5b30fe9b 100644
--- a/net/third_party/quic/test_tools/simulator/quic_endpoint_test.cc
+++ b/net/third_party/quic/test_tools/simulator/quic_endpoint_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quic/test_tools/simulator/quic_endpoint.h"
 
+#include "net/third_party/quic/platform/api/quic_flags.h"
 #include "net/third_party/quic/platform/api/quic_ptr_util.h"
 #include "net/third_party/quic/platform/api/quic_test.h"
 #include "net/third_party/quic/test_tools/quic_connection_peer.h"
@@ -153,6 +154,8 @@
 
 // Simulate three hosts trying to send data to a fourth one simultaneously.
 TEST_F(QuicEndpointTest, Competition) {
+  // TODO(fayang): Turn back on this flag when the issue if fixed.
+  SetQuicReloadableFlag(quic_bbr_one_mss_conservation, false);
   auto endpoint_a = QuicMakeUnique<QuicEndpoint>(
       &simulator_, "Endpoint A", "Endpoint D (A)", Perspective::IS_CLIENT, 42);
   auto endpoint_b = QuicMakeUnique<QuicEndpoint>(
diff --git a/net/tools/transport_security_state_generator/README.md b/net/tools/transport_security_state_generator/README.md
index db93276..b26e462 100644
--- a/net/tools/transport_security_state_generator/README.md
+++ b/net/tools/transport_security_state_generator/README.md
@@ -20,7 +20,6 @@
 * [HTTP Strict Transport Security (HSTS)](https://tools.ietf.org/html/rfc6797)
 * [Public Key Pinning Extension for HTTP](https://tools.ietf.org/html/rfc7469)
 * [Expect-CT Extension for HTTP](http://httpwg.org/http-extensions/expect-ct.html)
-* [OCSP Expect-Staple](https://docs.google.com/document/d/1aISglJIIwglcOAhqNfK-2vtQl-_dWAapc-VLDh-9-BE/preview)
 
 Chromium and most other browsers ship the preloaded configurations inside their
 binary. Chromium uses a custom data structure for this.
@@ -169,7 +168,7 @@
 
 ```abnf
 preloaded-entry    = BIT                   ; simple entry flag
-                     [hsts-part hpkp-part expect-ct-part expect-staple-part]
+                     [hsts-part hpkp-part expect-ct-part]
                                            ; policy specific parts are only
                                            ; present when the simple entry flag
                                            ; is set to 0 and omitted otherwise
@@ -188,12 +187,6 @@
 expect-ct-part     = BIT              ; whether to enable Expect-CT
                      [report-uri-id]  ; only present when Expect-CT is enabled
 
-expect-staple-part = BIT              ; whether to enable Expect-Staple
-                     [include-subdomains report-uri-id]
-                                      ; Expect-Staple includeSubdomains flag and
-                                      ; report-uri, only present when
-                                      ; Expect-Staple is enabled
-
 report-uri-id      = array-index
 include-subdomains = BIT
 array-index        = 4BIT             ; a 4 bit number
@@ -204,8 +197,6 @@
 *  `net::TransportSecurityStateSource::pinsets` for **pinset-id**
 *  `net::TransportSecurityStateSource::expect_ct_report_uris` for Expect-CT's
 **report-uri-id**
-*  `net::TransportSecurityStateSource::expect_staple_report_uris` for
-Expect-Staple's **report-uri-id**.
 
 #### Simple entries
 
diff --git a/net/tools/transport_security_state_generator/input_file_parsers.cc b/net/tools/transport_security_state_generator/input_file_parsers.cc
index 85e2245..1046ff6 100644
--- a/net/tools/transport_security_state_generator/input_file_parsers.cc
+++ b/net/tools/transport_security_state_generator/input_file_parsers.cc
@@ -175,10 +175,6 @@
 static const char kPinsJSONKey[] = "pins";
 static const char kExpectCTJSONKey[] = "expect_ct";
 static const char kExpectCTReportURIJSONKey[] = "expect_ct_report_uri";
-static const char kExpectStapleJSONKey[] = "expect_staple";
-static const char kExpectStapleReportURIJSONKey[] = "expect_staple_report_uri";
-static const char kIncludeSubdomainsForExpectStapleJSONKey[] =
-    "include_subdomains_for_expect_staple";
 
 // Additional valid keys for entries in the input JSON that will not be included
 // in the output and contain metadata (e.g., for list maintenance).
@@ -306,10 +302,7 @@
                                       kModeJSONKey,
                                       kPinsJSONKey,
                                       kExpectCTJSONKey,
-                                      kExpectCTReportURIJSONKey,
-                                      kExpectStapleJSONKey,
-                                      kExpectStapleReportURIJSONKey,
-                                      kIncludeSubdomainsForExpectStapleJSONKey};
+                                      kExpectCTReportURIJSONKey};
 
   // See the comments in net/http/transport_security_state_static.json for more
   // info on these policies.
@@ -385,11 +378,6 @@
     parsed->GetString(kPinsJSONKey, &entry->pinset);
     parsed->GetBoolean(kExpectCTJSONKey, &entry->expect_ct);
     parsed->GetString(kExpectCTReportURIJSONKey, &entry->expect_ct_report_uri);
-    parsed->GetBoolean(kExpectStapleJSONKey, &entry->expect_staple);
-    parsed->GetBoolean(kIncludeSubdomainsForExpectStapleJSONKey,
-                       &entry->expect_staple_include_subdomains);
-    parsed->GetString(kExpectStapleReportURIJSONKey,
-                      &entry->expect_staple_report_uri);
 
     entries->push_back(std::move(entry));
   }
diff --git a/net/tools/transport_security_state_generator/input_file_parsers_unittest.cc b/net/tools/transport_security_state_generator/input_file_parsers_unittest.cc
index b259994..babe915 100644
--- a/net/tools/transport_security_state_generator/input_file_parsers_unittest.cc
+++ b/net/tools/transport_security_state_generator/input_file_parsers_unittest.cc
@@ -51,18 +51,6 @@
       "      \"policy\": \"test\","
       "      \"expect_ct\": true,"
       "      \"expect_ct_report_uri\": \"https://expect-ct-log.example.com\""
-      "    }, {"
-      "      \"name\": \"expect-staple.example.com\","
-      "      \"policy\": \"test\","
-      "      \"expect_staple\": true,"
-      "      \"expect_staple_report_uri\": "
-      "\"https://expect-staple-log.example.com\","
-      "      \"include_subdomains_for_expect_staple\": true"
-      "    }, {"
-      "      \"name\": \"expect-staple-no-subdomains.example.com\","
-      "      \"policy\": \"test\","
-      "      \"expect_staple\": true,"
-      "      \"include_subdomains_for_expect_staple\": false"
       "    }"
       "  ]"
       "}";
@@ -84,7 +72,7 @@
   ASSERT_EQ(1U, pinset->second->bad_static_spki_hashes().size());
   EXPECT_EQ("BadTestSPKI", pinset->second->bad_static_spki_hashes()[0]);
 
-  ASSERT_EQ(7U, entries.size());
+  ASSERT_EQ(5U, entries.size());
   TransportSecurityStateEntry* entry = entries[0].get();
   EXPECT_EQ("hsts.example.com", entry->hostname);
   EXPECT_TRUE(entry->force_https);
@@ -93,9 +81,6 @@
   EXPECT_EQ("", entry->pinset);
   EXPECT_FALSE(entry->expect_ct);
   EXPECT_EQ("", entry->expect_ct_report_uri);
-  EXPECT_FALSE(entry->expect_staple);
-  EXPECT_FALSE(entry->expect_staple_include_subdomains);
-  EXPECT_EQ("", entry->expect_staple_report_uri);
 
   entry = entries[1].get();
   EXPECT_EQ("hsts-no-subdomains.example.com", entry->hostname);
@@ -105,9 +90,6 @@
   EXPECT_EQ("", entry->pinset);
   EXPECT_FALSE(entry->expect_ct);
   EXPECT_EQ("", entry->expect_ct_report_uri);
-  EXPECT_FALSE(entry->expect_staple);
-  EXPECT_FALSE(entry->expect_staple_include_subdomains);
-  EXPECT_EQ("", entry->expect_staple_report_uri);
 
   entry = entries[2].get();
   EXPECT_EQ("hpkp.example.com", entry->hostname);
@@ -117,9 +99,6 @@
   EXPECT_EQ("thepinset", entry->pinset);
   EXPECT_FALSE(entry->expect_ct);
   EXPECT_EQ("", entry->expect_ct_report_uri);
-  EXPECT_FALSE(entry->expect_staple);
-  EXPECT_FALSE(entry->expect_staple_include_subdomains);
-  EXPECT_EQ("", entry->expect_staple_report_uri);
 
   entry = entries[3].get();
   EXPECT_EQ("hpkp-no-subdomains.example.com", entry->hostname);
@@ -129,9 +108,6 @@
   EXPECT_EQ("thepinset2", entry->pinset);
   EXPECT_FALSE(entry->expect_ct);
   EXPECT_EQ("", entry->expect_ct_report_uri);
-  EXPECT_FALSE(entry->expect_staple);
-  EXPECT_FALSE(entry->expect_staple_include_subdomains);
-  EXPECT_EQ("", entry->expect_staple_report_uri);
 
   entry = entries[4].get();
   EXPECT_EQ("expect-ct.example.com", entry->hostname);
@@ -141,34 +117,6 @@
   EXPECT_EQ("", entry->pinset);
   EXPECT_TRUE(entry->expect_ct);
   EXPECT_EQ("https://expect-ct-log.example.com", entry->expect_ct_report_uri);
-  EXPECT_FALSE(entry->expect_staple);
-  EXPECT_FALSE(entry->expect_staple_include_subdomains);
-  EXPECT_EQ("", entry->expect_staple_report_uri);
-
-  entry = entries[5].get();
-  EXPECT_EQ("expect-staple.example.com", entry->hostname);
-  EXPECT_FALSE(entry->force_https);
-  EXPECT_FALSE(entry->include_subdomains);
-  EXPECT_FALSE(entry->hpkp_include_subdomains);
-  EXPECT_EQ("", entry->pinset);
-  EXPECT_FALSE(entry->expect_ct);
-  EXPECT_EQ("", entry->expect_ct_report_uri);
-  EXPECT_TRUE(entry->expect_staple);
-  EXPECT_TRUE(entry->expect_staple_include_subdomains);
-  EXPECT_EQ("https://expect-staple-log.example.com",
-            entry->expect_staple_report_uri);
-
-  entry = entries[6].get();
-  EXPECT_EQ("expect-staple-no-subdomains.example.com", entry->hostname);
-  EXPECT_FALSE(entry->force_https);
-  EXPECT_FALSE(entry->include_subdomains);
-  EXPECT_FALSE(entry->hpkp_include_subdomains);
-  EXPECT_EQ("", entry->pinset);
-  EXPECT_FALSE(entry->expect_ct);
-  EXPECT_EQ("", entry->expect_ct_report_uri);
-  EXPECT_TRUE(entry->expect_staple);
-  EXPECT_FALSE(entry->expect_staple_include_subdomains);
-  EXPECT_EQ("", entry->expect_staple_report_uri);
 }
 
 // Test that parsing valid JSON with missing keys fails.
diff --git a/net/tools/transport_security_state_generator/preloaded_state_generator.cc b/net/tools/transport_security_state_generator/preloaded_state_generator.cc
index 938dc4911..0070b6e 100644
--- a/net/tools/transport_security_state_generator/preloaded_state_generator.cc
+++ b/net/tools/transport_security_state_generator/preloaded_state_generator.cc
@@ -139,9 +139,6 @@
   NameIDMap expect_ct_report_uri_map;
   ProcessExpectCTURIs(entries, &expect_ct_report_uri_map, &output);
 
-  NameIDMap expect_staple_report_uri_map;
-  ProcessExpectStapleURIs(entries, &expect_staple_report_uri_map, &output);
-
   NameIDMap pinsets_map;
   ProcessPinsets(pinsets, &pinsets_map, &output);
 
@@ -150,7 +147,6 @@
   for (const auto& entry : entries) {
     std::unique_ptr<TransportSecurityStateTrieEntry> trie_entry(
         new TransportSecurityStateTrieEntry(expect_ct_report_uri_map,
-                                            expect_staple_report_uri_map,
                                             pinsets_map, entry.get()));
     raw_trie_entries.push_back(trie_entry.get());
     trie_entries.push_back(std::move(trie_entry));
@@ -257,38 +253,6 @@
   ReplaceTag("EXPECT_CT_REPORT_URIS", output, tpl);
 }
 
-void PreloadedStateGenerator::ProcessExpectStapleURIs(
-    const TransportSecurityStateEntries& entries,
-    NameIDMap* expect_staple_report_uri_map,
-    std::string* tpl) {
-  std::string output = "{";
-  output.append(kNewLine);
-
-  for (const auto& entry : entries) {
-    const std::string& url = entry->expect_staple_report_uri;
-    if (entry->expect_staple && url.size() &&
-        expect_staple_report_uri_map->find(url) ==
-            expect_staple_report_uri_map->cend()) {
-      output.append(kIndent);
-      output.append(kIndent);
-      output.append("\"" + entry->expect_staple_report_uri + "\",");
-      output.append(kNewLine);
-
-      expect_staple_report_uri_map->insert(NameIDPair(
-          entry->expect_staple_report_uri,
-          static_cast<uint32_t>(expect_staple_report_uri_map->size())));
-    }
-  }
-
-  output.append(kIndent);
-  output.append(kIndent);
-  output.append("nullptr,");
-  output.append(kNewLine);
-
-  output.append("}");
-  ReplaceTag("EXPECT_STAPLE_REPORT_URIS", output, tpl);
-}
-
 void PreloadedStateGenerator::ProcessPinsets(const Pinsets& pinset,
                                              NameIDMap* pinset_map,
                                              std::string* tpl) {
diff --git a/net/tools/transport_security_state_generator/preloaded_state_generator.h b/net/tools/transport_security_state_generator/preloaded_state_generator.h
index e4e2b57..815777a 100644
--- a/net/tools/transport_security_state_generator/preloaded_state_generator.h
+++ b/net/tools/transport_security_state_generator/preloaded_state_generator.h
@@ -38,9 +38,6 @@
   void ProcessExpectCTURIs(const TransportSecurityStateEntries& entries,
                            NameIDMap* expect_ct_report_uri_map,
                            std::string* tpl);
-  void ProcessExpectStapleURIs(const TransportSecurityStateEntries& entries,
-                               NameIDMap* expect_staple_report_uri_map,
-                               std::string* tpl);
   void ProcessPinsets(const Pinsets& pinset,
                       NameIDMap* pinset_map,
                       std::string* tpl);
diff --git a/net/tools/transport_security_state_generator/transport_security_state_entry.cc b/net/tools/transport_security_state_generator/transport_security_state_entry.cc
index b00c737b..a1bbe6ed 100644
--- a/net/tools/transport_security_state_generator/transport_security_state_entry.cc
+++ b/net/tools/transport_security_state_generator/transport_security_state_entry.cc
@@ -16,7 +16,7 @@
 // reduce the overall size of the trie.
 bool IsSimpleEntry(const TransportSecurityStateEntry* entry) {
   return entry->force_https && entry->include_subdomains &&
-         entry->pinset.empty() && !entry->expect_ct && !entry->expect_staple;
+         entry->pinset.empty() && !entry->expect_ct;
 }
 
 }  // namespace
@@ -26,11 +26,9 @@
 
 TransportSecurityStateTrieEntry::TransportSecurityStateTrieEntry(
     const NameIDMap& expect_ct_report_uri_map,
-    const NameIDMap& expect_staple_report_uri_map,
     const NameIDMap& pinsets_map,
     TransportSecurityStateEntry* entry)
     : expect_ct_report_uri_map_(expect_ct_report_uri_map),
-      expect_staple_report_uri_map_(expect_staple_report_uri_map),
       pinsets_map_(pinsets_map),
       entry_(entry) {}
 
@@ -105,31 +103,6 @@
     writer->WriteBit(0);
   }
 
-  if (entry_->expect_staple) {
-    writer->WriteBit(1);
-
-    if (entry_->expect_staple_include_subdomains) {
-      writer->WriteBit(1);
-    } else {
-      writer->WriteBit(0);
-    }
-
-    NameIDMap::const_iterator expect_staple_report_uri_it =
-        expect_staple_report_uri_map_.find(entry_->expect_staple_report_uri);
-    if (expect_staple_report_uri_it == expect_staple_report_uri_map_.cend()) {
-      return false;
-    }
-
-    const uint8_t& expect_staple_report_id =
-        expect_staple_report_uri_it->second;
-    if (expect_staple_report_id > 15) {
-      return false;
-    }
-
-    writer->WriteBits(expect_staple_report_id, 4);
-  } else {
-    writer->WriteBit(0);
-  }
   return true;
 }
 
diff --git a/net/tools/transport_security_state_generator/transport_security_state_entry.h b/net/tools/transport_security_state_generator/transport_security_state_entry.h
index 6c16c3f..59059d88 100644
--- a/net/tools/transport_security_state_generator/transport_security_state_entry.h
+++ b/net/tools/transport_security_state_generator/transport_security_state_entry.h
@@ -36,10 +36,6 @@
 
   bool expect_ct = false;
   std::string expect_ct_report_uri;
-
-  bool expect_staple = false;
-  bool expect_staple_include_subdomains = false;
-  std::string expect_staple_report_uri;
 };
 
 using TransportSecurityStateEntries =
@@ -48,7 +44,6 @@
 class TransportSecurityStateTrieEntry : public huffman_trie::TrieEntry {
  public:
   TransportSecurityStateTrieEntry(const NameIDMap& expect_ct_report_uri_map,
-                                  const NameIDMap& expect_staple_report_uri_map,
                                   const NameIDMap& pinsets_map,
                                   TransportSecurityStateEntry* entry);
   ~TransportSecurityStateTrieEntry() override;
@@ -59,7 +54,6 @@
 
  private:
   const NameIDMap& expect_ct_report_uri_map_;
-  const NameIDMap& expect_staple_report_uri_map_;
   const NameIDMap& pinsets_map_;
   TransportSecurityStateEntry* entry_;
 };
diff --git a/net/tools/transport_security_state_generator/transport_security_state_generator.cc b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
index 40e8f1d..ce3e570 100644
--- a/net/tools/transport_security_state_generator/transport_security_state_generator.cc
+++ b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
@@ -123,16 +123,14 @@
 // Checks for entries which have no effect.
 bool CheckNoopEntries(const TransportSecurityStateEntries& entries) {
   for (const auto& entry : entries) {
-    if (!entry->force_https && entry->pinset.empty() && !entry->expect_ct &&
-        !entry->expect_staple) {
+    if (!entry->force_https && entry->pinset.empty() && !entry->expect_ct) {
       if (entry->hostname == "learn.doubleclick.net") {
         // This entry is deliberately used as an exclusion.
         continue;
       }
 
-      LOG(ERROR)
-          << "Entry for " << entry->hostname
-          << " has no mode, no pins and is not expect-CT or expect-staple";
+      LOG(ERROR) << "Entry for " << entry->hostname
+                 << " has no mode, no pins and is not expect-CT";
       return false;
     }
   }
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 0465bab..ebf6c537 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -6816,9 +6816,6 @@
 
 namespace {
 const char kExpectCTStaticHostname[] = "expect-ct.preloaded.test";
-const char kExpectStapleStaticHostname[] = "expect-staple.preloaded.test";
-const char kExpectStapleReportURI[] =
-    "http://report-uri.preloaded.test/expect-staple";
 const char kHPKPReportUri[] = "https://hpkp-report.test";
 }  // namespace
 
@@ -11273,230 +11270,6 @@
   EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
 }
 
-TEST_F(HTTPSOCSPTest, ExpectStapleReportSentOnMissing) {
-  SetTransportSecurityStateSourceForTesting(&test_default::kHSTSSource);
-
-  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.SetSSLConfig(
-      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
-  https_test_server.ServeFilesFromSourceDirectory(
-      base::FilePath(kTestFilePath));
-  ASSERT_TRUE(https_test_server.Start());
-
-  // Set up a MockCertVerifier to accept the certificate that the server sends,
-  // but not provide any OCSP information.
-  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
-  ASSERT_TRUE(cert);
-  MockCertVerifier cert_verifier;
-  CertVerifyResult verify_result;
-  verify_result.verified_cert = cert;
-  verify_result.is_issued_by_known_root = true;
-  verify_result.ocsp_result.response_status = OCSPVerifyResult::MISSING;
-  cert_verifier.AddResultForCert(cert.get(), verify_result, OK);
-
-  // Catch the Expect-Staple report.
-  TransportSecurityState transport_security_state;
-  MockCertificateReportSender mock_report_sender;
-  transport_security_state.SetReportSender(&mock_report_sender);
-
-  // Use a MockHostResolver (which by default maps all hosts to 127.0.0.1) so
-  // that the request can be sent to a site on the Expect-Staple preload list.
-  MockHostResolver host_resolver;
-  TestNetworkDelegate network_delegate;
-  TestURLRequestContext context(true);
-  context.set_host_resolver(&host_resolver);
-  context.set_transport_security_state(&transport_security_state);
-  context.set_network_delegate(&network_delegate);
-  context.set_cert_verifier(&cert_verifier);
-  context.Init();
-
-  // Now send a request to trigger the violation.
-  TestDelegate d;
-  GURL url = https_test_server.GetURL("/");
-  GURL::Replacements replace_host;
-  replace_host.SetHostStr(kExpectStapleStaticHostname);
-  url = url.ReplaceComponents(replace_host);
-  std::unique_ptr<URLRequest> violating_request(context.CreateRequest(
-      url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
-  violating_request->Start();
-  d.RunUntilComplete();
-
-  // Confirm a report was sent.
-  EXPECT_FALSE(mock_report_sender.latest_report().empty());
-  EXPECT_EQ(GURL(kExpectStapleReportURI),
-            mock_report_sender.latest_report_uri());
-}
-
-// Tests that Expect-Staple reports are not sent for connections on which there
-// is a certificate error.
-TEST_F(HTTPSOCSPTest, ExpectStapleReportNotSentOnMissingWithCertError) {
-  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.SetSSLConfig(
-      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
-  https_test_server.ServeFilesFromSourceDirectory(
-      base::FilePath(kTestFilePath));
-  ASSERT_TRUE(https_test_server.Start());
-
-  // Set up a MockCertVerifier to report an error for the certificate
-  // and indicate that there was no stapled OCSP response.
-  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
-  ASSERT_TRUE(cert);
-  MockCertVerifier cert_verifier;
-  CertVerifyResult verify_result;
-  verify_result.cert_status = CERT_STATUS_DATE_INVALID;
-  verify_result.verified_cert = cert;
-  verify_result.is_issued_by_known_root = true;
-  verify_result.ocsp_result.response_status = OCSPVerifyResult::MISSING;
-  cert_verifier.AddResultForCert(cert.get(), verify_result,
-                                 ERR_CERT_DATE_INVALID);
-
-  // Set up a mock report sender so that the test can check that an
-  // Expect-Staple report is not sent.
-  TransportSecurityState transport_security_state;
-  MockCertificateReportSender mock_report_sender;
-  transport_security_state.SetReportSender(&mock_report_sender);
-
-  TestNetworkDelegate network_delegate;
-  TestURLRequestContext context(true);
-
-  // Force |kExpectStapleStaticHostname| to resolve to |https_test_server|.
-  MockHostResolver host_resolver;
-  context.set_host_resolver(&host_resolver);
-
-  context.set_transport_security_state(&transport_security_state);
-  context.set_network_delegate(&network_delegate);
-  context.set_cert_verifier(&cert_verifier);
-  context.Init();
-
-  // Make a connection to |kExpectStapleStaticHostname|. Because the
-  // |verify_result| used with the |cert_verifier| will indicate a certificate
-  // error, an Expect-Staple report should not be sent.
-  TestDelegate d;
-  GURL url = https_test_server.GetURL("/");
-  GURL::Replacements replace_host;
-  replace_host.SetHostStr(kExpectStapleStaticHostname);
-  url = url.ReplaceComponents(replace_host);
-  std::unique_ptr<URLRequest> violating_request(context.CreateRequest(
-      url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
-  violating_request->Start();
-  d.RunUntilComplete();
-
-  // Confirm a report was not sent.
-  EXPECT_TRUE(mock_report_sender.latest_report().empty());
-  EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
-}
-
-TEST_F(HTTPSOCSPTest, ExpectStapleReportNotSentOnValid) {
-  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.SetSSLConfig(
-      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
-  https_test_server.ServeFilesFromSourceDirectory(
-      base::FilePath(kTestFilePath));
-  ASSERT_TRUE(https_test_server.Start());
-
-  // Set up a MockCertVerifier to accept the certificate that the server sends,
-  // and provide GOOD revocation status.
-  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
-  ASSERT_TRUE(cert);
-  MockCertVerifier cert_verifier;
-  CertVerifyResult verify_result;
-  verify_result.verified_cert = cert;
-  verify_result.is_issued_by_known_root = true;
-  verify_result.ocsp_result.response_status = OCSPVerifyResult::PROVIDED;
-  verify_result.ocsp_result.revocation_status = OCSPRevocationStatus::GOOD;
-  cert_verifier.AddResultForCert(cert.get(), verify_result, OK);
-
-  // Catch the Expect-Staple report.
-  TransportSecurityState transport_security_state;
-  MockCertificateReportSender mock_report_sender;
-  transport_security_state.SetReportSender(&mock_report_sender);
-
-  // Use a MockHostResolver (which by default maps all hosts to 127.0.0.1) so
-  // that the request can be sent to a site on the Expect-Staple preload list.
-  MockHostResolver host_resolver;
-  TestNetworkDelegate network_delegate;
-  TestURLRequestContext context(true);
-  context.set_host_resolver(&host_resolver);
-  context.set_transport_security_state(&transport_security_state);
-  context.set_network_delegate(&network_delegate);
-  context.set_cert_verifier(&cert_verifier);
-  context.Init();
-
-  // This request should not not trigger an Expect-Staple violation.
-  TestDelegate d;
-  GURL url = https_test_server.GetURL("/");
-  GURL::Replacements replace_host;
-  replace_host.SetHostStr(kExpectStapleStaticHostname);
-  url = url.ReplaceComponents(replace_host);
-  std::unique_ptr<URLRequest> ok_request(context.CreateRequest(
-      url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
-  ok_request->Start();
-  d.RunUntilComplete();
-
-  // Check that no report was sent.
-  EXPECT_TRUE(mock_report_sender.latest_report().empty());
-  EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
-}
-
-// Tests that an Expect-Staple report is not sent when OCSP details are not
-// checked on the connection.
-TEST_F(HTTPSOCSPTest, ExpectStapleReportNotSentOnNotChecked) {
-  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.SetSSLConfig(
-      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
-  https_test_server.ServeFilesFromSourceDirectory(
-      base::FilePath(kTestFilePath));
-  ASSERT_TRUE(https_test_server.Start());
-
-  // Set up a MockCertVerifier to accept the certificate that the server sends,
-  // and set |ocsp_result| to indicate that OCSP stapling details were not
-  // checked on the connection.
-  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
-  ASSERT_TRUE(cert);
-  MockCertVerifier cert_verifier;
-  CertVerifyResult verify_result;
-  verify_result.verified_cert = cert;
-  verify_result.is_issued_by_known_root = true;
-  verify_result.ocsp_result.response_status = OCSPVerifyResult::NOT_CHECKED;
-  cert_verifier.AddResultForCert(cert.get(), verify_result, OK);
-
-  // Set up a mock report sender so that the test can check that an
-  // Expect-Staple report is not sent.
-  TransportSecurityState transport_security_state;
-  MockCertificateReportSender mock_report_sender;
-  transport_security_state.SetReportSender(&mock_report_sender);
-
-  TestNetworkDelegate network_delegate;
-  TestURLRequestContext context(true);
-
-  // Force |kExpectStapleStaticHostname| to resolve to |https_test_server|.
-  MockHostResolver host_resolver;
-  context.set_host_resolver(&host_resolver);
-
-  context.set_transport_security_state(&transport_security_state);
-  context.set_network_delegate(&network_delegate);
-  context.set_cert_verifier(&cert_verifier);
-  context.Init();
-
-  // Make a connection to |kExpectStapleStaticHostname|. Because the
-  // |verify_result| used with the |cert_verifier| will indicate that OCSP
-  // stapling details were not checked on the connection, an Expect-Staple
-  // report should not be sent.
-  TestDelegate d;
-  GURL url = https_test_server.GetURL("/");
-  GURL::Replacements replace_host;
-  replace_host.SetHostStr(kExpectStapleStaticHostname);
-  url = url.ReplaceComponents(replace_host);
-  std::unique_ptr<URLRequest> ok_request(context.CreateRequest(
-      url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
-  ok_request->Start();
-  d.RunUntilComplete();
-
-  // Check that no report was sent.
-  EXPECT_TRUE(mock_report_sender.latest_report().empty());
-  EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
-}
-
 static const struct OCSPVerifyTestData {
   std::vector<SpawnedTestServer::SSLOptions::OCSPSingleResponse> ocsp_responses;
   SpawnedTestServer::SSLOptions::OCSPProduced ocsp_produced;
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc
index 6a3497c7..5f86ef3 100644
--- a/net/websockets/websocket_stream.cc
+++ b/net/websockets/websocket_stream.cc
@@ -184,7 +184,7 @@
     failure_message_ = message;
   }
 
-  void Start(std::unique_ptr<base::Timer> timer) {
+  void Start(std::unique_ptr<base::OneShotTimer> timer) {
     DCHECK(timer);
     base::TimeDelta timeout(base::TimeDelta::FromSeconds(
         kHandshakeTimeoutIntervalInSeconds));
@@ -309,7 +309,7 @@
   std::string failure_message_;
 
   // A timer for handshake timeout.
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
 
   // A delegate for On*HandshakeCreated and OnFailure calls.
   std::unique_ptr<WebSocketStreamRequestAPI> api_delegate_;
@@ -489,7 +489,7 @@
       socket_url, url_request_context, origin, site_for_cookies,
       additional_headers, std::move(connect_delegate), std::move(create_helper),
       nullptr);
-  request->Start(std::make_unique<base::Timer>(false, false));
+  request->Start(std::make_unique<base::OneShotTimer>());
   return std::move(request);
 }
 
@@ -503,7 +503,7 @@
     URLRequestContext* url_request_context,
     const NetLogWithSource& net_log,
     std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
-    std::unique_ptr<base::Timer> timer,
+    std::unique_ptr<base::OneShotTimer> timer,
     std::unique_ptr<WebSocketStreamRequestAPI> api_delegate) {
   auto request = std::make_unique<WebSocketStreamRequestImpl>(
       socket_url, url_request_context, origin, site_for_cookies,
diff --git a/net/websockets/websocket_stream.h b/net/websockets/websocket_stream.h
index b39df5c..52054170 100644
--- a/net/websockets/websocket_stream.h
+++ b/net/websockets/websocket_stream.h
@@ -23,7 +23,7 @@
 class GURL;
 
 namespace base {
-class Timer;
+class OneShotTimer;
 }
 
 namespace url {
@@ -173,7 +173,7 @@
       URLRequestContext* url_request_context,
       const NetLogWithSource& net_log,
       std::unique_ptr<ConnectDelegate> connect_delegate,
-      std::unique_ptr<base::Timer> timer,
+      std::unique_ptr<base::OneShotTimer> timer,
       std::unique_ptr<WebSocketStreamRequestAPI> api_delegate);
 
   // Derived classes must make sure Close() is called when the stream is not
diff --git a/net/websockets/websocket_stream_create_test_base.cc b/net/websockets/websocket_stream_create_test_base.cc
index 9f197bc..10fcc9a 100644
--- a/net/websockets/websocket_stream_create_test_base.cc
+++ b/net/websockets/websocket_stream_create_test_base.cc
@@ -98,7 +98,7 @@
     const url::Origin& origin,
     const GURL& site_for_cookies,
     const HttpRequestHeaders& additional_headers,
-    std::unique_ptr<base::Timer> timer) {
+    std::unique_ptr<base::OneShotTimer> timer) {
   auto connect_delegate = std::make_unique<TestConnectDelegate>(
       this, connect_run_loop_.QuitClosure());
   auto create_helper = std::make_unique<WebSocketHandshakeStreamCreateHelper>(
@@ -108,7 +108,7 @@
       socket_url, std::move(create_helper), origin, site_for_cookies,
       additional_headers, url_request_context_host_.GetURLRequestContext(),
       NetLogWithSource(), std::move(connect_delegate),
-      timer ? std::move(timer) : std::make_unique<base::Timer>(false, false),
+      timer ? std::move(timer) : std::make_unique<base::OneShotTimer>(),
       std::move(api_delegate));
 }
 
diff --git a/net/websockets/websocket_stream_create_test_base.h b/net/websockets/websocket_stream_create_test_base.h
index c4ed5be..228789c 100644
--- a/net/websockets/websocket_stream_create_test_base.h
+++ b/net/websockets/websocket_stream_create_test_base.h
@@ -45,7 +45,7 @@
                               const url::Origin& origin,
                               const GURL& site_for_cookies,
                               const HttpRequestHeaders& additional_headers,
-                              std::unique_ptr<base::Timer> timer);
+                              std::unique_ptr<base::OneShotTimer> timer);
 
   static std::vector<HeaderKeyValuePair> RequestHeadersToVector(
       const HttpRequestHeaders& headers);
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc
index 78e6aa2..0a011407 100644
--- a/net/websockets/websocket_stream_test.cc
+++ b/net/websockets/websocket_stream_test.cc
@@ -120,7 +120,7 @@
     url_request_context_host_.AddSSLSocketDataProvider(std::move(ssl_data));
   }
 
-  void SetTimer(std::unique_ptr<base::Timer> timer) {
+  void SetTimer(std::unique_ptr<base::OneShotTimer> timer) {
     timer_ = std::move(timer);
   }
 
@@ -372,7 +372,7 @@
   const HandshakeStreamType stream_type_;
 
  private:
-  std::unique_ptr<base::Timer> timer_;
+  std::unique_ptr<base::OneShotTimer> timer_;
   std::string additional_data_;
   const char* http2_response_status_;
   bool reset_websocket_http2_stream_;
diff --git a/services/network/test/test_utils.cc b/services/network/test/test_utils.cc
index 0512175..1021ffe 100644
--- a/services/network/test/test_utils.cc
+++ b/services/network/test/test_utils.cc
@@ -8,15 +8,15 @@
 
 namespace network {
 
-std::string GetUploadData(const network::ResourceRequest& request) {

-  auto body = request.request_body;

-  if (!body)

-    return std::string();

-

-  CHECK_EQ(1u, body->elements()->size());

-  const auto& element = body->elements()->at(0);

-  CHECK_EQ(network::DataElement::TYPE_BYTES, element.type());

-  return std::string(element.bytes(), element.length());

+std::string GetUploadData(const network::ResourceRequest& request) {
+  auto body = request.request_body;
+  if (!body)
+    return std::string();
+
+  CHECK_EQ(1u, body->elements()->size());
+  const auto& element = body->elements()->at(0);
+  CHECK_EQ(network::DataElement::TYPE_BYTES, element.type());
+  return std::string(element.bytes(), element.length());
 }
 
 }  // namespace network
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index d28f6ba4..1384d6b 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -31,8 +31,8 @@
 crbug.com/854840 fast/table/backgr_border-table-quirks.html [ Failure ]
 
 # An DCHECK related to HandleOverflow and rewinding? Details in bug.
-crbug.com/860516 http/tests/devtools/console/console-smart-enter.js [ Crash ]
 crbug.com/860516 http/tests/devtools/console/console-correct-suggestions.js [ Crash ]
+crbug.com/860516 http/tests/devtools/console/console-smart-enter.js [ Crash Pass ]
 
 # Fails due to incorrect offset mapping using cache.
 crbug.com/636993 external/wpt/css/css-text/word-break/word-break-break-all-005.html [ Failure ]
@@ -43,7 +43,6 @@
 crbug.com/636993 external/wpt/css/css-text-decor/text-decoration-color.html [ Failure ]
 
 # rightsizing-grid.html is truly flaky, show flakiness on reload
-crbug.com/591099 svg/wicd/rightsizing-grid.html [ Pass Failure ]
 
 # New passes
 crbug.com/774229 editing/pasteboard/copy-paste-white-space.html [ Pass ]
@@ -85,7 +84,6 @@
 crbug.com/591099 css2.1/t1202-counters-04-b.html [ Failure ]
 crbug.com/591099 css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change.html [ Failure ]
 crbug.com/591099 css3/flexbox/bug646288.html [ Failure ]
-crbug.com/591099 css3/flexbox/bug669714.html [ Failure ]
 crbug.com/591099 css3/flexbox/flex-flow-margins-auto-size.html [ Failure ]
 crbug.com/591099 css3/flexbox/intrinsic-width-orthogonal-writing-mode.html [ Failure ]
 crbug.com/591099 css3/flexbox/line-wrapping.html [ Failure ]
@@ -272,7 +270,7 @@
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-item-vert-001b.html [ Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-definite-sizes-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-definite-sizes-004.html [ Failure ]
-crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-003v.html [ Pass ]
+crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-003v.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/ib-split/emptyspan-1.html [ Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/ib-split/emptyspan-4.html [ Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/ib-split/remove-from-split-inline-6.html [ Pass ]
@@ -303,7 +301,7 @@
 crbug.com/591099 external/wpt/editing/run/misc.html [ Pass ]
 crbug.com/591099 external/wpt/editing/run/multitest.html [ Pass ]
 crbug.com/591099 external/wpt/editing/run/strikethrough.html [ Pass ]
-crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Pass ]
+crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ]
 crbug.com/591099 external/wpt/html-media-capture/capture_audio_cancel-manual.html [ Failure ]
 crbug.com/591099 external/wpt/html-media-capture/capture_image_cancel-manual.html [ Failure ]
 crbug.com/591099 external/wpt/html-media-capture/capture_video_cancel-manual.html [ Failure ]
@@ -317,13 +315,13 @@
 crbug.com/591099 external/wpt/payment-request/payment-disabled-by-feature-policy.https.sub.html [ Pass ]
 crbug.com/591099 external/wpt/pointerevents/pointerevent_click_during_capture-manual.html [ Crash Timeout ]
 crbug.com/591099 external/wpt/quirks/line-height-calculation.html [ Failure ]
-crbug.com/591099 external/wpt/requestidlecallback/basic.html [ Pass ]
+crbug.com/591099 external/wpt/requestidlecallback/basic.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/requestidlecallback/callback-exception.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/callback-idle-periods.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/callback-iframe.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/callback-invoked.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/cancel-invoked.html [ Pass ]
-crbug.com/591099 external/wpt/requestidlecallback/idlharness.html [ Pass ]
+crbug.com/591099 external/wpt/requestidlecallback/idlharness.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html [ Pass ]
 crbug.com/591099 external/wpt/webrtc/interfaces.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/websockets/opening-handshake/003-sets-origin.worker.html [ Pass ]
@@ -482,7 +480,7 @@
 crbug.com/591099 fast/table/fixed-table-layout/table-with-percent-width.html [ Failure ]
 crbug.com/591099 fast/table/height-percent-test-vertical.html [ Failure ]
 crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure Pass ]
-crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure ]
+crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure Pass ]
 crbug.com/591099 fast/table/percent-height-replaced-content-in-cell.html [ Failure ]
 crbug.com/858998 fast/table/table-continuation-outline-paint-crash.html [ Failure ]
 crbug.com/591099 fast/table/table-display-types-vertical.html [ Failure ]
@@ -497,11 +495,11 @@
 crbug.com/796943 fast/text/international/shape-across-elements-simple.html [ Pass ]
 crbug.com/591099 fast/text/international/text-combine-image-test.html [ Failure ]
 crbug.com/591099 fast/text/orientation-sideways.html [ Failure ]
+crbug.com/591099 fast/text/selection/atsui-partial-selection.html [ Failure Pass ]
 crbug.com/591099 fast/text/selection/emphasis.html [ Failure ]
 crbug.com/591099 fast/text/text-combine-first-line-crash.html [ Crash ]
 crbug.com/591099 fast/text/unicode-fallback-font.html [ Failure ]
 crbug.com/591099 fast/text/whitespace/018.html [ Failure ]
-crbug.com/591099 fast/text/whitespace/inline-whitespace-wrapping-3.html [ Failure ]
 crbug.com/591099 fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ]
 crbug.com/714962 fast/writing-mode/background-vertical-lr.html [ Failure ]
 crbug.com/591099 fast/writing-mode/background-vertical-rl.html [ Failure ]
@@ -528,9 +526,10 @@
 crbug.com/591099 http/tests/csspaint/invalidation-background-image.html [ Timeout ]
 crbug.com/591099 http/tests/csspaint/invalidation-border-image.html [ Timeout ]
 crbug.com/591099 http/tests/csspaint/invalidation-content-image.html [ Timeout ]
-crbug.com/591099 http/tests/devtools/console-resource-errors.js [ Pass ]
+crbug.com/591099 http/tests/devtools/console-resource-errors.js [ Failure Pass ]
 crbug.com/591099 http/tests/devtools/console/console-search.js [ Timeout ]
 crbug.com/591099 http/tests/devtools/persistence/persistence-merge-editor-tabs.js [ Failure ]
+crbug.com/591099 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Failure Pass ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-grouped-invalidations.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.js [ Timeout ]
@@ -554,17 +553,17 @@
 crbug.com/591099 http/tests/permissions/test-api-surface.html [ Pass ]
 crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ]
 crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.https.html [ Crash Failure Pass ]
-crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Pass ]
+crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Crash ]
 crbug.com/591099 http/tests/security/xssAuditor/block-does-not-leak-location.html [ Failure ]
 crbug.com/591099 http/tests/websocket/invalid-subprotocol-characters.html [ Pass Timeout ]
-crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Pass ]
+crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Crash Pass ]
 crbug.com/714962 images/color-profile-background-clip-text.html [ Failure ]
 crbug.com/591099 images/color-profile-image-filter-all.html [ Failure ]
 crbug.com/714962 inspector-protocol/css/css-get-platform-fonts.js [ Failure ]
 crbug.com/714962 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport.js [ Failure ]
 crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot.js [ Failure ]
 crbug.com/714962 inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.js [ Failure ]
-crbug.com/591099 inspector-protocol/timeline/page-frames.js [ Pass ]
+crbug.com/591099 inspector-protocol/timeline/page-frames.js [ Failure Pass ]
 crbug.com/714962 intersection-observer/text-target.html [ Failure ]
 crbug.com/591099 paint/inline/focus-ring-under-absolute-with-relative-continuation.html [ Failure ]
 crbug.com/591099 paint/invalidation/background/backgroundSizeRepaint.html [ Failure ]
@@ -589,11 +588,7 @@
 crbug.com/591099 paint/invalidation/compositing/iframe-inside-squashed-layer.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/remove-squashed-layer-plus-move.html [ Failure ]
 crbug.com/714962 paint/invalidation/compositing/repaint-via-layout-offset.html [ Failure ]
-crbug.com/591099 paint/invalidation/compositing/should-invoke-deferred-compositing.html [ Failure ]
-crbug.com/591099 paint/invalidation/compositing/should-not-clip-composited-overflow-scrolling-layer.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ Failure ]
-crbug.com/591099 paint/invalidation/compositing/text-match-highlight.html [ Failure ]
-crbug.com/591099 paint/invalidation/compositing/updating-scrolling-container-and-content.html [ Failure ]
 crbug.com/591099 paint/invalidation/css-grid-layout/grid-element-change-columns-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/css-grid-layout/grid-element-change-rows-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/css-grid-layout/grid-item-change-column-repaint.html [ Failure ]
@@ -628,8 +623,6 @@
 crbug.com/591099 paint/invalidation/inline-block-resize.html [ Failure ]
 crbug.com/591099 paint/invalidation/inline-color-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/inline-reflow.html [ Failure ]
-crbug.com/591099 paint/invalidation/insert-frame.html [ Failure ]
-crbug.com/591099 paint/invalidation/invalidation-after-opacity-change-subtree.html [ Failure ]
 crbug.com/591099 paint/invalidation/invisible-objects.html [ Failure ]
 crbug.com/591099 paint/invalidation/lines-with-layout-delta.html [ Failure ]
 crbug.com/591099 paint/invalidation/list-marker-2.html [ Failure ]
@@ -638,7 +631,6 @@
 crbug.com/824918 paint/invalidation/multicol/multicol-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/multicol/multicol-resize-with-rule.html [ Failure ]
 crbug.com/824918 paint/invalidation/multicol/multicol-with-text.html [ Failure ]
-crbug.com/591099 paint/invalidation/non-text-link-invalidation-optimization.html [ Failure ]
 crbug.com/591099 paint/invalidation/offset-change-wrong-invalidation-with-float.html [ Failure ]
 crbug.com/591099 paint/invalidation/outline/focus-continuations.html [ Failure ]
 crbug.com/591099 paint/invalidation/outline/focus-enable-continuations.html [ Failure ]
@@ -690,15 +682,10 @@
 crbug.com/591099 paint/invalidation/remove-inline-layer-after-layout.html [ Failure ]
 crbug.com/591099 paint/invalidation/repaint-across-writing-mode-boundary.html [ Failure ]
 crbug.com/591099 paint/invalidation/repaint-descandant-on-ancestor-layer-move.html [ Failure ]
-crbug.com/591099 paint/invalidation/scroll/invalidate-after-composited-scroll-of-window.html [ Failure ]
-crbug.com/591099 paint/invalidation/scroll/line-in-scrolled-clipped-block.html [ Failure ]
-crbug.com/591099 paint/invalidation/scroll/resize-scrollable-iframe.html [ Failure ]
-crbug.com/714962 paint/invalidation/selection/text-selection-rect-in-overflow-2.html [ Failure ]
 crbug.com/591099 paint/invalidation/stacked-diacritics.html [ Failure ]
 crbug.com/591099 paint/invalidation/stacking-context-lost.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/add-background-property-on-root.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/add-outline-property-on-root.html [ Failure ]
-crbug.com/591099 paint/invalidation/svg/animated-path-inside-transformed-html.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/overflow-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/remove-background-property-on-root.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/remove-outline-property-on-root.html [ Failure ]
@@ -709,7 +696,6 @@
 crbug.com/728378 paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-cell-sl-border-color.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/collapsed-border-cell-resize.html [ Failure ]
-crbug.com/591099 paint/invalidation/table/composited-table-row.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/repaint-table-row-in-composited-document.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/replace-col.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/resize-table-repaint-percent-size-cell.html [ Failure ]
@@ -724,7 +710,6 @@
 crbug.com/591099 paint/invalidation/table/table-shrink-row-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/table-two-pass-layout-overpaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/text-append-dirty-lines.html [ Failure ]
-crbug.com/591099 paint/invalidation/text-match-document-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/change-transform.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/transform-inline-layered-child.html [ Failure ]
 crbug.com/591099 paint/invalidation/transform/transform-layout-repaint.html [ Failure ]
@@ -742,11 +727,11 @@
 crbug.com/591099 printing/iframe-svg-in-object-print.html [ Failure ]
 crbug.com/591099 scrollbars/auto-scrollbar-fit-content.html [ Failure ]
 crbug.com/591099 shapedetection/detection-HTMLVideoElement.html [ Pass ]
-crbug.com/591099 storage/indexeddb/cursor-continue-validity.html [ Pass Timeout ]
+crbug.com/591099 storage/indexeddb/cursor-continue-validity.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/index-cursor.html [ Pass Timeout ]
 crbug.com/591099 storage/indexeddb/mozilla/indexes.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Timeout ]
-crbug.com/591099 storage/indexeddb/objectstore-cursor.html [ Pass Timeout ]
+crbug.com/591099 storage/indexeddb/objectstore-cursor.html [ Pass ]
 crbug.com/591099 storage/indexeddb/objectstore-keycursor.html [ Pass Timeout ]
 crbug.com/591099 svg/as-border-image/svg-as-border-image-2.html [ Failure ]
 crbug.com/591099 svg/as-border-image/svg-as-border-image.html [ Failure ]
@@ -780,13 +765,12 @@
 crbug.com/591099 virtual/exotic-color-space/ [ Skip ]
 crbug.com/591099 virtual/feature-policy-vibrate/ [ Skip ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ]
-crbug.com/591099 virtual/gpu/fast/canvas/shadow-huge-blur.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/ [ Skip ]
 crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ]
-crbug.com/591099 virtual/mojo-blob-urls/external/wpt/FileAPI/url/sandboxed-iframe.html [ Pass ]
+crbug.com/591099 virtual/mojo-blob-urls/external/wpt/FileAPI/url/sandboxed-iframe.html [ Pass Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/background-tab-on-submit-ctrl-click.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/background-tab-on-submit-synthesized-ctrl-click.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/select-element.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/select-element.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/mainthread-touchpad-fling-latching.html [ Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ]
@@ -803,12 +787,16 @@
 crbug.com/591099 virtual/spv2/paint/invalidation/box/margin.html [ Failure Pass ]
 crbug.com/591099 virtual/stable/ [ Skip ]
 crbug.com/591099 virtual/threaded/ [ Skip ]
-crbug.com/591099 virtual/user-activation-v2/fast/dom/Window/window-lookup-precedence.html [ Failure ]
+crbug.com/591099 virtual/user-activation-v2/fast/dom/Window/window-lookup-precedence.html [ Failure Pass ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/background-tab-on-submit-ctrl-click.html [ Failure ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/background-tab-on-submit-synthesized-ctrl-click.html [ Failure ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/mouse-cursor.html [ Failure ]
-crbug.com/591099 virtual/user-activation-v2/fast/events/select-element.html [ Failure ]
+crbug.com/591099 virtual/user-activation-v2/fast/events/select-element.html [ Failure Pass ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
 crbug.com/591099 virtual/user-activation-v2/fullscreen/full-screen-with-flex-item.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/picture-in-picture/controls/picture-in-picture-button.html [ Pass ]
+crbug.com/591099 virtual/video-surface-layer/media/picture-in-picture/controls/picture-in-picture-video-with-audio-only-button.html [ Pass ]
 crbug.com/591099 virtual/video-surface-layer/media/picture-in-picture/picture-in-picture-enabled.html [ Pass ]
+crbug.com/591099 virtual/video-surface-layer/media/picture-in-picture/picture-in-picture-interstitial.html [ Pass ]
+crbug.com/591099 virtual/video-surface-layer/media/video-display-toggle.html [ Failure ]
 crbug.com/591099 virtual/wheelscrolllatching/ [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index cbcef54..0615515 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -397,3 +397,5 @@
 # calls and waits for events in each of them. Even on a release Linux build it
 # can take almost 6 seconds to run, and it often times out on the Mac bots.
 crbug.com/833215 external/wpt/accelerometer/Accelerometer.https.html [ Slow ]
+
+crbug.com/861670 [ Linux Mac ] virtual/gpu/fast/canvas/canvas-blending-image-over-gradient.html [ Slow ] 
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 7ea21d3..1e22593 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2730,6 +2730,12 @@
 crbug.com/849859 external/wpt/web-animations/timing-model/animations/pausing-an-animation.html [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/svg/shapes/ellipse-05.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/shapes/ellipse-06.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/shapes/ellipse-08.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/shapes/ellipse-03.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/shapes/ellipse-07.svg [ Failure ]
+crbug.com/626703 external/wpt/svg/shapes/ellipse-02.svg [ Failure ]
 crbug.com/626703 external/wpt/svg/rendering/order/z-index.svg [ Failure ]
 crbug.com/626703 external/wpt/websockets/Create-on-worker-shutdown.any.html [ Timeout ]
 crbug.com/626703 external/wpt/web-animations/timing-model/timelines/update-and-send-events.html [ Timeout ]
@@ -4665,3 +4671,7 @@
 crbug.com/831796 virtual/user-activation-v2/fast/events/autoscroll-in-textfield.html [ Failure Pass ]
 
 crbug.com/860731 fast/scroll-snap/animate-fling-to-snap-points.html [ Failure Pass ]
+
+crbug.com/861544 [ Win ] fast/text/selection/khmer-selection.html [ Failure Pass ]
+
+crbug.com/861682 [ Win ] external/wpt/css/mediaqueries/device-aspect-ratio-003.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
index 258278a2..ff5333f 100644
--- a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
+++ b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
@@ -175,15 +175,6 @@
             AXRole: AXCell "Cell2"
                 AXRole: AXStaticText "Cell2"
                     AXRole: AXInlineTextBox "Cell2"
-        AXRole: AXColumn
-            AXRole: AXCell "Cell1"
-                AXRole: AXStaticText "Cell1"
-                    AXRole: AXInlineTextBox "Cell1"
-        AXRole: AXColumn
-            AXRole: AXCell "Cell2"
-                AXRole: AXStaticText "Cell2"
-                    AXRole: AXInlineTextBox "Cell2"
-        AXRole: AXTableHeaderContainer
     AXRole: AXFigure "Fig1. - Blue Box"
         AXRole: AXImage "blue"
         AXRole: AXFigcaption
diff --git a/third_party/WebKit/LayoutTests/accessibility/presentation-owned-elements-expected.txt b/third_party/WebKit/LayoutTests/accessibility/presentation-owned-elements-expected.txt
index 0651f3c..45f2ba6 100644
--- a/third_party/WebKit/LayoutTests/accessibility/presentation-owned-elements-expected.txt
+++ b/third_party/WebKit/LayoutTests/accessibility/presentation-owned-elements-expected.txt
@@ -66,14 +66,6 @@
             AXRole: AXCell "Normal td"
                 AXRole: AXStaticText "Normal td"
                     AXRole: AXInlineTextBox "Normal td"
-        AXRole: AXColumn
-            AXRole: AXGenericContainer
-                AXRole: AXStaticText "Presentation th"
-                    AXRole: AXInlineTextBox "Presentation th"
-            AXRole: AXCell "Normal td"
-                AXRole: AXStaticText "Normal td"
-                    AXRole: AXInlineTextBox "Normal td"
-        AXRole: AXTableHeaderContainer
     AXRole: AXGenericContainer
         AXRole: AXStaticText "The row for "Explicit th" has a row role even if table has a presentation role because it has an explicit role."
             AXRole: AXInlineTextBox "The row for "Explicit th" has a row role even if table has a presentation role because it has an explicit role."
diff --git a/third_party/WebKit/LayoutTests/accessibility/table-caption-expected.txt b/third_party/WebKit/LayoutTests/accessibility/table-caption-expected.txt
index 7eb1dce0..4020b794 100644
--- a/third_party/WebKit/LayoutTests/accessibility/table-caption-expected.txt
+++ b/third_party/WebKit/LayoutTests/accessibility/table-caption-expected.txt
@@ -3,7 +3,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS table.childrenCount is 5
+PASS table.childrenCount is 2
 PASS captionText is 'TableCaption'
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/accessibility/table-caption.html b/third_party/WebKit/LayoutTests/accessibility/table-caption.html
index a75ffe4d..28caaff 100644
--- a/third_party/WebKit/LayoutTests/accessibility/table-caption.html
+++ b/third_party/WebKit/LayoutTests/accessibility/table-caption.html
@@ -20,7 +20,7 @@
 
     if (window.accessibilityController) {
         var table = accessibilityController.accessibleElementById("table");
-        shouldBe("table.childrenCount", "5");
+        shouldBe("table.childrenCount", "2");
         window.captionText = table.childAtIndex(0).childAtIndex(0).name;
         shouldBe("captionText", "'TableCaption'");
         // Clear the HTML for cleaner results.
diff --git a/third_party/WebKit/LayoutTests/accessibility/table-header-expected.txt b/third_party/WebKit/LayoutTests/accessibility/table-header-expected.txt
deleted file mode 100644
index 5d900b9..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/table-header-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This tests that table headers are exposed for accessibility.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS table.rowCount is 2
-PASS tableheader.isValid is true
-PASS tableheader.childrenCount is 2
-PASS firstHeaderText is 'header 1'
-PASS secondHeaderText is 'header 2'
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/table-header.html b/third_party/WebKit/LayoutTests/accessibility/table-header.html
deleted file mode 100644
index 0297a70..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/table-header.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-</head>
-<body id="body">
-
-<div id="content">
-
-<table id="table" border=1>
-  <tr><th>header 1</th><th>header 2</th></tr>
-  <tr><td>foo</td><td>bar</td></tr>
-</table>
-
-</div>
-
-<script>
-
-    description("This tests that table headers are exposed for accessibility.");
-
-    if (window.accessibilityController) {
-        var table = accessibilityController.accessibleElementById("table");
-        shouldBe("table.rowCount", "2");
-        var tableheader = table.tableHeader();
-        shouldBeTrue("tableheader.isValid");
-        shouldBe("tableheader.childrenCount", "2");
-        window.firstHeaderText = tableheader.childAtIndex(0).childAtIndex(0).name;
-        shouldBe("firstHeaderText", "'header 1'");
-        window.secondHeaderText = tableheader.childAtIndex(1).childAtIndex(0).name;
-        shouldBe("secondHeaderText", "'header 2'");
-
-        // Clear the HTML for cleaner results.
-        document.getElementById("content").innerHTML = "";
-    }
-
-
-</script>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins-expected.html b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins-expected.html
index 3c5ef2a..2a87bb5 100644
--- a/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins-expected.html
+++ b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins-expected.html
@@ -1,15 +1,15 @@
-<!DOCTYPE html>

-<style>

-  .bordered {

-	  margin: auto;

-	  margin-top: -40px;

-	  width: 260px;

-	  height: 260px;

-	  background-color: red;

-	  background-image: linear-gradient(green, green);

-	  border: 40px solid green;

-  }

-</style>

-<div id="spacer" style="height: 100px; width: 100px;"></div>

-<!-- Test should show no red background color around the gradient. -->

-<div class="bordered"></div>

+<!DOCTYPE html>
+<style>
+  .bordered {
+	  margin: auto;
+	  margin-top: -40px;
+	  width: 260px;
+	  height: 260px;
+	  background-color: red;
+	  background-image: linear-gradient(green, green);
+	  border: 40px solid green;
+  }
+</style>
+<div id="spacer" style="height: 100px; width: 100px;"></div>
+<!-- Test should show no red background color around the gradient. -->
+<div class="bordered"></div>
diff --git a/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins.html b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins.html
index 9b6fb5be..3b5e6cf4 100644
--- a/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins.html
+++ b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins.html
@@ -1,15 +1,15 @@
-<!DOCTYPE html>

-<style>

-  .bordered {

-	  margin: auto;

-	  width: 200px;

-	  height: 200px;

-	  background-color: red;

-	  background-image: linear-gradient(green, green);

-	  border: 30px solid red;

-	  border-image: repeat stretch 40 / 40px / 40px linear-gradient(green, green);

-  }

-</style>

-<div id="spacer" style="height: 100px; width: 100px;"></div>

-<!-- Test should show no red background color around the gradient. -->

-<div class="bordered"></div>

+<!DOCTYPE html>
+<style>
+  .bordered {
+	  margin: auto;
+	  width: 200px;
+	  height: 200px;
+	  background-color: red;
+	  background-image: linear-gradient(green, green);
+	  border: 30px solid red;
+	  border-image: repeat stretch 40 / 40px / 40px linear-gradient(green, green);
+  }
+</style>
+<div id="spacer" style="height: 100px; width: 100px;"></div>
+<!-- Test should show no red background color around the gradient. -->
+<div class="bordered"></div>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index ff0f129..7bb8069 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -93971,6 +93971,42 @@
      {}
     ]
    ],
+   "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html": [
+    [
+     "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html",
+     [
+      [
+       "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html": [
+    [
+     "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html",
+     [
+      [
+       "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html": [
+    [
+     "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html",
+     [
+      [
+       "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml": [
     [
      "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml",
@@ -95787,6 +95823,102 @@
      {}
     ]
    ],
+   "svg/shapes/ellipse-01.svg": [
+    [
+     "/svg/shapes/ellipse-01.svg",
+     [
+      [
+       "/svg/shapes/ellipse-01-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-02.svg": [
+    [
+     "/svg/shapes/ellipse-02.svg",
+     [
+      [
+       "/svg/shapes/ellipse-02-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-03.svg": [
+    [
+     "/svg/shapes/ellipse-03.svg",
+     [
+      [
+       "/svg/shapes/ellipse-03-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-04.svg": [
+    [
+     "/svg/shapes/ellipse-04.svg",
+     [
+      [
+       "/svg/shapes/ellipse-04-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-05.svg": [
+    [
+     "/svg/shapes/ellipse-05.svg",
+     [
+      [
+       "/svg/shapes/ellipse-02-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-06.svg": [
+    [
+     "/svg/shapes/ellipse-06.svg",
+     [
+      [
+       "/svg/shapes/ellipse-03-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-07.svg": [
+    [
+     "/svg/shapes/ellipse-07.svg",
+     [
+      [
+       "/svg/shapes/ellipse-07-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-08.svg": [
+    [
+     "/svg/shapes/ellipse-08.svg",
+     [
+      [
+       "/svg/shapes/ellipse-07-ref.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "svg/shapes/line-dasharray.svg": [
     [
      "/svg/shapes/line-dasharray.svg",
@@ -102100,16 +102232,6 @@
      {}
     ]
    ],
-   "accelerometer/Accelerometer_onerror-manual.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "accelerometer/META.yml": [
     [
      {}
@@ -104630,6 +104752,16 @@
      {}
     ]
    ],
+   "content-security-policy/securitypolicyviolation/blockeduri-eval-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "content-security-policy/securitypolicyviolation/blockeduri-inline-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html.headers": [
     [
      {}
@@ -144040,11 +144172,6 @@
      {}
     ]
    ],
-   "geolocation-sensor/GeolocationSensor_onerror-manual.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "geolocation-sensor/GeolocationSensor_read.https-expected.txt": [
     [
      {}
@@ -144110,11 +144237,6 @@
      {}
     ]
    ],
-   "gyroscope/Gyroscope.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "gyroscope/META.yml": [
     [
      {}
@@ -152505,6 +152627,16 @@
      {}
     ]
    ],
+   "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html": [
+    [
+     {}
+    ]
+   ],
    "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml": [
     [
      {}
@@ -158535,11 +158667,6 @@
      {}
     ]
    ],
-   "magnetometer/Magnetometer_onerror-manual.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "magnetometer/OWNERS": [
     [
      {}
@@ -160180,11 +160307,6 @@
      {}
     ]
    ],
-   "orientation-sensor/AbsoluteOrientationSensor.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "orientation-sensor/META.yml": [
     [
      {}
@@ -160215,11 +160337,6 @@
      {}
     ]
    ],
-   "orientation-sensor/RelativeOrientationSensor.https-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "orientation-sensor/orientation-sensor-tests.js": [
     [
      {}
@@ -168315,6 +168432,31 @@
      {}
     ]
    ],
+   "svg/shapes/ellipse-01-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-02-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-03-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-04-ref.svg": [
+    [
+     {}
+    ]
+   ],
+   "svg/shapes/ellipse-07-ref.svg": [
+    [
+     {}
+    ]
+   ],
    "svg/shapes/line-dasharray-ref.svg": [
     [
      {}
@@ -169345,6 +169487,11 @@
      {}
     ]
    ],
+   "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt": [
     [
      {}
@@ -250794,6 +250941,12 @@
      {}
     ]
    ],
+   "svg/shapes/rx-ry-not-inherited.svg": [
+    [
+     "/svg/shapes/rx-ry-not-inherited.svg",
+     {}
+    ]
+   ],
    "svg/struct/UnknownElement/interface.svg": [
     [
      "/svg/struct/UnknownElement/interface.svg",
@@ -272902,7 +273055,7 @@
    "testharness"
   ],
   "accelerometer/Accelerometer.https-expected.txt": [
-   "eb8f690a2264e1f0a9171453b0d343a701ecd0a1",
+   "4b869d46c5fbfbd30392db7e51398b649db494f6",
    "support"
   ],
   "accelerometer/Accelerometer.https.html": [
@@ -272913,18 +273066,10 @@
    "82be1b9a5c6e75291fdc1aabe230af28e22823a8",
    "testharness"
   ],
-  "accelerometer/Accelerometer_onerror-manual.https-expected.txt": [
-   "5655b4361914f873488e5a79f45f0fee1e3cf5d1",
-   "support"
-  ],
   "accelerometer/Accelerometer_onerror-manual.https.html": [
    "f6a624b70b401c0802c5f189c89e85d63fe58795",
    "manual"
   ],
-  "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https-expected.txt": [
-   "30da7c7a75ed1896c2f92c266d7c463c8294fe39",
-   "support"
-  ],
   "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https.html": [
    "30e8588ff49a1d526d65aac89bc80f4782715914",
    "manual"
@@ -277173,12 +277318,20 @@
    "30daa6c42351724a09ba60028ce2558d688c3555",
    "testharness"
   ],
+  "content-security-policy/securitypolicyviolation/blockeduri-eval-expected.txt": [
+   "5d864ee91e4389f6dbbaca3acca72bf7845b0c18",
+   "support"
+  ],
   "content-security-policy/securitypolicyviolation/blockeduri-eval.html": [
-   "01d4ce834d175d13eb0d9c80bbe4a7be614d687f",
+   "26a5ce6bed6fba88412ffbd7a0aa0c04c4b9c86d",
    "testharness"
   ],
+  "content-security-policy/securitypolicyviolation/blockeduri-inline-expected.txt": [
+   "12c3210d1ac1ccc97d731616d683cf59ed0c8c7d",
+   "support"
+  ],
   "content-security-policy/securitypolicyviolation/blockeduri-inline.html": [
-   "8e7326101e28ec65c6c834f7711b261917f93218",
+   "ff8d1c26701d15164bcb549d42937825e1f0edd0",
    "testharness"
   ],
   "content-security-policy/securitypolicyviolation/idl.html": [
@@ -277250,7 +277403,7 @@
    "support"
   ],
   "content-security-policy/securitypolicyviolation/targeting.html": [
-   "36ec8dd9ef0bd1be3615913015d857aa1a7c9e97",
+   "44a9c8d566dd2532d09972df3b5745db671ed8dc",
    "testharness"
   ],
   "content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html": [
@@ -355366,7 +355519,7 @@
    "support"
   ],
   "generic-sensor/generic-sensor-tests.js": [
-   "b950811d99ac923c300a45967889a57ec8bf2204",
+   "5179cfb6bf7d65930900602e490c479297aa6979",
    "support"
   ],
   "generic-sensor/idlharness.https.html": [
@@ -355521,10 +355674,6 @@
    "58fd65d3a72e6734392381fe225e3fbd7007fc06",
    "testharness"
   ],
-  "geolocation-sensor/GeolocationSensor_onerror-manual.https-expected.txt": [
-   "887c07ca1096158e88bc6a9d2843a51fd5e4f29e",
-   "support"
-  ],
   "geolocation-sensor/GeolocationSensor_onerror-manual.https.html": [
    "35fcdb034664c1e69a44ed1c8b1df2c43d3688bd",
    "manual"
@@ -355637,10 +355786,6 @@
    "1c82cb09f995361bcd3144ca57d4ecc1c69d4508",
    "testharness"
   ],
-  "gyroscope/Gyroscope.https-expected.txt": [
-   "b0a057a754e19f96e120240cdb478f58f12240ab",
-   "support"
-  ],
   "gyroscope/Gyroscope.https.html": [
    "e2b1919195d0af74bb7733a6d8a299adf43f4ee4",
    "testharness"
@@ -365949,6 +366094,26 @@
    "c1cff7b05cc400195328292521ecf76840d60540",
    "reftest"
   ],
+  "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html": [
+   "0c229767f50480bc044975494ffbc5c30b9a38ec",
+   "reftest"
+  ],
+  "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html": [
+   "691b374d8852aaaa5459a125989ee25e46632224",
+   "reftest"
+  ],
+  "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html": [
+   "7e62d0a23322cf52a49ab203bbd2ce3224cb2cc1",
+   "support"
+  ],
+  "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html": [
+   "db5ba23b7ff29945bb5c7ba71a9c24567c8a5446",
+   "support"
+  ],
+  "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html": [
+   "32df51d982607e285e34199ce3f1f90ad208deb5",
+   "reftest"
+  ],
   "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml": [
    "48efda6cb8f06cc70c71c436cecf6f3e4fea6aec",
    "support"
@@ -376886,7 +377051,7 @@
    "testharness"
   ],
   "magnetometer/Magnetometer.https-expected.txt": [
-   "19d0c8dddeee0d869e7924c71761565fc8ea34d0",
+   "555c01135c6c625667f89eebc09f29b3786bc150",
    "support"
   ],
   "magnetometer/Magnetometer.https.html": [
@@ -376897,10 +377062,6 @@
    "0eeb95340d7c74a0243eac8d3f004b6e06b87a92",
    "testharness"
   ],
-  "magnetometer/Magnetometer_onerror-manual.https-expected.txt": [
-   "71d027277b0af0e5264cc3f520145c0bdac528b6",
-   "support"
-  ],
   "magnetometer/Magnetometer_onerror-manual.https.html": [
    "5da81d90bd6960c94d5b3dd7592aa4c93d996e1a",
    "manual"
@@ -386273,10 +386434,6 @@
    "fd5dc9438ba3e81e9c8b69dcc814aaf5716f6c2f",
    "testharness"
   ],
-  "orientation-sensor/AbsoluteOrientationSensor.https-expected.txt": [
-   "e642947463a634fa4bc4e3adbfe85bc89b3ca174",
-   "support"
-  ],
   "orientation-sensor/AbsoluteOrientationSensor.https.html": [
    "c482c21d4336decf5d4c47b4e6911dc2b03a19e9",
    "testharness"
@@ -386337,10 +386494,6 @@
    "3e8344b5b3647bac67411facfefe766b9525c5ef",
    "testharness"
   ],
-  "orientation-sensor/RelativeOrientationSensor.https-expected.txt": [
-   "bfda2f7ce33918474e05c50052b5216b254c6226",
-   "support"
-  ],
   "orientation-sensor/RelativeOrientationSensor.https.html": [
    "9bf83c64eb5dcf284eb6c45db8ac278ab3c637a2",
    "testharness"
@@ -402965,6 +403118,58 @@
    "1660ebba379a218ba1ce74a655df2725d788622c",
    "testharness"
   ],
+  "svg/shapes/ellipse-01-ref.svg": [
+   "0d8b6dd9a471759dda8d9e33904b8a936c146b3a",
+   "support"
+  ],
+  "svg/shapes/ellipse-01.svg": [
+   "1d4ed53ac1c02fef27c83ccdefe7df95750ecd9b",
+   "reftest"
+  ],
+  "svg/shapes/ellipse-02-ref.svg": [
+   "ed927fa98a12be61040b6f9254fa209581f104a1",
+   "support"
+  ],
+  "svg/shapes/ellipse-02.svg": [
+   "041dbe27f4e08542f147d235244f0f98b155f5b2",
+   "reftest"
+  ],
+  "svg/shapes/ellipse-03-ref.svg": [
+   "0bae74326f227df4bf539bf046aea4ecb269c218",
+   "support"
+  ],
+  "svg/shapes/ellipse-03.svg": [
+   "81164201dc7116cf11d4047e5a7626159283603f",
+   "reftest"
+  ],
+  "svg/shapes/ellipse-04-ref.svg": [
+   "f42c2e31193806301d525b89227761f8156408e1",
+   "support"
+  ],
+  "svg/shapes/ellipse-04.svg": [
+   "a13ba9204163bc2ef59cfc91f4d1266632448f1f",
+   "reftest"
+  ],
+  "svg/shapes/ellipse-05.svg": [
+   "0592f5ffc8b8d7a04d63c3aec59969b95a526e21",
+   "reftest"
+  ],
+  "svg/shapes/ellipse-06.svg": [
+   "b164ebcf3b84265f5791751246c62a7e4e163786",
+   "reftest"
+  ],
+  "svg/shapes/ellipse-07-ref.svg": [
+   "db865e15becdd56b4a6646eda4a5d34e9ae60f01",
+   "support"
+  ],
+  "svg/shapes/ellipse-07.svg": [
+   "da30b99a5945cd508f1e285457ae5bb744b63169",
+   "reftest"
+  ],
+  "svg/shapes/ellipse-08.svg": [
+   "c56c1ec7f6c00f2291805a62d51b21ef2be6bfdb",
+   "reftest"
+  ],
   "svg/shapes/line-dasharray-ref.svg": [
    "1703bd2fa544c3b2a0cd9a2ff3ff329089f19e6a",
    "support"
@@ -403013,6 +403218,10 @@
    "ad79ad2f821e30c3c016bb1e156c1fafb4a4decf",
    "reftest"
   ],
+  "svg/shapes/rx-ry-not-inherited.svg": [
+   "47c4d5ed23e7f6a73b5f6495168df31cdd6a591d",
+   "testharness"
+  ],
   "svg/struct/UnknownElement/interface-expected.txt": [
    "8c5fb8c45f3a07e9b4494a4ca442a40191d27acc",
    "support"
@@ -404546,7 +404755,7 @@
    "testharness"
   ],
   "web-animations/animation-model/animation-types/property-list.js": [
-   "5a818163c3ddcb6e0901b4f0086d555e9d440e27",
+   "a6c524f515065db203ae5395f699b857eb279cd4",
    "support"
   ],
   "web-animations/animation-model/animation-types/property-types.js": [
@@ -404761,8 +404970,12 @@
    "c5ce17faeb355f1e9efae516d6272a88c46daa1f",
    "testharness"
   ],
+  "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt": [
+   "091b7f5e5eb71f65f0f926304a9e88e9b25fef20",
+   "support"
+  ],
   "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html": [
-   "f68c116e1da5ae8783187af22f00758d02b7a0e9",
+   "fe0f1f5f1b2066c71cc20495c96e6e89914788a8",
    "testharness"
   ],
   "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002.html": [
@@ -406822,7 +407035,7 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-add-track-no-deadlock.https.html": [
-   "d08414aefa6b0f082a0fcb7f5d05933636c012bb",
+   "e6c4c1e922e47bfb065d65bcf0954610162b8839",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-addIceCandidate-expected.txt": [
@@ -406838,7 +407051,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-addTrack.https.html": [
-   "eddb5aedbfea3636ae03c0920c4450afc8e70658",
+   "c924fe69d43bdef8ff1bd9e645c5cecc6b4fe34f",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-addTransceiver-expected.txt": [
@@ -406894,7 +407107,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt": [
-   "67aacb512a609600b199632884b8eed38be80d5a",
+   "ae109983a8f1761931ab848288e22dc991672032",
    "support"
   ],
   "webrtc/RTCPeerConnection-createOffer-offerToReceive.html": [
@@ -406938,7 +407151,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-getStats.https.html": [
-   "f703ed5bf1fc434afd72f525e1639c7e4621e1b7",
+   "dd972db6f5b3ef771ff817fbeb18fb65de01710a",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-getTransceivers-expected.txt": [
@@ -406950,7 +407163,7 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-helper.js": [
-   "8f8de7bbc399d3598f425c865b59e3d68830b2f8",
+   "e92d33cfb3fdacc6a2f172ecfe3444a1ced5680e",
    "support"
   ],
   "webrtc/RTCPeerConnection-iceConnectionState-expected.txt": [
@@ -407006,7 +407219,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-removeTrack.https.html": [
-   "f4251f373bce768c30c5da9253029319921f3cf0",
+   "a5c919e396c7f8a916a9e8fe6c766f9dc263a6f8",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt": [
@@ -407106,7 +407319,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html": [
-   "b3d025c0a50886293e340afc27081212b0bead95",
+   "3d1cfd0db67de255f7b1845d1be7fda6847eeb90",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription.html": [
@@ -407214,7 +407427,7 @@
    "support"
   ],
   "webrtc/RTCRtpReceiver-getStats.https.html": [
-   "ebbca119f90320469cb311cac234c82d230f1191",
+   "6dbb42fd71efcfbf8f637090f0326c834326c618",
    "testharness"
   ],
   "webrtc/RTCRtpReceiver-getSynchronizationSources.https-expected.txt": [
@@ -407238,7 +407451,7 @@
    "support"
   ],
   "webrtc/RTCRtpSender-getStats.https.html": [
-   "7cea6806ce165a32f5f28d6df215a2af07da7bd2",
+   "d00d8893b7f4f0e150d3e6281eff0c2e19fd03c3",
    "testharness"
   ],
   "webrtc/RTCRtpSender-replaceTrack-expected.txt": [
@@ -407346,7 +407559,7 @@
    "support"
   ],
   "webrtc/interfaces.https.html": [
-   "e66dc8812ea38e216c4483dbb3c7814574c39653",
+   "a5656af33767d909ae61760773f715d1cb44ac42",
    "testharness"
   ],
   "webrtc/no-media-call.html": [
@@ -407366,7 +407579,7 @@
    "testharness"
   ],
   "webrtc/simplecall.https.html": [
-   "146432ca56e487a035df8ad9d5a7fa4a495b5405",
+   "01b15f6f42ca762c5e2949370b64575d45ec9941",
    "testharness"
   ],
   "webrtc/tools/README.md": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/accelerometer/Accelerometer.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/accelerometer/Accelerometer.https-expected.txt
index f9d1e1a..8597e2a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/accelerometer/Accelerometer.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/accelerometer/Accelerometer.https-expected.txt
@@ -10,7 +10,7 @@
 PASS Accelerometer: Test that fresh reading is fetched on start()
 PASS Accelerometer: frequency hint works
 PASS Accelerometer: sensor receives suspend / resume notifications when  cross-origin subframe is focused
-FAIL Accelerometer: throw 'TypeError' if frequency is invalid assert_throws: when freq is undefined function "() => { new sensorType({frequency: freq}) }" did not throw
+PASS Accelerometer: throw 'TypeError' if frequency is invalid
 PASS Accelerometer: sensor reading is correct when options.referenceFrame is 'screen'
 PASS Accelerometer: throw 'TypeError' if referenceFrame is not one of enumeration values
 FAIL GravitySensor: Test that 'onreading' is called and sensor reading is valid assert_true: expected true got false
@@ -38,7 +38,7 @@
 PASS LinearAccelerationSensor: Test that fresh reading is fetched on start()
 PASS LinearAccelerationSensor: frequency hint works
 PASS LinearAccelerationSensor: sensor receives suspend / resume notifications when  cross-origin subframe is focused
-FAIL LinearAccelerationSensor: throw 'TypeError' if frequency is invalid assert_throws: when freq is undefined function "() => { new sensorType({frequency: freq}) }" did not throw
+PASS LinearAccelerationSensor: throw 'TypeError' if frequency is invalid
 PASS LinearAccelerationSensor: sensor reading is correct when options.referenceFrame is 'screen'
 PASS LinearAccelerationSensor: throw 'TypeError' if referenceFrame is not one of enumeration values
 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-eval-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-eval-expected.txt
new file mode 100644
index 0000000..e170223
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-eval-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Eval violations have a blockedURI of 'eval' assert_equals: expected 12 but got 13
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-eval.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-eval.html
index c9d74e6..ddd5068 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-eval.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-eval.html
@@ -7,7 +7,8 @@
         var watcher = new EventWatcher(t, document, 'securitypolicyviolation');
         watcher.wait_for('securitypolicyviolation').then(t.step_func_done(e => {
             assert_equals(e.blockedURI, "eval");
-            assert_equals(e.lineNumber, 14);
+            assert_equals(e.lineNumber, 15);
+            assert_equals(e.columnNumber, 12);
         }));
 
         try {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-inline-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-inline-expected.txt
new file mode 100644
index 0000000..9c3089f2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-inline-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Inline violations have a blockedURI of 'inline' assert_equals: expected 1 but got 0
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-inline.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-inline.html
index c4862337..40c4865 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-inline.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/blockeduri-inline.html
@@ -7,7 +7,8 @@
         var watcher = new EventWatcher(t, document, 'securitypolicyviolation');
         watcher.wait_for('securitypolicyviolation').then(t.step_func_done(e => {
             assert_equals(e.blockedURI, "inline");
-            assert_equals(e.lineNumber, 14);
+            assert_equals(e.lineNumber, 15);
+            assert_equals(e.columnNumber, 1);
         }));
     }, "Inline violations have a blockedURI of 'inline'");
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/targeting.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/targeting.html
index 1464f4e..d27cc00 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/targeting.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/targeting.html
@@ -35,19 +35,22 @@
             }))
             .then(t.step_func(e => {
                 assert_equals(e.blockedURI, "inline");
-                assert_equals(e.lineNumber, 132);
+                assert_equals(e.lineNumber, 135);
+                assert_equals(e.columnNumber, 7);
                 assert_equals(e.target, document, "Disconnected elements target the document");
                 return watcher.wait_for('securitypolicyviolation');
             }))
             .then(t.step_func(e => {
                 assert_equals(e.blockedURI, "inline");
-                assert_equals(e.lineNumber, 143);
+                assert_equals(e.lineNumber, 146);
+                assert_equals(e.columnNumber, 7);
                 assert_equals(e.target, document, "Elements disconnected after triggering target the document.");
                 return watcher.wait_for('securitypolicyviolation');
             }))
             .then(t.step_func(e => {
                 assert_equals(e.blockedURI, "inline");
-                assert_equals(e.lineNumber, 157);
+                assert_equals(e.lineNumber, 160);
+                assert_equals(e.columnNumber, 7);
                 assert_equals(e.target, document, "Elements in DocumentFragments target the document");
             }))
             .then(t.step_func_done(_ => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/interfaces-expected.txt
index 370a1dd..18d406b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/cssom/interfaces-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom/interfaces-expected.txt
@@ -77,8 +77,8 @@
 PASS Unscopable handled correctly for media property on StyleSheet
 PASS StyleSheet interface: attribute disabled
 PASS Unscopable handled correctly for disabled property on StyleSheet
-PASS CSSStyleSheet interface: existence and properties of interface object
-FAIL CSSStyleSheet interface object length assert_equals: wrong value for CSSStyleSheet.length expected 0 but got 1
+FAIL CSSStyleSheet interface: existence and properties of interface object assert_throws: interface object didn't throw TypeError when called as a constructor function "function () { [native code] }" did not throw
+PASS CSSStyleSheet interface object length
 PASS CSSStyleSheet interface object name
 PASS CSSStyleSheet interface: existence and properties of interface prototype object
 PASS CSSStyleSheet interface: existence and properties of interface prototype object's "constructor" property
diff --git a/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/generic-sensor-tests.js b/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/generic-sensor-tests.js
index 7313550..8168d7a3 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/generic-sensor-tests.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/generic-sensor/generic-sensor-tests.js
@@ -337,8 +337,7 @@
       NaN,
       Infinity,
       -Infinity,
-      {},
-      undefined
+      {}
     ];
     invalidFreqs.map(freq => {
       assert_throws(new TypeError(),
diff --git a/third_party/WebKit/LayoutTests/external/wpt/gyroscope/Gyroscope.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/gyroscope/Gyroscope.https-expected.txt
deleted file mode 100644
index c673fd7..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/gyroscope/Gyroscope.https-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS Gyroscope: Test that 'onreading' is called and sensor reading is valid
-PASS Gyroscope: sensor reading is correct
-PASS Gyroscope: sensor timestamp is updated when time passes
-PASS Gyroscope: Test that sensor can be successfully created and its states are correct.
-PASS Gyroscope: sensor.start() returns undefined
-PASS Gyroscope: no exception is thrown when calling start() on already started sensor
-PASS Gyroscope: sensor.stop() returns undefined
-PASS Gyroscope: no exception is thrown when calling stop() on already stopped sensor
-PASS Gyroscope: Test that fresh reading is fetched on start()
-PASS Gyroscope: frequency hint works
-PASS Gyroscope: sensor receives suspend / resume notifications when  cross-origin subframe is focused
-FAIL Gyroscope: throw 'TypeError' if frequency is invalid assert_throws: when freq is undefined function "() => { new sensorType({frequency: freq}) }" did not throw
-PASS Gyroscope: sensor reading is correct when options.referenceFrame is 'screen'
-PASS Gyroscope: throw 'TypeError' if referenceFrame is not one of enumeration values
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html
new file mode 100644
index 0000000..6e32206d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<link rel="match" href="input-align-right-ref.html">
+<input type="image" align="right">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html
new file mode 100644
index 0000000..d58848a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<link rel="match" href="input-align-right-ref.html">
+<input align="right" type="image">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html
new file mode 100644
index 0000000..55f06ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<input type="image" style="float: right">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html
new file mode 100644
index 0000000..7768379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<input align="right">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html
new file mode 100644
index 0000000..00747a5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel=match href="input-type-change-from-image-1-ref.html">
+<input type="image" align="right">
+<script>
+  onload = function() {
+    var i = document.querySelector("input");
+    window.rect = i.getBoundingClientRect();
+    i.type = "text";
+  }
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/magnetometer/Magnetometer.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/magnetometer/Magnetometer.https-expected.txt
index e0cd043..2a48ea4 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/magnetometer/Magnetometer.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/magnetometer/Magnetometer.https-expected.txt
@@ -10,7 +10,7 @@
 PASS Magnetometer: Test that fresh reading is fetched on start()
 PASS Magnetometer: frequency hint works
 PASS Magnetometer: sensor receives suspend / resume notifications when  cross-origin subframe is focused
-FAIL Magnetometer: throw 'TypeError' if frequency is invalid assert_throws: when freq is undefined function "() => { new sensorType({frequency: freq}) }" did not throw
+PASS Magnetometer: throw 'TypeError' if frequency is invalid
 PASS Magnetometer: sensor reading is correct when options.referenceFrame is 'screen'
 PASS Magnetometer: throw 'TypeError' if referenceFrame is not one of enumeration values
 FAIL UncalibratedMagnetometer: Test that 'onreading' is called and sensor reading is valid assert_true: expected true got false
diff --git a/third_party/WebKit/LayoutTests/external/wpt/orientation-sensor/AbsoluteOrientationSensor.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/orientation-sensor/AbsoluteOrientationSensor.https-expected.txt
deleted file mode 100644
index 0f0347d..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/orientation-sensor/AbsoluteOrientationSensor.https-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-This is a testharness.js-based test.
-PASS AbsoluteOrientationSensor.quaternion return a four-element FrozenArray.
-PASS AbsoluteOrientationSensor.populateMatrix() method works correctly.
-PASS AbsoluteOrientationSensor: Test that 'onreading' is called and sensor reading is valid
-PASS AbsoluteOrientationSensor: sensor reading is correct
-PASS AbsoluteOrientationSensor: sensor timestamp is updated when time passes
-PASS AbsoluteOrientationSensor: Test that sensor can be successfully created and its states are correct.
-PASS AbsoluteOrientationSensor: sensor.start() returns undefined
-PASS AbsoluteOrientationSensor: no exception is thrown when calling start() on already started sensor
-PASS AbsoluteOrientationSensor: sensor.stop() returns undefined
-PASS AbsoluteOrientationSensor: no exception is thrown when calling stop() on already stopped sensor
-PASS AbsoluteOrientationSensor: Test that fresh reading is fetched on start()
-PASS AbsoluteOrientationSensor: frequency hint works
-PASS AbsoluteOrientationSensor: sensor receives suspend / resume notifications when  cross-origin subframe is focused
-FAIL AbsoluteOrientationSensor: throw 'TypeError' if frequency is invalid assert_throws: when freq is undefined function "() => { new sensorType({frequency: freq}) }" did not throw
-PASS AbsoluteOrientationSensor: sensor reading is correct when options.referenceFrame is 'screen'
-PASS AbsoluteOrientationSensor: throw 'TypeError' if referenceFrame is not one of enumeration values
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/orientation-sensor/RelativeOrientationSensor.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/orientation-sensor/RelativeOrientationSensor.https-expected.txt
deleted file mode 100644
index 55378e9..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/orientation-sensor/RelativeOrientationSensor.https-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-This is a testharness.js-based test.
-PASS RelativeOrientationSensor.quaternion return a four-element FrozenArray.
-PASS RelativeOrientationSensor.populateMatrix() method works correctly.
-PASS RelativeOrientationSensor: Test that 'onreading' is called and sensor reading is valid
-PASS RelativeOrientationSensor: sensor reading is correct
-PASS RelativeOrientationSensor: sensor timestamp is updated when time passes
-PASS RelativeOrientationSensor: Test that sensor can be successfully created and its states are correct.
-PASS RelativeOrientationSensor: sensor.start() returns undefined
-PASS RelativeOrientationSensor: no exception is thrown when calling start() on already started sensor
-PASS RelativeOrientationSensor: sensor.stop() returns undefined
-PASS RelativeOrientationSensor: no exception is thrown when calling stop() on already stopped sensor
-PASS RelativeOrientationSensor: Test that fresh reading is fetched on start()
-PASS RelativeOrientationSensor: frequency hint works
-PASS RelativeOrientationSensor: sensor receives suspend / resume notifications when  cross-origin subframe is focused
-FAIL RelativeOrientationSensor: throw 'TypeError' if frequency is invalid assert_throws: when freq is undefined function "() => { new sensorType({frequency: freq}) }" did not throw
-PASS RelativeOrientationSensor: sensor reading is correct when options.referenceFrame is 'screen'
-PASS RelativeOrientationSensor: throw 'TypeError' if referenceFrame is not one of enumeration values
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-01-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-01-ref.svg
new file mode 100644
index 0000000..c4ab1bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-01-ref.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <ellipse cx="50" cy="50" rx="40" ry="30" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-01.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-01.svg
new file mode 100644
index 0000000..1b1124e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-01.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-01-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="ellipse element uses rx/ry properties."/>
+  </metadata>
+  <style>
+    ellipse {
+      rx: 40px;
+      ry: 30px;
+    }
+  </style>
+  <ellipse cx="50" cy="50" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-02-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-02-ref.svg
new file mode 100644
index 0000000..1a4b455
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-02-ref.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <ellipse cx="50" cy="50" rx="40" ry="40" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-02.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-02.svg
new file mode 100644
index 0000000..c4727b8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-02.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-02-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="ry auto means rx is used"/>
+  </metadata>
+  <style>
+    ellipse {
+      rx: 40px;
+      ry: auto;
+    }
+  </style>
+  <ellipse cx="50" cy="50" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-03-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-03-ref.svg
new file mode 100644
index 0000000..15fae5e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-03-ref.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <ellipse cx="50" cy="50" rx="30" ry="30" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-03.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-03.svg
new file mode 100644
index 0000000..e0aacef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-03.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-03-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="rx auto means ry is used."/>
+  </metadata>
+  <style>
+    ellipse {
+      rx: auto;
+      ry: 30px;
+    }
+  </style>
+  <ellipse cx="50" cy="50" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-04-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-04-ref.svg
new file mode 100644
index 0000000..1d62e8e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-04-ref.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-04.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-04.svg
new file mode 100644
index 0000000..79e6d06
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-04.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-04-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="rx and ry auto disables rendering."/>
+  </metadata>
+  <style>
+    ellipse {
+      rx: auto;
+      ry: auto;
+    }
+  </style>
+  <ellipse cx="50" cy="50" fill="none" stroke="red" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-05.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-05.svg
new file mode 100644
index 0000000..e86f105
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-05.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-02-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="ry defaults to auto."/>
+  </metadata>
+  <style>
+    ellipse {
+      rx: 40px;
+    }
+  </style>
+  <ellipse cx="50" cy="50" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-06.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-06.svg
new file mode 100644
index 0000000..80f36a9ad
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-06.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-03-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="rx defaults to auto."/>
+  </metadata>
+  <style>
+    ellipse {
+      ry: 30px;
+    }
+  </style>
+  <ellipse cx="50" cy="50" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-07-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-07-ref.svg
new file mode 100644
index 0000000..bd84518
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-07-ref.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="240px" height="160px" viewBox="0 0 60 40">
+  <ellipse cx="20" cy="20" rx="15" ry="15" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-07.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-07.svg
new file mode 100644
index 0000000..396e5f3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-07.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="240px" height="160px" viewBox="0 0 60 40">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-07-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="ry auto means rx absolute length is used"/>
+  </metadata>
+  <style>
+    ellipse {
+      rx: 25%;
+      ry: auto;
+    }
+  </style>
+  <ellipse cx="20" cy="20" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-08.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-08.svg
new file mode 100644
index 0000000..1ff393b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/ellipse-08.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="240px" height="160px" viewBox="0 0 60 40">
+  <metadata>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="ellipse-07-ref.svg"/>
+    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="rx auto means ry absolute length is used"/>
+  </metadata>
+  <style>
+    ellipse {
+      rx: auto;
+      ry: 37.5%;
+    }
+  </style>
+  <ellipse cx="20" cy="20" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/rx-ry-not-inherited.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/rx-ry-not-inherited.svg
new file mode 100644
index 0000000..ff943e8b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/svg/shapes/rx-ry-not-inherited.svg
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:h="http://www.w3.org/1999/xhtml">
+  <metadata>
+    <h:link rel="help" href="https://www.w3.org/TR/SVG2/shapes.html#EllipseElement"/>
+    <h:meta name="assert" content="rx,ry are not inherited by default"/>
+  </metadata>
+  <style>
+    g {
+      rx: 10px;
+      ry: 20px;
+    }
+  </style>
+  <g>
+    <ellipse id="spot" cx="50" cy="50"/>
+  </g>
+  <h:script src="/resources/testharness.js"/>
+  <h:script src="/resources/testharnessreport.js"/>
+  <script><![CDATA[
+  test(function() {
+    var spot = document.getElementById('spot');
+    assert_equals(getComputedStyle(spot).rx, "auto");
+    assert_equals(getComputedStyle(spot).ry, "auto");
+    spot.style.rx = 'inherit';
+    spot.style.ry = 'inherit';
+    assert_equals(getComputedStyle(spot).rx, "10px");
+    assert_equals(getComputedStyle(spot).ry, "20px");
+  });
+  ]]></script>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
index cb6e2c8..8871343 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
@@ -446,12 +446,6 @@
       { type: 'discrete', options: [ [ 'pointer', 'wait' ] ] }
     ]
   },
-  'direction': {
-    // https://drafts.csswg.org/css-writing-modes-3/#propdef-direction
-    types: [
-      { type: 'discrete', options: [ [ 'ltr', 'rtl' ] ] }
-    ]
-  },
   'dominant-baseline': {
     // https://drafts.csswg.org/css-inline/#propdef-dominant-baseline
     types: [
@@ -1472,12 +1466,6 @@
       { type: 'discrete', options: [ [ 'scroll-position', 'contents' ] ] }
     ]
   },
-  'writing-mode': {
-    // https://drafts.csswg.org/css-writing-modes-3/#propdef-writing-mode
-    types: [
-      { type: 'discrete', options: [ [ 'vertical-rl', 'sideways-rl' ] ] }
-    ]
-  },
   'z-index': {
     // https://drafts.csswg.org/css-position/#propdef-z-index
     types: [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt
new file mode 100644
index 0000000..98683f7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt
@@ -0,0 +1,64 @@
+This is a testharness.js-based test.
+Found 60 tests; 56 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS non-animatable property 'animation' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationDelay' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationDirection' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationDuration' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationFillMode' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationIterationCount' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationName' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationPlayState' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animationTimingFunction' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'transition' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'transitionDelay' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'transitionDuration' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'transitionProperty' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'transitionTimingFunction' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'display' is not accessed when using a property-indexed keyframe object
+FAIL non-animatable property 'direction' is not accessed when using a property-indexed keyframe object assert_equals: Accessor not called expected 0 but got 1
+PASS non-animatable property 'unsupportedProperty' is not accessed when using a property-indexed keyframe object
+FAIL non-animatable property 'writingMode' is not accessed when using a property-indexed keyframe object assert_equals: Accessor not called expected 0 but got 1
+PASS non-animatable property 'font-size' is not accessed when using a property-indexed keyframe object
+PASS non-animatable property 'animation' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationDelay' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationDirection' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationDuration' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationFillMode' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationIterationCount' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationName' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationPlayState' is not accessed when using a keyframe sequence
+PASS non-animatable property 'animationTimingFunction' is not accessed when using a keyframe sequence
+PASS non-animatable property 'transition' is not accessed when using a keyframe sequence
+PASS non-animatable property 'transitionDelay' is not accessed when using a keyframe sequence
+PASS non-animatable property 'transitionDuration' is not accessed when using a keyframe sequence
+PASS non-animatable property 'transitionProperty' is not accessed when using a keyframe sequence
+PASS non-animatable property 'transitionTimingFunction' is not accessed when using a keyframe sequence
+PASS non-animatable property 'display' is not accessed when using a keyframe sequence
+FAIL non-animatable property 'direction' is not accessed when using a keyframe sequence assert_equals: Accessor not called expected 0 but got 1
+PASS non-animatable property 'unsupportedProperty' is not accessed when using a keyframe sequence
+FAIL non-animatable property 'writingMode' is not accessed when using a keyframe sequence assert_equals: Accessor not called expected 0 but got 1
+PASS non-animatable property 'font-size' is not accessed when using a keyframe sequence
+PASS Equivalent property-indexed and sequenced keyframes: two properties with one value
+PASS Equivalent property-indexed and sequenced keyframes: two properties with three values
+PASS Equivalent property-indexed and sequenced keyframes: two properties with different numbers of values
+PASS Equivalent property-indexed and sequenced keyframes: same easing applied to all keyframes
+PASS Equivalent property-indexed and sequenced keyframes: same composite applied to all keyframes
+PASS Keyframes are read from a custom iterator
+PASS 'easing' and 'offset' are ignored on iterable objects
+PASS Keyframes are read from a custom iterator with multiple properties specified
+PASS Keyframes are read from a custom iterator with where an offset is specified
+PASS If a keyframe throws for an animatable property, that exception should be propagated
+PASS Reading from a custom iterator that returns a non-object keyframe should throw
+PASS An undefined keyframe returned from a custom iterator should be treated as a default keyframe
+PASS A null keyframe returned from a custom iterator should be treated as a default keyframe
+PASS A list of values returned from a custom iterator should be ignored
+PASS If a custom iterator throws from next(), the exception should be rethrown
+PASS Accessing a Symbol.iterator property that throws should rethrow
+PASS A non-object returned from the Symbol.iterator property should cause a TypeError to be thrown
+PASS Only enumerable properties on keyframes are read
+PASS Only properties defined directly on keyframes are read
+PASS Only enumerable properties on property-indexed keyframes are read
+PASS Only properties defined directly on property-indexed keyframes are read
+PASS Properties are read in ascending order by Unicode codepoint
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
index 1b28210..b20daf3 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
@@ -36,7 +36,9 @@
   'transitionProperty',
   'transitionTimingFunction',
   'display',
+  'direction',
   'unsupportedProperty',
+  'writingMode',
   'font-size', // Supported property that uses dashes
 ];
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html
index 0a69431..81e3b73 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-add-track-no-deadlock.https.html
@@ -3,6 +3,7 @@
 <title>RTCPeerConnection addTrack does not deadlock</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
 <script>
   'use strict';
 
@@ -12,7 +13,7 @@
   promise_test(async t => {
     const pc1 = new RTCPeerConnection();
     t.add_cleanup(() => pc1.close());
-    const stream = await navigator.mediaDevices.getUserMedia(
+    const stream = await getNoiseStream(
       {audio: false, video: true});
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const videoTrack = stream.getVideoTracks()[0];
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html
index 6864f091..920b6a47 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.https.html
@@ -41,7 +41,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
 
@@ -64,7 +64,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
 
@@ -96,7 +96,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
 
@@ -113,7 +113,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
 
@@ -137,7 +137,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt
index 29c100b..a4f81da 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createOffer-offerToReceive-expected.txt
@@ -2,17 +2,17 @@
 FAIL createOffer() with offerToReceiveAudio set to false should not create a transceiver promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL createOffer() with offerToReceiveAudio should create a "recvonly" transceiver promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL offerToReceiveAudio option should be ignored if a non-stopped "recvonly" transceiver exists promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
-FAIL offerToReceiveAudio option should be ignored if a non-stopped "sendrecv" transceiver exists promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
-FAIL offerToReceiveAudio set to false with a track should create a "sendonly" transceiver promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL offerToReceiveAudio option should be ignored if a non-stopped "sendrecv" transceiver exists promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
+FAIL offerToReceiveAudio set to false with a track should create a "sendonly" transceiver promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL offerToReceiveAudio set to false with a "recvonly" transceiver should change the direction to "inactive" pc.addTransceiver is not a function
-FAIL subsequent offerToReceiveAudio set to false with a track should change the direction to "sendonly" promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL subsequent offerToReceiveAudio set to false with a track should change the direction to "sendonly" promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL createOffer() with offerToReceiveVideo set to false should not create a transceiver promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL createOffer() with offerToReceiveVideo should create a "recvonly" transceiver promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL offerToReceiveVideo option should be ignored if a non-stopped "recvonly" transceiver exists promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
-FAIL offerToReceiveVideo option should be ignored if a non-stopped "sendrecv" transceiver exists promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
-FAIL offerToReceiveVideo set to false with a track should create a "sendonly" transceiver promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL offerToReceiveVideo option should be ignored if a non-stopped "sendrecv" transceiver exists promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
+FAIL offerToReceiveVideo set to false with a track should create a "sendonly" transceiver promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL offerToReceiveVideo set to false with a "recvonly" transceiver should change the direction to "inactive" pc.addTransceiver is not a function
-FAIL subsequent offerToReceiveVideo set to false with a track should change the direction to "sendonly" promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL subsequent offerToReceiveVideo set to false with a track should change the direction to "sendonly" promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 FAIL offerToReceiveAudio and Video should create two "recvonly" transceivers promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers is not a function"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html
index 2c0170f..5f5a2fb 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html
@@ -238,7 +238,7 @@
 
     const dataChannel = pc1.createDataChannel('test-channel');
 
-    return navigator.mediaDevices.getUserMedia({
+    return getNoiseStream({
       audio: true,
       video: true
     })
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js
index 6107d6d3..bc6d3cd 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js
@@ -350,12 +350,110 @@
   return track;
 }
 
-// Obtain a MediaStreamTrack of kind using getUserMedia.
+// These media tracks will be continually updated with deterministic "noise" in
+// order to ensure UAs do not cease transmission in response to apparent
+// silence.
+//
+// > Many codecs and systems are capable of detecting "silence" and changing
+// > their behavior in this case by doing things such as not transmitting any
+// > media.
+//
+// Source: https://w3c.github.io/webrtc-pc/#offer-answer-options
+const trackFactories = {
+  // Share a single context between tests to avoid exceeding resource limits
+  // without requiring explicit destruction.
+  audioContext: null,
+
+  /**
+   * Given a set of requested media types, determine if the user agent is
+   * capable of procedurally generating a suitable media stream.
+   *
+   * @param {object} requested
+   * @param {boolean} [requested.audio] - flag indicating whether the desired
+   *                                      stream should include an audio track
+   * @param {boolean} [requested.video] - flag indicating whether the desired
+   *                                      stream should include a video track
+   *
+   * @returns {boolean}
+   */
+  canCreate(requested) {
+    const supported = {
+      audio: !!window.MediaStreamAudioDestinationNode,
+      video: !!HTMLCanvasElement.prototype.captureStream
+    };
+
+    return (!requested.audio || supported.audio) &&
+      (!requested.video || supported.video);
+  },
+
+  audio() {
+    const ctx = trackFactories.audioContext = trackFactories.audioContext ||
+      new AudioContext();
+    const oscillator = ctx.createOscillator();
+    const dst = oscillator.connect(ctx.createMediaStreamDestination());
+    oscillator.start();
+    return dst.stream.getAudioTracks()[0];
+  },
+
+  video({width = 640, height = 480} = {}) {
+    const canvas = Object.assign(
+      document.createElement("canvas"), {width, height}
+    );
+    const ctx = canvas.getContext('2d');
+    const stream = canvas.captureStream();
+
+    let count = 0;
+    setInterval(() => {
+      ctx.fillStyle = `rgb(${count%255}, ${count*count%255}, ${count%255})`;
+      count += 1;
+
+      ctx.fillRect(0, 0, width, height);
+    }, 100);
+
+    if (document.body) {
+      document.body.appendChild(canvas);
+    } else {
+      document.addEventListener('DOMContentLoaded', () => {
+        document.body.appendChild(canvas);
+      });
+    }
+
+    return stream.getVideoTracks()[0];
+  }
+};
+
+// Generate a MediaStream bearing the specified tracks.
+//
+// @param {object} [caps]
+// @param {boolean} [caps.audio] - flag indicating whether the generated stream
+//                                 should include an audio track
+// @param {boolean} [caps.video] - flag indicating whether the generated stream
+//                                 should include a video track
+async function getNoiseStream(caps = {}) {
+  if (!trackFactories.canCreate(caps)) {
+    return navigator.mediaDevices.getUserMedia(caps);
+  }
+  const tracks = [];
+
+  if (caps.audio) {
+    tracks.push(trackFactories.audio());
+  }
+
+  if (caps.video) {
+    tracks.push(trackFactories.video());
+  }
+
+  return new MediaStream(tracks);
+}
+
+// Obtain a MediaStreamTrack of kind using procedurally-generated streams (and
+// falling back to `getUserMedia` when the user agent cannot generate the
+// requested streams).
 // Return Promise of pair of track and associated mediaStream.
 // Assumes that there is at least one available device
 // to generate the track.
 function getTrackFromUserMedia(kind) {
-  return navigator.mediaDevices.getUserMedia({ [kind]: true })
+  return getNoiseStream({ [kind]: true })
   .then(mediaStream => {
     const [track] = mediaStream.getTracks();
     return [track, mediaStream];
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html
index 51d199d..e8a8bac 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html
@@ -50,7 +50,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
     const sender = pc.addTrack(track, stream);
@@ -75,7 +75,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
     const sender = pc.addTrack(track, stream);
@@ -104,7 +104,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
     const sender = pc.addTrack(track, stream);
@@ -137,7 +137,7 @@
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
 
-    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+    const stream = await getNoiseStream({ audio: true });
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
     const sender = pc.addTrack(track, stream);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html
index eb2510dd..91828f96 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html
@@ -23,7 +23,7 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     caller.addTrack(localStream.getTracks()[0]);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
@@ -41,7 +41,7 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     caller.addTrack(localStream.getTracks()[0], localStream);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
@@ -64,7 +64,7 @@
     t.add_cleanup(() => callee.close());
     let eventSequence = '';
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     caller.addTrack(localStream.getTracks()[0], localStream);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
@@ -82,8 +82,8 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStreams = await Promise.all([
-      navigator.mediaDevices.getUserMedia({audio: true}),
-      navigator.mediaDevices.getUserMedia({audio: true}),
+      getNoiseStream({audio: true}),
+      getNoiseStream({audio: true}),
     ]);
     caller.addTrack(localStreams[0].getTracks()[0], localStreams[0]);
     caller.addTrack(localStreams[1].getTracks()[0], localStreams[0]);
@@ -126,8 +126,8 @@
     t.add_cleanup(() => callee.close());
     let eventSequence = '';
     const localStreams = await Promise.all([
-      navigator.mediaDevices.getUserMedia({audio: true}),
-      navigator.mediaDevices.getUserMedia({audio: true}),
+      getNoiseStream({audio: true}),
+      getNoiseStream({audio: true}),
     ]);
     caller.addTrack(localStreams[0].getTracks()[0], localStreams[0]);
     const remoteStreams = [];
@@ -158,8 +158,8 @@
     t.add_cleanup(() => callee.close());
     let eventSequence = '';
     const localStreams = await Promise.all([
-      navigator.mediaDevices.getUserMedia({audio: true}),
-      navigator.mediaDevices.getUserMedia({audio: true}),
+      getNoiseStream({audio: true}),
+      getNoiseStream({audio: true}),
     ]);
     caller.addTrack(localStreams[0].getTracks()[0], localStreams[0]);
     const remoteStreams = [];
@@ -187,8 +187,8 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStreams = await Promise.all([
-      navigator.mediaDevices.getUserMedia({audio: true}),
-      navigator.mediaDevices.getUserMedia({audio: true}),
+      getNoiseStream({audio: true}),
+      getNoiseStream({audio: true}),
     ]);
     caller.addTrack(localStreams[0].getTracks()[0],
                     localStreams[0], localStreams[1]);
@@ -215,7 +215,7 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     caller.addTrack(localStream.getTracks()[0]);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
@@ -232,7 +232,7 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     const sender = caller.addTrack(localStream.getTracks()[0]);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track');
@@ -250,7 +250,7 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     const [track] = localStream.getTracks();
     const sender = caller.addTrack(track, localStream);
@@ -279,7 +279,7 @@
     t.add_cleanup(() => callee.close());
     let eventSequence = '';
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     const sender = caller.addTrack(localStream.getTracks()[0], localStream);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
@@ -306,7 +306,7 @@
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     const sender = caller.addTrack(localStream.getTracks()[0], localStream);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
@@ -332,7 +332,7 @@
     t.add_cleanup(() => callee.close());
     let eventSequence = '';
     const localStream =
-        await navigator.mediaDevices.getUserMedia({audio: true});
+        await getNoiseStream({audio: true});
     t.add_cleanup(() => localStream.getTracks().forEach(track => track.stop()));
     const sender = caller.addTrack(localStream.getTracks()[0], localStream);
     const ontrackPromise = addEventListenerPromise(t, callee, 'track', e => {
@@ -356,7 +356,7 @@
   promise_test(async t => {
     const pc = new RTCPeerConnection();
     t.add_cleanup(() => pc.close());
-    const stream = await navigator.mediaDevices.getUserMedia({audio: true});
+    const stream = await getNoiseStream({audio: true});
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const sender = pc.addTrack(stream.getTracks()[0]);
     pc.removeTrack(sender);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getStats.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getStats.https.html
index 083f9e12..4a2e6a0 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getStats.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpReceiver-getStats.https.html
@@ -62,7 +62,7 @@
     t.add_cleanup(() => caller.close());
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
-    const stream = await navigator.mediaDevices.getUserMedia({audio:true});
+    const stream = await getNoiseStream({audio:true});
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
     caller.addTrack(track, stream);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getStats.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getStats.https.html
index dc403bbe6..18ab825 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getStats.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCRtpSender-getStats.https.html
@@ -57,7 +57,7 @@
     t.add_cleanup(() => caller.close());
     const callee = new RTCPeerConnection();
     t.add_cleanup(() => callee.close());
-    const stream = await navigator.mediaDevices.getUserMedia({audio:true});
+    const stream = await getNoiseStream({audio:true});
     t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
     const [track] = stream.getTracks();
     const sender = caller.addTrack(track, stream);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html
index 5807a63..fc620a2f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html
@@ -79,7 +79,7 @@
 
   // Asynchoronously generate MediaStreamTrack from getUserMedia
   function asyncInitMediaStreamTrack() {
-    return navigator.mediaDevices.getUserMedia({ audio: true })
+    return getNoiseStream({ audio: true })
     .then(mediaStream => {
       idlTestObjects.mediaStreamTrack = mediaStream.getTracks()[0];
     });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/simplecall.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/simplecall.https.html
index 4d948ee..6adefe7 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/simplecall.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/simplecall.https.html
@@ -1,23 +1,15 @@
 <!doctype html>
-<!--
-To run this test, you must have a webcam and a microphone or use
-fake devices by specifying
-  --use-fake-device-for-media-stream --use-fake-ui-for-media-stream
-for Chrome or by setting the
-  media.navigator.streams.fake
-property to true in Firefox.
--->
-
 <html>
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   <title>RTCPeerConnection Connection Test</title>
+  <script src="RTCPeerConnection-helper.js"></script>
 </head>
 <body>
   <div id="log"></div>
   <div>
-    <video id="local-view" autoplay="autoplay"></video>
-    <video id="remote-view" autoplay="autoplay"/>
+    <video id="local-view" muted autoplay="autoplay"></video>
+    <video id="remote-view" muted autoplay="autoplay"/>
     </video>
   </div>
 
@@ -38,7 +30,7 @@
     test.done();
   });
 
-  function getUserMediaOkCallback(localStream) {
+  function getNoiseStreamOkCallback(localStream) {
     gFirstConnection = new RTCPeerConnection(null);
     gFirstConnection.onicecandidate = onIceCandidateToFirst;
     localStream.getTracks().forEach(function(track) {
@@ -111,8 +103,8 @@
 
   // This function starts the test.
   test.step(function() {
-    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
-      .then(test.step_func(getUserMediaOkCallback), failed('getUserMedia'));
+    getNoiseStream({ video: true, audio: true })
+      .then(test.step_func(getNoiseStreamOkCallback), failed('getNoiseStream'));
   });
 </script>
 
diff --git a/third_party/WebKit/LayoutTests/fast/css/CSSStyleSheet-constructable.html b/third_party/WebKit/LayoutTests/fast/css/CSSStyleSheet-constructable.html
index d78c6984..429ba344 100644
--- a/third_party/WebKit/LayoutTests/fast/css/CSSStyleSheet-constructable.html
+++ b/third_party/WebKit/LayoutTests/fast/css/CSSStyleSheet-constructable.html
@@ -2,80 +2,30 @@
 <!-- TODO(rakina): move to WPT once spec is finalized -->
 <script src = '../../resources/testharness.js'></script>
 <script src = '../../resources/testharnessreport.js'></script>
-<style>dummy {}</style>
-
-<section id="firstSection">
-  <div>
-    <span class="green"></span>
-    <span class="red"></span>
-    <span class="blue"></span>
-    <span class="white"></span>
-    <span class="yellow"></span>
-  </div>
-</section>
-<section id="secondSection"></section>
 
 <script>
 'use strict';
-const greenStyleText = ".green { color: green; }";
+
 const redStyleTexts = [".red { color: red; }", ".red + span + span { color: red; }"];
-const blueStyleTexts = [".blue { color: blue; }", ".blue + span + span { color: blue; }"];
-const whiteStyleText = "* { color: white; }";
-const yellowStyleText = ".yellow { color: yellow; }";
 
 test(() => {
   // Style sheets can be created
-  const greenStyleSheet = new CSSStyleSheet(greenStyleText);
-  const redStyleSheet = new CSSStyleSheet(redStyleTexts[0] + redStyleTexts[1], {media: "screen, print"});
-  const blueStyleSheet = new CSSStyleSheet(blueStyleTexts[0] + blueStyleTexts[1], {title: "Blue", disabled: true});
-  const whiteStyleSheet = new CSSStyleSheet(whiteStyleText, {title: "White", alternate: true});
-  const yellowStyleSheet = new CSSStyleSheet(yellowStyleText, {disabled: false});
+const sheet = new CSSStyleSheet({title: "Red", disabled: true, media: "screen, print"});
+  assert_equals(sheet.title, "Red");
+  assert_equals(sheet.ownerNode, null);
+  assert_equals(sheet.ownerRule, null);
+  assert_equals(sheet.media.length, 2);
+  assert_equals(sheet.media.item(0), "screen");
+  assert_equals(sheet.media.item(1), "print");
+  assert_true(sheet.disabled);
+  assert_equals(sheet.cssRules.length, 0);
 
-  assert_equals(greenStyleSheet.title, "");
-  assert_equals(redStyleSheet.title, "");
-  assert_equals(blueStyleSheet.title, "Blue");
-  assert_equals(whiteStyleSheet.title, "White");
-  assert_equals(yellowStyleSheet.title, "");
+  sheet.insertRule(redStyleTexts[0]);
+  assert_equals(sheet.cssRules.length, 1);
+  assert_equals(sheet.cssRules[0].cssText, redStyleTexts[0]);
 
-  assert_equals(greenStyleSheet.ownerNode, null);
-  assert_equals(redStyleSheet.ownerNode, null);
-  assert_equals(blueStyleSheet.ownerNode, null);
-  assert_equals(whiteStyleSheet.ownerNode, null);
-  assert_equals(yellowStyleSheet.ownerNode, null);
-
-  assert_equals(greenStyleSheet.ownerRule, null);
-  assert_equals(redStyleSheet.ownerRule, null);
-  assert_equals(blueStyleSheet.ownerRule, null);
-  assert_equals(whiteStyleSheet.ownerRule, null);
-  assert_equals(yellowStyleSheet.ownerRule, null);
-
-  assert_equals(greenStyleSheet.media.length, 0);
-  assert_equals(redStyleSheet.media.length, 2);
-  assert_equals(redStyleSheet.media.item(0), "screen");
-  assert_equals(redStyleSheet.media.item(1), "print");
-  assert_equals(blueStyleSheet.media.length, 0);
-  assert_equals(whiteStyleSheet.media.length, 0);
-  assert_equals(yellowStyleSheet.media.length, 0);
-
-  assert_false(greenStyleSheet.disabled);
-  assert_false(redStyleSheet.disabled);
-  assert_true(blueStyleSheet.disabled);
-  assert_false(whiteStyleSheet.disabled);
-  assert_false(yellowStyleSheet.disabled);
-
-  assert_equals(greenStyleSheet.cssRules.length, 1);
-  assert_equals(redStyleSheet.cssRules.length, 2);
-  assert_equals(blueStyleSheet.cssRules.length, 2);
-  assert_equals(whiteStyleSheet.cssRules.length, 1);
-  assert_equals(yellowStyleSheet.cssRules.length, 1);
-
-  assert_equals(greenStyleSheet.cssRules[0].cssText, greenStyleText);
-  assert_equals(redStyleSheet.cssRules[0].cssText, redStyleTexts[0]);
-  assert_equals(redStyleSheet.cssRules[1].cssText, redStyleTexts[1]);
-  assert_equals(blueStyleSheet.cssRules[0].cssText, blueStyleTexts[0]);
-  assert_equals(blueStyleSheet.cssRules[1].cssText, blueStyleTexts[1]);
-  assert_equals(whiteStyleSheet.cssRules[0].cssText, whiteStyleText);
-  assert_equals(yellowStyleSheet.cssRules[0].cssText, yellowStyleText);
-
-}, 'Style sheets can be constructed using script');
+  sheet.insertRule(redStyleTexts[1]);
+  assert_equals(sheet.cssRules.length, 2);
+  assert_equals(sheet.cssRules[0].cssText, redStyleTexts[1]);
+}, 'Empty CSSStyleSheet can be constructed using script');
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt
index ee72f095..39d0f34 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt
@@ -74,7 +74,7 @@
 PASS TryAllocate('CSSRuleList') is 'exception'
 PASS TryAllocate('CSSStyleDeclaration') is 'exception'
 PASS TryAllocate('CSSStyleRule') is 'exception'
-PASS TryAllocate('CSSStyleSheet') is 'exception'
+FAIL TryAllocate('CSSStyleSheet') should be exception. Was [object CSSStyleSheet].
 PASS TryAllocate('DOMImplementation') is 'exception'
 PASS TryAllocate('HTMLCollection') is 'exception'
 PASS TryAllocate('MediaList') is 'exception'
diff --git a/third_party/WebKit/LayoutTests/fast/text/whitespace/nowrap-space-inside.html b/third_party/WebKit/LayoutTests/fast/text/whitespace/nowrap-space-inside.html
index 1423c2e4..5e720fc 100644
--- a/third_party/WebKit/LayoutTests/fast/text/whitespace/nowrap-space-inside.html
+++ b/third_party/WebKit/LayoutTests/fast/text/whitespace/nowrap-space-inside.html
@@ -1,47 +1,47 @@
-<!DOCTYPE html>

-<script src="../../../resources/testharness.js"></script>

-<script src="../../../resources/testharnessreport.js"></script>

-<style>

-.container {

-  width:200px;

-  background-color:#eee;

-}

-.spacer {

-  height:10px; background-color:black;

-}

-.nowrap {

-  white-space: nowrap;

-}

-</style>

-<body>

-<p>Spaces in nowrap shold not break when the text before it fits but the space overflows.</p>

-<template id=template>

-  <div class=container>

-    <img class=spacer />

-    <span class=nowrap><span>foo</span> <span>bar</span></span>

-  </div>

-</template>

-<script>

-run();

-function run() {

-  let tests = [];

-  for (let width = 170; width < 180; width++) {

-    let element = template.content.children[0].cloneNode(true);

-    let spacer = element.querySelector('img');

-    spacer.style.width = width + 'px';

-    document.body.appendChild(element);

-    tests.push({width: width, element: element});

-  }

-  let results = [];

-  for (let t of tests) {

-    test(() => {

-      let nowrap = t.element.querySelector('.nowrap');

-      let child1 = nowrap.children[0];

-      let child2 = nowrap.children[1];

-      assert_equals(child1.offsetTop, child2.offsetTop);

-    }, `width: ${t.width}`);

-  }

-}

-</script>

-</body>

-

+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<style>
+.container {
+  width:200px;
+  background-color:#eee;
+}
+.spacer {
+  height:10px; background-color:black;
+}
+.nowrap {
+  white-space: nowrap;
+}
+</style>
+<body>
+<p>Spaces in nowrap shold not break when the text before it fits but the space overflows.</p>
+<template id=template>
+  <div class=container>
+    <img class=spacer />
+    <span class=nowrap><span>foo</span> <span>bar</span></span>
+  </div>
+</template>
+<script>
+run();
+function run() {
+  let tests = [];
+  for (let width = 170; width < 180; width++) {
+    let element = template.content.children[0].cloneNode(true);
+    let spacer = element.querySelector('img');
+    spacer.style.width = width + 'px';
+    document.body.appendChild(element);
+    tests.push({width: width, element: element});
+  }
+  let results = [];
+  for (let t of tests) {
+    test(() => {
+      let nowrap = t.element.querySelector('.nowrap');
+      let child1 = nowrap.children[0];
+      let child2 = nowrap.children[1];
+      assert_equals(child1.offsetTop, child2.offsetTop);
+    }, `width: ${t.width}`);
+  }
+}
+</script>
+</body>
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/writing-mode/vertical-rl-replaced-selection-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/writing-mode/vertical-rl-replaced-selection-expected.png
new file mode 100644
index 0000000..474e7aaf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/writing-mode/vertical-rl-replaced-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-invoke-deferred-compositing-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-invoke-deferred-compositing-expected.txt
index 2a548f2..d09682c 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-invoke-deferred-compositing-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-invoke-deferred-compositing-expected.txt
@@ -29,7 +29,7 @@
         {
           "object": "LayoutHTMLCanvas (positioned) CANVAS",
           "rect": [0, 0, 200, 200],
-          "reason": "full"
+          "reason": "full layer"
         }
       ]
     }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-not-clip-composited-overflow-scrolling-layer-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-not-clip-composited-overflow-scrolling-layer-expected.txt
index afebcc86..4ddc99c 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-not-clip-composited-overflow-scrolling-layer-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/should-not-clip-composited-overflow-scrolling-layer-expected.txt
@@ -56,7 +56,7 @@
         {
           "object": "Horizontal Scrollbar Layer",
           "rect": [0, 0, 385, 15],
-          "reason": "full"
+          "reason": "full layer"
         }
       ]
     },
@@ -69,7 +69,7 @@
         {
           "object": "Vertical Scrollbar Layer",
           "rect": [0, 0, 15, 285],
-          "reason": "full"
+          "reason": "full layer"
         }
       ]
     },
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/text-match-highlight-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/text-match-highlight-expected.txt
new file mode 100644
index 0000000..07cdf74
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/text-match-highlight-expected.txt
@@ -0,0 +1,110 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "InlineTextBox 'Can you findme in this boring text?'",
+          "rect": [10, 135, 223, 19],
+          "reason": "DocumentMarker change"
+        },
+        {
+          "object": "InlineTextBox 'Findme on a path! Did you findme?'",
+          "rect": [20, 224, 182, 72],
+          "reason": "DocumentMarker change"
+        },
+        {
+          "object": "InlineTextBox 'Findme in a typewriter!'",
+          "rect": [10, 191, 138, 12],
+          "reason": "DocumentMarker change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [278, 40, 44, 19],
+          "reason": "DocumentMarker change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [264, 60, 44, 19],
+          "reason": "DocumentMarker change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [220, 60, 44, 19],
+          "reason": "DocumentMarker change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [89, 60, 44, 19],
+          "reason": "DocumentMarker change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [51, 80, 44, 19],
+          "reason": "DocumentMarker change"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "InlineTextBox 'Can you findme in this boring text?'",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "InlineTextBox 'Findme in a typewriter!'",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "DocumentMarker change"
+    },
+    {
+      "object": "InlineTextBox 'Findme on a path! Did you findme?'",
+      "reason": "DocumentMarker change"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/updating-scrolling-container-and-content-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/updating-scrolling-container-and-content-expected.txt
new file mode 100644
index 0000000..fc13236
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/compositing/updating-scrolling-container-and-content-expected.txt
@@ -0,0 +1,128 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 258, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 238, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 218, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 198, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 178, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 158, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 138, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 118, 77, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 278, 77, 15],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 108, 77, 9],
+          "reason": "style change"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/insert-frame-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/insert-frame-expected.txt
new file mode 100644
index 0000000..804cf332
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/insert-frame-expected.txt
@@ -0,0 +1,39 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "LayoutNGBlockFlow HTML",
+          "rect": [0, 0, 104, 104],
+          "reason": "chunk appeared"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "LayoutIFrame IFRAME",
+      "reason": "subtree"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/invalidation-after-opacity-change-subtree-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/invalidation-after-opacity-change-subtree-expected.txt
index 8fba1ef..6d55b9f 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/invalidation-after-opacity-change-subtree-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/invalidation-after-opacity-change-subtree-expected.txt
@@ -18,9 +18,9 @@
       "backgroundColor": "#FFFFFF",
       "paintInvalidations": [
         {
-          "object": "LayoutNGBlockFlow (positioned) DIV id='absolute'",
+          "object": "LayoutNGBlockFlow HTML",
           "rect": [8, 2046, 774, 257],
-          "reason": "appeared"
+          "reason": "chunk appeared"
         }
       ],
       "transform": 1
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/non-text-link-invalidation-optimization-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/non-text-link-invalidation-optimization-expected.txt
new file mode 100644
index 0000000..d4d9b1dc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/non-text-link-invalidation-optimization-expected.txt
@@ -0,0 +1,80 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [164, 8, 145, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [75, 8, 61, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 8, 57, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [353, 8, 52, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [136, 8, 28, 19],
+          "reason": "style change"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [319, 8, 24, 19],
+          "reason": "style change"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "style change"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/invalidate-after-composited-scroll-of-window-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/invalidate-after-composited-scroll-of-window-expected.txt
new file mode 100644
index 0000000..2f7b6f98
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/invalidate-after-composited-scroll-of-window-expected.txt
@@ -0,0 +1,53 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [785, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [785, 4936],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 4908, 540, 19],
+          "reason": "appeared"
+        },
+        {
+          "object": "LayoutNGBlockFlow DIV id='target'",
+          "rect": [8, 2408, 100, 100],
+          "reason": "style change"
+        }
+      ],
+      "transform": 1
+    }
+  ],
+  "transforms": [
+    {
+      "id": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [0, -2350, 0, 1]
+      ],
+      "flattenInheritedTransform": false
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutNGBlockFlow DIV id='target'",
+      "reason": "style change"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/line-in-scrolled-clipped-block-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/line-in-scrolled-clipped-block-expected.png
new file mode 100644
index 0000000..1706fc58
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/line-in-scrolled-clipped-block-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/line-in-scrolled-clipped-block-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/line-in-scrolled-clipped-block-expected.txt
new file mode 100644
index 0000000..6157bb7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/line-in-scrolled-clipped-block-expected.txt
@@ -0,0 +1,44 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 8, 100, 19],
+          "reason": "chunk appeared"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 8, 100, 19],
+          "reason": "chunk disappeared"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/resize-scrollable-iframe-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/resize-scrollable-iframe-expected.txt
index eadd3f8..60b62bc7 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/resize-scrollable-iframe-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/resize-scrollable-iframe-expected.txt
@@ -50,7 +50,7 @@
         {
           "object": "LayoutView #document",
           "rect": [8, 108, 300, 300],
-          "reason": "geometry"
+          "reason": "subtree"
         },
         {
           "object": "HorizontalScrollbar",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/animated-path-inside-transformed-html-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/animated-path-inside-transformed-html-expected.png
new file mode 100644
index 0000000..41c236d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/animated-path-inside-transformed-html-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/animated-path-inside-transformed-html-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/animated-path-inside-transformed-html-expected.txt
new file mode 100644
index 0000000..c68dcc8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/svg/animated-path-inside-transformed-html-expected.txt
@@ -0,0 +1,80 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "InlineTextBox 'This is some text'",
+          "rect": [246, 89, 127, 46],
+          "reason": "disappeared"
+        },
+        {
+          "object": "InlineTextBox 'This is some text'",
+          "rect": [203, 336, 126, 45],
+          "reason": "appeared"
+        },
+        {
+          "object": "LayoutSVGRect rect id='rect'",
+          "rect": [108, 84, 105, 102],
+          "reason": "full"
+        },
+        {
+          "object": "LayoutSVGRect rect id='rect'",
+          "rect": [355, 125, 104, 104],
+          "reason": "full"
+        },
+        {
+          "object": "LayoutSVGImage image id='image'",
+          "rect": [352, 398, 99, 98],
+          "reason": "full"
+        },
+        {
+          "object": "LayoutSVGImage image id='image'",
+          "rect": [90, 207, 98, 99],
+          "reason": "full"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutSVGRect rect id='rect'",
+      "reason": "full"
+    },
+    {
+      "object": "LayoutSVGText text id='text'",
+      "reason": "full"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "full"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "geometry"
+    },
+    {
+      "object": "InlineTextBox 'This is some text'",
+      "reason": "geometry"
+    },
+    {
+      "object": "LayoutSVGImage image id='image'",
+      "reason": "full"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/composited-table-row-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/composited-table-row-expected.txt
index f46ec95..69b4408 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/composited-table-row-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/composited-table-row-expected.txt
@@ -24,7 +24,7 @@
       "backgroundColor": "#FF0000",
       "paintInvalidations": [
         {
-          "object": "LayoutTableRow TR",
+          "object": "NGPaintFragment",
           "rect": [0, 0, 37, 23],
           "reason": "appeared"
         }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/text-match-document-change-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/text-match-document-change-expected.txt
index e7f3568..ec76613 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/text-match-document-change-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/text-match-document-change-expected.txt
@@ -70,10 +70,6 @@
     {
       "object": "NGPaintFragment",
       "reason": "subtree"
-    },
-    {
-      "object": "LayoutNGBlockFlow DIV",
-      "reason": "geometry"
     }
   ]
 }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.png
new file mode 100644
index 0000000..b12f7a2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.txt
new file mode 100644
index 0000000..5aab8fe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.txt
@@ -0,0 +1,54 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (474,0) size 326x166
+  LayoutNGBlockFlow {HTML} at (0,0) size 326x166
+    LayoutNGBlockFlow {BODY} at (8,8) size 310x150
+      LayoutNGBlockFlow (anonymous) at (90,0) size 20x150
+        LayoutBR {BR} at (1,0) size 0x0
+      LayoutNGBlockFlow (anonymous) at (200,0) size 20x150
+        LayoutBR {BR} at (1,0) size 0x0
+layer at (762,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (0,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (732,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (30,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (702,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (60,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (652,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (110,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (622,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (140,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (592,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (170,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (542,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (220,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (512,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (250,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
+layer at (482,8) size 30x150 scrollHeight 216
+  LayoutNGBlockFlow {DIV} at (280,0) size 30x150
+    LayoutText {#text} at (3,0) size 27x147
+      text run at (3,0) width 132: "ppppppppppp"
+      text run at (3,132) width 15: "..."
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/127.0.0.1.sxg.pem.cbor b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/127.0.0.1.sxg.pem.cbor
index 6485caa3..9e218d0b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/127.0.0.1.sxg.pem.cbor
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/127.0.0.1.sxg.pem.cbor
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
index 03b69895f..5c90f8b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-invalid-validity-url.sxg b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-invalid-validity-url.sxg
index a5921d20..26221fd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-invalid-validity-url.sxg
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-invalid-validity-url.sxg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
index 8aefd59..247fff1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-header-same-origin-get-async-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-header-same-origin-get-async-expected.txt
index c2775d9..52db1b3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-header-same-origin-get-async-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/origin-header-same-origin-get-async-expected.txt
@@ -1,4 +1,4 @@
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: 

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: 
 
 
diff --git a/third_party/WebKit/LayoutTests/paint/markers/vertical-rl-expected.png b/third_party/WebKit/LayoutTests/paint/markers/vertical-rl-expected.png
new file mode 100644
index 0000000..6d336ab6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/markers/vertical-rl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/markers/vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/paint/markers/vertical-rl-expected.txt
new file mode 100644
index 0000000..e06c250
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/markers/vertical-rl-expected.txt
@@ -0,0 +1,45 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (474,0) size 326x166
+  LayoutBlockFlow {HTML} at (0,0) size 326x166
+    LayoutBlockFlow {BODY} at (8,8) size 310x150
+      LayoutBlockFlow (anonymous) at (90,0) size 20x150
+        LayoutBR {BR} at (0,0) size 19x0
+      LayoutBlockFlow (anonymous) at (200,0) size 20x150
+        LayoutBR {BR} at (0,0) size 19x0
+layer at (762,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (0,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (732,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (30,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (702,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (60,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (652,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (110,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (622,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (140,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (592,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (170,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (542,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (220,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (512,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (250,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
+layer at (482,8) size 30x150 scrollHeight 216
+  LayoutBlockFlow {DIV} at (280,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x216
+      text run at (0,0) width 216: "pppppppppppppppppp"
diff --git a/third_party/WebKit/LayoutTests/paint/markers/vertical-rl.html b/third_party/WebKit/LayoutTests/paint/markers/vertical-rl.html
new file mode 100644
index 0000000..91c8043
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/markers/vertical-rl.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<script src="../../resources/ahem.js"></script>
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+<style>
+  @font-face {
+    font-family: 'testFont';
+    src: url('../../resources/opensans/OpenSans-Regular.woff') format("woff");
+  }
+
+  body {
+    writing-mode: vertical-rl;
+  }
+  div {
+    width: 30px;
+    height: 150px;
+    font: 20px testFont;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: pre;
+  }
+</style>
+
+<div id="markAllComposition">pppppppppppppppppp</div>
+<div id="markStartComposition">pppppppppppppppppp</div>
+<div id="markEndComposition">pppppppppppppppppp</div>
+<br>
+<div id="markAllSpelling">pppppppppppppppppp</div>
+<div id="markStartSpelling">pppppppppppppppppp</div>
+<div id="markEndSpelling">pppppppppppppppppp</div>
+<br>
+<div id="markAllTextMatch">pppppppppppppppppp</div>
+<div id="markStartTextMatch">pppppppppppppppppp</div>
+<div id="markEndTextMatch">pppppppppppppppppp</div>
+
+<script>
+function addCompositionMarker(elem, start, end) {
+    const range = document.createRange();
+    const textNode = elem.firstChild;
+    range.setStart(textNode, start);
+    range.setEnd(textNode, end);
+    if (typeof internals !== 'undefined')
+        internals.addCompositionMarker(range, 'orange', 'thin', 'lightBlue');
+};
+
+function addSpellingMarker(elem, start, end) {
+    const range = document.createRange();
+    const textNode = elem.firstChild;
+    range.setStart(textNode, start);
+    range.setEnd(textNode, end);
+    if (typeof internals !== 'undefined')
+        internals.setMarker(document, range, 'spelling');
+};
+
+function addTextMatchMarker(elem, start, end) {
+    const range = document.createRange();
+    const textNode = elem.firstChild;
+    range.setStart(textNode, start);
+    range.setEnd(textNode, end);
+    if (typeof internals !== 'undefined') {
+        internals.addTextMatchMarker(range, 'kActive');
+        internals.setMarkedTextMatchesAreHighlighted(document, true);
+    }
+};
+
+onload = runAfterLayoutAndPaint(function() {
+    addCompositionMarker(markAllComposition, 0, 18);
+    addCompositionMarker(markStartComposition, 0, 9);
+    addCompositionMarker(markEndComposition, 7, 18);
+
+    addSpellingMarker(markAllSpelling, 0, 15);
+    addSpellingMarker(markStartSpelling, 0, 9);
+    addSpellingMarker(markEndSpelling, 7, 15);
+
+    addTextMatchMarker(markAllTextMatch, 0, 16);
+    addTextMatchMarker(markStartTextMatch, 0, 9);
+    addTextMatchMarker(markEndTextMatch, 7, 16);
+}, true);
+</script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/markers/vertical-rl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/markers/vertical-rl-expected.png
new file mode 100644
index 0000000..b073aa2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/markers/vertical-rl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
index db787c8..920160da 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 584 tests; 406 PASS, 178 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 578 tests; 401 PASS, 177 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testAccumulation function
 PASS align-content: "flex-end" onto "flex-start"
@@ -200,9 +200,6 @@
 PASS cursor (type: discrete) has testAccumulation function
 PASS cursor: "wait" onto "pointer"
 PASS cursor: "pointer" onto "wait"
-PASS direction (type: discrete) has testAccumulation function
-PASS direction: "rtl" onto "ltr"
-PASS direction: "ltr" onto "rtl"
 PASS dominant-baseline (type: discrete) has testAccumulation function
 PASS dominant-baseline: "alphabetic" onto "ideographic"
 PASS dominant-baseline: "ideographic" onto "alphabetic"
@@ -581,8 +578,5 @@
 PASS will-change (type: discrete) has testAccumulation function
 PASS will-change: "contents" onto "scroll-position"
 PASS will-change: "scroll-position" onto "contents"
-PASS writing-mode (type: discrete) has testAccumulation function
-FAIL writing-mode: "sideways-rl" onto "vertical-rl" assert_equals: The value should be sideways-rl at 0ms expected "sideways-rl" but got "vertical-rl"
-PASS writing-mode: "vertical-rl" onto "sideways-rl"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
index dede9a2..b6327c10 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 580 tests; 538 PASS, 42 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 574 tests; 533 PASS, 41 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testAddition function
 PASS align-content: "flex-end" onto "flex-start"
@@ -200,9 +200,6 @@
 PASS cursor (type: discrete) has testAddition function
 PASS cursor: "wait" onto "pointer"
 PASS cursor: "pointer" onto "wait"
-PASS direction (type: discrete) has testAddition function
-PASS direction: "rtl" onto "ltr"
-PASS direction: "ltr" onto "rtl"
 PASS dominant-baseline (type: discrete) has testAddition function
 PASS dominant-baseline: "alphabetic" onto "ideographic"
 PASS dominant-baseline: "ideographic" onto "alphabetic"
@@ -577,8 +574,5 @@
 PASS will-change (type: discrete) has testAddition function
 PASS will-change: "contents" onto "scroll-position"
 PASS will-change: "scroll-position" onto "contents"
-PASS writing-mode (type: discrete) has testAddition function
-FAIL writing-mode: "sideways-rl" onto "vertical-rl" assert_equals: The value should be sideways-rl at 0ms expected "sideways-rl" but got "vertical-rl"
-PASS writing-mode: "vertical-rl" onto "sideways-rl"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
index 0ef9c47..3379b81 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 724 tests; 647 PASS, 77 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 716 tests; 642 PASS, 74 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testInterpolation function
 PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
@@ -244,10 +244,6 @@
 PASS cursor uses discrete animation when animating between "pointer" and "wait" with linear easing
 PASS cursor uses discrete animation when animating between "pointer" and "wait" with effect easing
 PASS cursor uses discrete animation when animating between "pointer" and "wait" with keyframe easing
-PASS direction (type: discrete) has testInterpolation function
-PASS direction uses discrete animation when animating between "ltr" and "rtl" with linear easing
-PASS direction uses discrete animation when animating between "ltr" and "rtl" with effect easing
-PASS direction uses discrete animation when animating between "ltr" and "rtl" with keyframe easing
 PASS dominant-baseline (type: discrete) has testInterpolation function
 PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with linear easing
 PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with effect easing
@@ -720,9 +716,5 @@
 PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with linear easing
 PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with effect easing
 PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with keyframe easing
-PASS writing-mode (type: discrete) has testInterpolation function
-FAIL writing-mode uses discrete animation when animating between "vertical-rl" and "sideways-rl" with linear easing assert_equals: The value should be sideways-rl at 500ms expected "sideways-rl" but got "horizontal-tb"
-FAIL writing-mode uses discrete animation when animating between "vertical-rl" and "sideways-rl" with effect easing assert_equals: The value should be sideways-rl at 960ms expected "sideways-rl" but got "horizontal-tb"
-FAIL writing-mode uses discrete animation when animating between "vertical-rl" and "sideways-rl" with keyframe easing assert_equals: The value should be sideways-rl at 960ms expected "sideways-rl" but got "horizontal-tb"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/markers/vertical-rl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/markers/vertical-rl-expected.png
new file mode 100644
index 0000000..c0b9ea5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/markers/vertical-rl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/markers/vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/markers/vertical-rl-expected.txt
new file mode 100644
index 0000000..46ec730
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/markers/vertical-rl-expected.txt
@@ -0,0 +1,45 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (478,0) size 322x166
+  LayoutBlockFlow {HTML} at (0,0) size 322x166
+    LayoutBlockFlow {BODY} at (8,8) size 306x150
+      LayoutBlockFlow (anonymous) at (90,0) size 18x150
+        LayoutBR {BR} at (0,0) size 18x0
+      LayoutBlockFlow (anonymous) at (198,0) size 18x150
+        LayoutBR {BR} at (0,0) size 18x0
+layer at (762,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (0,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (732,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (30,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (702,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (60,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (654,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (108,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (624,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (138,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (594,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (168,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (546,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (216,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (516,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (246,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
+layer at (486,8) size 30x150 scrollHeight 221
+  LayoutBlockFlow {DIV} at (276,0) size 30x150
+    LayoutText {#text} at (0,0) size 27x221
+      text run at (0,0) width 221: "pppppppppppppppppp"
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
index 66670b8..758196f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 584 tests; 405 PASS, 179 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 578 tests; 400 PASS, 178 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testAccumulation function
 PASS align-content: "flex-end" onto "flex-start"
@@ -200,9 +200,6 @@
 PASS cursor (type: discrete) has testAccumulation function
 PASS cursor: "wait" onto "pointer"
 PASS cursor: "pointer" onto "wait"
-PASS direction (type: discrete) has testAccumulation function
-PASS direction: "rtl" onto "ltr"
-PASS direction: "ltr" onto "rtl"
 PASS dominant-baseline (type: discrete) has testAccumulation function
 PASS dominant-baseline: "alphabetic" onto "ideographic"
 PASS dominant-baseline: "ideographic" onto "alphabetic"
@@ -581,8 +578,5 @@
 PASS will-change (type: discrete) has testAccumulation function
 PASS will-change: "contents" onto "scroll-position"
 PASS will-change: "scroll-position" onto "contents"
-PASS writing-mode (type: discrete) has testAccumulation function
-FAIL writing-mode: "sideways-rl" onto "vertical-rl" assert_equals: The value should be sideways-rl at 0ms expected "sideways-rl" but got "vertical-rl"
-PASS writing-mode: "vertical-rl" onto "sideways-rl"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
index 47996ff..0bdad94 100644
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 580 tests; 537 PASS, 43 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 574 tests; 532 PASS, 42 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testAddition function
 PASS align-content: "flex-end" onto "flex-start"
@@ -200,9 +200,6 @@
 PASS cursor (type: discrete) has testAddition function
 PASS cursor: "wait" onto "pointer"
 PASS cursor: "pointer" onto "wait"
-PASS direction (type: discrete) has testAddition function
-PASS direction: "rtl" onto "ltr"
-PASS direction: "ltr" onto "rtl"
 PASS dominant-baseline (type: discrete) has testAddition function
 PASS dominant-baseline: "alphabetic" onto "ideographic"
 PASS dominant-baseline: "ideographic" onto "alphabetic"
@@ -577,8 +574,5 @@
 PASS will-change (type: discrete) has testAddition function
 PASS will-change: "contents" onto "scroll-position"
 PASS will-change: "scroll-position" onto "contents"
-PASS writing-mode (type: discrete) has testAddition function
-FAIL writing-mode: "sideways-rl" onto "vertical-rl" assert_equals: The value should be sideways-rl at 0ms expected "sideways-rl" but got "vertical-rl"
-PASS writing-mode: "vertical-rl" onto "sideways-rl"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
index 3d743ab..dd7bded 100644
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 724 tests; 644 PASS, 80 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 716 tests; 639 PASS, 77 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testInterpolation function
 PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
@@ -244,10 +244,6 @@
 PASS cursor uses discrete animation when animating between "pointer" and "wait" with linear easing
 PASS cursor uses discrete animation when animating between "pointer" and "wait" with effect easing
 PASS cursor uses discrete animation when animating between "pointer" and "wait" with keyframe easing
-PASS direction (type: discrete) has testInterpolation function
-PASS direction uses discrete animation when animating between "ltr" and "rtl" with linear easing
-PASS direction uses discrete animation when animating between "ltr" and "rtl" with effect easing
-PASS direction uses discrete animation when animating between "ltr" and "rtl" with keyframe easing
 PASS dominant-baseline (type: discrete) has testInterpolation function
 PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with linear easing
 PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with effect easing
@@ -720,9 +716,5 @@
 PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with linear easing
 PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with effect easing
 PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with keyframe easing
-PASS writing-mode (type: discrete) has testInterpolation function
-FAIL writing-mode uses discrete animation when animating between "vertical-rl" and "sideways-rl" with linear easing assert_equals: The value should be sideways-rl at 500ms expected "sideways-rl" but got "horizontal-tb"
-FAIL writing-mode uses discrete animation when animating between "vertical-rl" and "sideways-rl" with effect easing assert_equals: The value should be sideways-rl at 960ms expected "sideways-rl" but got "horizontal-tb"
-FAIL writing-mode uses discrete animation when animating between "vertical-rl" and "sideways-rl" with keyframe easing assert_equals: The value should be sideways-rl at 960ms expected "sideways-rl" but got "horizontal-tb"
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt b/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt
index 55764c5..7386346 100644
--- a/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 13: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: http://127.0.0.1:8000

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: http://127.0.0.1:8000
 
 
diff --git a/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-same-origin-post-async-expected.txt b/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-same-origin-post-async-expected.txt
index 53d9dc8..85f9a5c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-same-origin-post-async-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/http/tests/xmlhttprequest/origin-header-same-origin-post-async-expected.txt
@@ -1,4 +1,4 @@
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: http://127.0.0.1:8000

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: http://127.0.0.1:8000
 
 
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt
index 55764c5..7386346 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 13: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: http://127.0.0.1:8000

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: http://127.0.0.1:8000
 
 
diff --git a/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt
index 55764c5..7386346 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 13: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: http://127.0.0.1:8000

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: http://127.0.0.1:8000
 
 
diff --git a/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt
index 55764c5..7386346 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win7/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 13: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: http://127.0.0.1:8000

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: http://127.0.0.1:8000
 
 
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt
index 55764c5..7386346 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-same-origin-post-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 13: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: http://127.0.0.1:8000

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: http://127.0.0.1:8000
 
 
diff --git a/third_party/WebKit/LayoutTests/svg/custom/pattern-inherit-remove-and-reattach.html b/third_party/WebKit/LayoutTests/svg/custom/pattern-inherit-remove-and-reattach.html
index e750f0d..e31b421 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/pattern-inherit-remove-and-reattach.html
+++ b/third_party/WebKit/LayoutTests/svg/custom/pattern-inherit-remove-and-reattach.html
@@ -1,21 +1,21 @@
-<!DOCTYPE html>

-<svg>

-  <defs>

-    <pattern width="100" height="100" id="ref_pattern1" patternUnits="userSpaceOnUse">

-      <rect width="100" height="100" fill="red"/>

-    </pattern>

-    <pattern href="#ref_pattern1" id="pattern1"></pattern>

-  </defs>

-  <rect width="100" height="100" fill="url(#pattern1) green"/>

-</svg>

-<script>

-document.addEventListener("DOMContentLoaded", function() {

-  document.documentElement.offsetTop;

-

-  let ref_pattern1 = document.getElementById("ref_pattern1");

-  ref_pattern1.style.display = "inline-block";

-

-  let pattern1 = document.getElementById("pattern1");

-  pattern1.removeAttribute('href');

-}, false);

-</script>

+<!DOCTYPE html>
+<svg>
+  <defs>
+    <pattern width="100" height="100" id="ref_pattern1" patternUnits="userSpaceOnUse">
+      <rect width="100" height="100" fill="red"/>
+    </pattern>
+    <pattern href="#ref_pattern1" id="pattern1"></pattern>
+  </defs>
+  <rect width="100" height="100" fill="url(#pattern1) green"/>
+</svg>
+<script>
+document.addEventListener("DOMContentLoaded", function() {
+  document.documentElement.offsetTop;
+
+  let ref_pattern1 = document.getElementById("ref_pattern1");
+  ref_pattern1.style.display = "inline-block";
+
+  let pattern1 = document.getElementById("pattern1");
+  pattern1.removeAttribute('href');
+}, false);
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt b/third_party/WebKit/LayoutTests/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt
index 55764c5..7386346 100644
--- a/third_party/WebKit/LayoutTests/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/outofblink-cors/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync-expected.txt
@@ -1,5 +1,5 @@
 CONSOLE WARNING: line 13: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-PASS: Cross-domain access allowed.

-HTTP_ORIGIN: http://127.0.0.1:8000

+PASS: Cross-domain access allowed.
+HTTP_ORIGIN: http://127.0.0.1:8000
 
 
diff --git a/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char-expected.html b/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char-expected.html
index dc94de2..15965d1 100644
--- a/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char-expected.html
+++ b/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char-expected.html
@@ -1,8 +1,8 @@
-<!doctype html>

-<html xmlns:v="urn:schemas-microsoft-com:vml">

-  <head>

-  </head>

-  <body id="test-body">

-    Test passes if you see this line, and this line alone.

-  </body>

-</html>

+<!doctype html>
+<html xmlns:v="urn:schemas-microsoft-com:vml">
+  <head>
+  </head>
+  <body id="test-body">
+    Test passes if you see this line, and this line alone.
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char.xml b/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char.xml
index 85c4e3e..a757b877 100644
--- a/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char.xml
+++ b/third_party/WebKit/LayoutTests/xmlviewer/long-multi-byte-char.xml
@@ -1,100 +1,100 @@
-<?xml version="1.0" encoding="windows-1251"?>

-<?xml-stylesheet type="text/xsl" href="resources/long-multi-byte-char.xslt"?>

-<home>

-  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vulputate odio ut enim blandit volutpat maecenas volutpat blandit aliquam. Ornare aenean euismod elementum nisi quis eleifend quam. Urna et pharetra pharetra massa massa ultricies mi quis. Id nibh tortor id aliquet lectus proin nibh nisl. Elementum eu facilisis sed odio morbi. Nibh nisl condimentum id venenatis a condimentum vitae sapien. Aliquam vestibulum morbi blandit cursus risus at ultrices. At tellus at urna condimentum mattis pellentesque id nibh tortor. Tortor id aliquet lectus proin nibh nisl condimentum id. Nulla malesuada pellentesque elit eget. Porta nibh venenatis cras sed felis eget. Volutpat est velit egestas dui id ornare. Donec ac odio tempor orci. Lectus mauris ultrices eros in. Amet dictum sit amet justo. Facilisis magna etiam tempor orci eu lobortis elementum. Pellentesque dignissim enim sit amet venenatis urna cursus eget. Sit amet facilisis magna etiam tempor. Ornare arcu odio ut sem nulla pharetra.

-

-  Porttitor massa id neque aliquam vestibulum morbi. Euismod lacinia at quis risus sed vulputate odio ut. Massa id neque aliquam vestibulum morbi blandit cursus. Tristique magna sit amet purus gravida. Felis eget nunc lobortis mattis. Placerat orci nulla pellentesque dignissim. Malesuada bibendum arcu vitae elementum curabitur vitae nunc. Fames ac turpis egestas sed. Felis eget nunc lobortis mattis aliquam. Ut faucibus pulvinar elementum integer enim neque volutpat ac. Sollicitudin tempor id eu nisl nunc mi ipsum. Platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras. Maecenas volutpat blandit aliquam etiam erat velit. Donec massa sapien faucibus et.

-

-  Duis ultricies lacus sed turpis tincidunt id aliquet risus. In tellus integer feugiat scelerisque varius morbi. Sit amet tellus cras adipiscing enim eu. Mi eget mauris pharetra et ultrices. Volutpat lacus laoreet non curabitur gravida arcu ac. Euismod quis viverra nibh cras pulvinar mattis nunc sed. In eu mi bibendum neque egestas. Fames ac turpis egestas maecenas pharetra convallis. Iaculis at erat pellentesque adipiscing commodo elit at imperdiet dui. Dui ut ornare lectus sit amet. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Fermentum posuere urna nec tincidunt praesent semper feugiat nibh. Nec feugiat nisl pretium fusce id velit ut tortor pretium. Rhoncus mattis rhoncus urna neque viverra justo nec ultrices dui. Aenean pharetra magna ac placerat vestibulum lectus mauris ultrices eros. Erat nam at lectus urna duis convallis convallis. Tristique senectus et netus et malesuada fames ac. Purus in massa tempor nec feugiat nisl pretium fusce id. Et magnis dis parturient montes nascetur ridiculus.

-

-  At elementum eu facilisis sed odio morbi. Interdum velit laoreet id donec ultrices tincidunt arcu non sodales. Sapien nec sagittis aliquam malesuada bibendum. Viverra mauris in aliquam sem fringilla ut. Amet nulla facilisi morbi tempus iaculis urna id volutpat lacus. Mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus. Bibendum at varius vel pharetra vel turpis nunc eget. Arcu non odio euismod lacinia at quis risus. In massa tempor nec feugiat nisl pretium fusce id velit. Sem et tortor consequat id porta nibh venenatis cras sed. Amet risus nullam eget felis eget nunc. Imperdiet proin fermentum leo vel orci porta non pulvinar. Ac auctor augue mauris augue neque. Tellus at urna condimentum mattis. Amet luctus venenatis lectus magna fringilla urna porttitor. Tincidunt praesent semper feugiat nibh sed pulvinar.

-

-  Faucibus scelerisque eleifend donec pretium vulputate sapien nec sagittis. Elit at imperdiet dui accumsan sit amet nulla. Ut consequat semper viverra nam libero justo laoreet sit. Morbi tincidunt augue interdum velit euismod in. Platea dictumst vestibulum rhoncus est. Sem et tortor consequat id porta nibh. Tristique risus nec feugiat in fermentum posuere. Nibh cras pulvinar mattis nunc sed blandit libero volutpat sed. Velit egestas dui id ornare arcu. Amet commodo nulla facilisi nullam vehicula ipsum a arcu. Venenatis tellus in metus vulputate eu. Sollicitudin ac orci phasellus egestas tellus rutrum tellus. Faucibus nisl tincidunt eget nullam. Et netus et malesuada fames ac turpis egestas maecenas. Diam quam nulla porttitor massa id neque aliquam vestibulum.

-

-  Ac turpis egestas integer eget aliquet nibh praesent tristique magna. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras. Risus pretium quam vulputate dignissim suspendisse in. Nunc sed id semper risus in hendrerit gravida rutrum. Interdum velit euismod in pellentesque massa placerat duis. Amet mauris commodo quis imperdiet massa tincidunt. Urna duis convallis convallis tellus id. Aliquam vestibulum morbi blandit cursus. Magna ac placerat vestibulum lectus mauris ultrices eros in cursus. Vitae et leo duis ut diam. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Faucibus nisl tincidunt eget nullam non nisi est sit amet.

-

-  Vel risus commodo viverra maecenas accumsan lacus. Magna sit amet purus gravida quis blandit. Purus non enim praesent elementum facilisis leo. Purus sit amet luctus venenatis lectus magna fringilla urna porttitor. Cursus sit amet dictum sit. Tellus cras adipiscing enim eu turpis egestas pretium. Tempus imperdiet nulla malesuada pellentesque elit. Etiam non quam lacus suspendisse faucibus interdum posuere. Tempus quam pellentesque nec nam aliquam sem et. Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Maecenas sed enim ut sem. Amet venenatis urna cursus eget nunc scelerisque. Curabitur vitae nunc sed velit. Risus feugiat in ante metus dictum. Auctor elit sed vulputate mi sit amet mauris commodo. Quam adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus urna. Nibh sed pulvinar proin gravida hendrerit. Suscipit adipiscing bibendum est ultricies integer quis auctor. Odio facilisis mauris sit amet.

-

-  Turpis egestas integer eget aliquet nibh. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Adipiscing elit duis tristique sollicitudin nibh sit amet. Nec feugiat nisl pretium fusce id. Fames ac turpis egestas integer. In dictum non consectetur a erat nam at lectus. Interdum velit euismod in pellentesque massa placerat duis ultricies. Enim facilisis gravida neque convallis a cras semper auctor neque. Condimentum lacinia quis vel eros donec ac odio tempor orci. Quam id leo in vitae turpis massa sed elementum. Mauris pharetra et ultrices neque ornare aenean.

-

-  Pulvinar sapien et ligula ullamcorper malesuada proin libero nunc consequat. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Placerat orci nulla pellentesque dignissim enim sit amet venenatis. Dignissim sodales ut eu sem integer. Amet consectetur adipiscing elit pellentesque habitant morbi tristique senectus. Dignissim enim sit amet venenatis urna cursus. Nisl vel pretium lectus quam. Quis risus sed vulputate odio ut. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus interdum. Faucibus et molestie ac feugiat sed. Mauris cursus mattis molestie a iaculis at erat pellentesque. Odio aenean sed adipiscing diam donec adipiscing tristique risus. Metus aliquam eleifend mi in nulla posuere sollicitudin aliquam. Pulvinar mattis nunc sed blandit libero volutpat sed cras. Massa placerat duis ultricies lacus.

-

-  Tellus id interdum velit laoreet. Sed faucibus turpis in eu mi bibendum neque egestas. Proin sagittis nisl rhoncus mattis. Arcu vitae elementum curabitur vitae nunc sed. Amet risus nullam eget felis eget nunc. Lacinia quis vel eros donec ac odio tempor. Enim eu turpis egestas pretium aenean pharetra magna ac. Suspendisse sed nisi lacus sed viverra tellus in hac. At volutpat diam ut venenatis tellus in metus vulputate. Ornare arcu odio ut sem nulla pharetra diam sit amet. Quis hendrerit dolor magna eget est. Pellentesque massa placerat duis ultricies lacus sed turpis.

-

-  Magna eget est lorem ipsum dolor sit amet consectetur adipiscing. At varius vel pharetra vel turpis nunc. Dis parturient montes nascetur ridiculus mus mauris vitae. Quam vulputate dignissim suspendisse in est ante. Neque convallis a cras semper auctor neque. Donec ultrices tincidunt arcu non sodales neque sodales ut etiam. Urna nunc id cursus metus aliquam eleifend mi in nulla. Nunc sed velit dignissim sodales ut eu sem integer vitae. Auctor eu augue ut lectus arcu. Nunc sed velit dignissim sodales ut. Cum sociis natoque penatibus et magnis dis parturient montes.

-

-  Neque aliquam vestibulum morbi blandit. Urna condimentum mattis pellentesque id. Dapibus ultrices in iaculis nunc sed augue lacus viverra. Dictum sit amet justo donec enim diam. Sit amet nulla facilisi morbi tempus. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Lacus sed turpis tincidunt id aliquet risus feugiat in ante. Sed viverra ipsum nunc aliquet bibendum enim facilisis. Consequat interdum varius sit amet mattis vulputate enim. Cum sociis natoque penatibus et magnis dis. Cursus mattis molestie a iaculis at erat. Sed sed risus pretium quam. Scelerisque fermentum dui faucibus in. Feugiat nisl pretium fusce id velit. Orci a scelerisque purus semper eget duis. Adipiscing at in tellus integer feugiat.

-

-  Dui faucibus in ornare quam viverra orci. Aliquam eleifend mi in nulla posuere. Eleifend quam adipiscing vitae proin sagittis. Amet commodo nulla facilisi nullam vehicula. Interdum consectetur libero id faucibus nisl tincidunt eget nullam. Leo vel orci porta non pulvinar neque laoreet suspendisse interdum. Posuere sollicitudin aliquam ultrices sagittis orci a. Nec ultrices dui sapien eget mi proin. Sodales neque sodales ut etiam sit amet. Ac placerat vestibulum lectus mauris ultrices eros in cursus. Amet facilisis magna etiam tempor orci.

-

-  Auctor eu augue ut lectus arcu bibendum at varius vel. Aliquam ultrices sagittis orci a scelerisque purus semper eget duis. Volutpat ac tincidunt vitae semper. Ornare lectus sit amet est placerat in egestas. Ac orci phasellus egestas tellus rutrum tellus pellentesque. Ullamcorper malesuada proin libero nunc consequat. Eget est lorem ipsum dolor sit amet. Et netus et malesuada fames ac turpis egestas. Donec massa sapien faucibus et molestie ac. Laoreet sit amet cursus sit amet dictum. Eget nullam non nisi est sit amet facilisis magna etiam. At tempor commodo ullamcorper a lacus vestibulum sed arcu non. Eget nulla facilisi etiam dignissim diam quis enim.

-

-  Ante metus dictum at tempor commodo ullamcorper. Ultricies mi quis hendrerit dolor magna eget est lorem ipsum. Nunc sed blandit libero volutpat. Tristique senectus et netus et. Nisi lacus sed viverra tellus in hac habitasse platea dictumst. Elementum facilisis leo vel fringilla. Lacus viverra vitae congue eu. Nisl condimentum id venenatis a condimentum vitae. Ipsum a arcu cursus vitae congue mauris rhoncus aenean vel. Felis imperdiet proin fermentum leo vel orci porta. Malesuada fames ac turpis egestas sed tempus. Aenean et tortor at risus viverra adipiscing at. Ultrices sagittis orci a scelerisque purus semper.

-

-  Orci eu lobortis elementum nibh tellus molestie nunc non blandit. Vel pharetra vel turpis nunc eget lorem. Diam maecenas ultricies mi eget. Consectetur libero id faucibus nisl tincidunt eget nullam non. Sit amet purus gravida quis blandit turpis cursus. Eget est lorem ipsum dolor sit amet consectetur. Pellentesque habitant morbi tristique senectus et netus. Nunc mattis enim ut tellus elementum sagittis vitae et leo. Laoreet id donec ultrices tincidunt arcu. Tellus id interdum velit laoreet id donec ultrices. Et netus et malesuada fames ac turpis egestas sed tempus. Viverra ipsum nunc aliquet bibendum enim. Mauris commodo quis imperdiet massa tincidunt nunc pulvinar sapien et. Diam vulputate ut pharetra sit amet aliquam. Eu tincidunt tortor aliquam nulla facilisi cras fermentum.

-

-  Massa sapien faucibus et molestie ac feugiat. Eget egestas purus viverra accumsan in nisl. Metus dictum at tempor commodo ullamcorper a lacus. Tempus imperdiet nulla malesuada pellentesque elit. At erat pellentesque adipiscing commodo elit at imperdiet. Lectus quam id leo in vitae turpis. Donec ultrices tincidunt arcu non sodales neque sodales. Semper eget duis at tellus at urna. Elementum sagittis vitae et leo duis ut. Imperdiet sed euismod nisi porta. Odio eu feugiat pretium nibh ipsum consequat nisl. Sit amet nulla facilisi morbi tempus iaculis. Sed pulvinar proin gravida hendrerit. Ut venenatis tellus in metus vulputate eu scelerisque felis imperdiet. Vitae semper quis lectus nulla at volutpat. Ut tortor pretium viverra suspendisse potenti nullam. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Varius quam quisque id diam vel quam elementum. Cursus mattis molestie a iaculis at erat pellentesque adipiscing.

-

-  Lectus mauris ultrices eros in cursus turpis massa. Id aliquet risus feugiat in ante metus dictum at. Parturient montes nascetur ridiculus mus. Blandit massa enim nec dui. Ornare arcu odio ut sem. Cursus in hac habitasse platea. Eu sem integer vitae justo eget magna fermentum iaculis eu. Pharetra magna ac placerat vestibulum. Aenean euismod elementum nisi quis eleifend quam adipiscing vitae proin. Mi bibendum neque egestas congue quisque egestas. Sapien faucibus et molestie ac feugiat sed lectus vestibulum. Urna id volutpat lacus laoreet non curabitur gravida arcu. Quis lectus nulla at volutpat diam ut.

-

-  Et netus et malesuada fames ac. At varius vel pharetra vel turpis. Nisi quis eleifend quam adipiscing vitae proin. Donec enim diam vulputate ut pharetra sit amet. Lectus arcu bibendum at varius vel pharetra vel turpis. Et molestie ac feugiat sed lectus. Cursus eget nunc scelerisque viverra mauris. Posuere lorem ipsum dolor sit amet consectetur adipiscing elit duis. Ultrices tincidunt arcu non sodales. Tempor orci dapibus ultrices in. Vehicula ipsum a arcu cursus vitae congue. Lectus vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt. Erat velit scelerisque in dictum non consectetur a erat nam. Risus quis varius quam quisque id. Lobortis elementum nibh tellus molestie. Pellentesque nec nam aliquam sem et tortor.

-

-  Nibh sed pulvinar proin gravida hendrerit lectus a. Consectetur a erat nam at lectus urna duis convallis. Consectetur a erat nam at lectus urna duis convallis convallis. Hac habitasse platea dictumst quisque sagittis purus sit amet. Sed odio morbi quis commodo. Cras fermentum odio eu feugiat pretium nibh ipsum consequat nisl. Consectetur libero id faucibus nisl tincidunt eget nullam. Convallis aenean et tortor at risus viverra adipiscing. At varius vel pharetra vel turpis nunc eget lorem. Tempus imperdiet nulla malesuada pellentesque elit eget gravida. Lobortis feugiat vivamus at augue eget arcu dictum varius. Bibendum ut tristique et egestas quis ipsum suspendisse ultrices. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus. Pretium nibh ipsum consequat nisl vel. Pretium aenean pharetra magna ac. Proin libero nunc consequat interdum varius sit amet. Aenean euismod elementum nisi quis eleifend quam adipiscing.

-

-  Turpis egestas maecenas pharetra convallis. Tellus in hac habitasse platea dictumst vestibulum. Est pellentesque elit ullamcorper dignissim. In pellentesque massa placerat duis ultricies lacus sed turpis tincidunt. Sed elementum tempus egestas sed sed risus pretium quam. Tellus mauris a diam maecenas. Aenean pharetra magna ac placerat vestibulum lectus mauris ultrices. Dictum at tempor commodo ullamcorper. Integer eget aliquet nibh praesent tristique magna sit amet. Venenatis tellus in metus vulputate eu scelerisque felis imperdiet proin. Risus nec feugiat in fermentum posuere urna nec tincidunt. Auctor elit sed vulputate mi sit amet mauris commodo quis. Sapien faucibus et molestie ac feugiat. Venenatis tellus in metus vulputate eu scelerisque felis. Congue mauris rhoncus aenean vel elit scelerisque mauris pellentesque. Potenti nullam ac tortor vitae purus. Ultrices gravida dictum fusce ut placerat. Ornare aenean euismod elementum nisi quis. Varius vel pharetra vel turpis. In pellentesque massa placerat duis.

-

-  Eget gravida cum sociis natoque penatibus et magnis. Diam maecenas ultricies mi eget mauris. Amet commodo nulla facilisi nullam vehicula ipsum a arcu cursus. Hendrerit gravida rutrum quisque non tellus orci ac auctor augue. Ac ut consequat semper viverra. Amet mauris commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Sagittis orci a scelerisque purus semper eget duis. Leo vel fringilla est ullamcorper eget nulla facilisi etiam dignissim. Viverra orci sagittis eu volutpat odio. Leo vel orci porta non pulvinar. Lacus luctus accumsan tortor posuere ac.

-

-  Faucibus scelerisque eleifend donec pretium vulputate sapien nec sagittis aliquam. Risus ultricies tristique nulla aliquet enim tortor at auctor urna. Odio morbi quis commodo odio aenean sed adipiscing. Lacus laoreet non curabitur gravida arcu. In aliquam sem fringilla ut. Egestas egestas fringilla phasellus faucibus scelerisque. Gravida in fermentum et sollicitudin ac orci phasellus. Enim sit amet venenatis urna cursus. Egestas erat imperdiet sed euismod nisi porta lorem mollis. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Id ornare arcu odio ut sem nulla pharetra diam sit.

-

-  Sed ullamcorper morbi tincidunt ornare massa eget egestas purus. Sagittis nisl rhoncus mattis rhoncus. Integer malesuada nunc vel risus commodo viverra maecenas. Enim nec dui nunc mattis enim. Enim eu turpis egestas pretium aenean pharetra magna ac placerat. Tortor dignissim convallis aenean et. Amet aliquam id diam maecenas ultricies mi eget. Amet mattis vulputate enim nulla aliquet porttitor lacus luctus. Vel quam elementum pulvinar etiam non quam. Tincidunt id aliquet risus feugiat in ante metus dictum. Eget sit amet tellus cras. Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus. Feugiat vivamus at augue eget arcu dictum varius duis at. Morbi blandit cursus risus at ultrices mi tempus. Lacus sed viverra tellus in hac habitasse platea dictumst. Eget nullam non nisi est sit amet facilisis magna. Augue ut lectus arcu bibendum at varius. Consectetur libero id faucibus nisl tincidunt eget nullam non nisi. Tincidunt dui ut ornare lectus sit amet est placerat in.

-

-  A erat nam at lectus urna duis convallis convallis tellus. Pretium viverra suspendisse potenti nullam ac tortor vitae purus faucibus. Sagittis id consectetur purus ut faucibus pulvinar. Praesent semper feugiat nibh sed pulvinar proin gravida. Mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare. Viverra nibh cras pulvinar mattis nunc sed. Et malesuada fames ac turpis egestas sed tempus urna. Penatibus et magnis dis parturient montes nascetur ridiculus mus mauris. Dapibus ultrices in iaculis nunc sed augue lacus. Ullamcorper sit amet risus nullam eget felis.

-

-  Faucibus et molestie ac feugiat sed lectus vestibulum mattis. Dui faucibus in ornare quam viverra orci. Vestibulum lorem sed risus ultricies tristique. Aliquet nibh praesent tristique magna sit amet purus. Interdum velit laoreet id donec ultrices tincidunt arcu. Tempor commodo ullamcorper a lacus vestibulum sed. Congue nisi vitae suscipit tellus. Sapien faucibus et molestie ac feugiat sed lectus. Nisi lacus sed viverra tellus. Nec ultrices dui sapien eget mi proin. A diam sollicitudin tempor id eu nisl nunc. Aenean sed adipiscing diam donec. Id porta nibh venenatis cras sed felis. Imperdiet massa tincidunt nunc pulvinar sapien et. Nisl pretium fusce id velit ut tortor pretium viverra. Magna eget est lorem ipsum dolor sit. Diam phasellus vestibulum lorem sed risus ultricies.

-

-  Aliquam eleifend mi in nulla posuere sollicitudin aliquam ultrices. Mauris nunc congue nisi vitae suscipit. Cras fermentum odio eu feugiat pretium nibh. Senectus et netus et malesuada. Quam nulla porttitor massa id neque aliquam vestibulum morbi blandit. Nam aliquam sem et tortor consequat. Arcu bibendum at varius vel pharetra. Faucibus purus in massa tempor nec feugiat nisl pretium fusce. Maecenas accumsan lacus vel facilisis volutpat est velit. Diam phasellus vestibulum lorem sed risus ultricies tristique. Et malesuada fames ac turpis egestas integer eget aliquet. Leo urna molestie at elementum eu facilisis. Molestie ac feugiat sed lectus vestibulum mattis ullamcorper velit. Sapien et ligula ullamcorper malesuada proin. Odio euismod lacinia at quis. Lacus viverra vitae congue eu consequat ac felis donec et. Bibendum neque egestas congue quisque egestas diam in arcu cursus. Aenean euismod elementum nisi quis. Egestas dui id ornare arcu odio ut.

-

-  Tortor pretium viverra suspendisse potenti nullam ac. Nec tincidunt praesent semper feugiat nibh sed. Nibh tortor id aliquet lectus proin nibh nisl. Gravida rutrum quisque non tellus orci ac auctor augue. Dui id ornare arcu odio. Turpis egestas sed tempus urna. Ut sem nulla pharetra diam sit amet. Cursus metus aliquam eleifend mi in nulla posuere sollicitudin aliquam. Mi sit amet mauris commodo quis. Quam id leo in vitae turpis massa sed elementum.

-

-  Quam adipiscing vitae proin sagittis. Sapien nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tellus molestie nunc non blandit massa enim nec dui. Volutpat odio facilisis mauris sit amet. Vestibulum sed arcu non odio euismod lacinia. Eget nunc scelerisque viverra mauris in aliquam sem. Aenean et tortor at risus viverra adipiscing at. Quis hendrerit dolor magna eget est lorem. Id porta nibh venenatis cras sed. Ut pharetra sit amet aliquam id diam maecenas ultricies mi.

-

-  Odio aenean sed adipiscing diam donec adipiscing tristique risus. Enim nunc faucibus a pellentesque sit amet porttitor. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Convallis convallis tellus id interdum velit laoreet. Iaculis eu non diam phasellus vestibulum lorem sed risus. Nunc vel risus commodo viverra. Malesuada nunc vel risus commodo viverra maecenas accumsan. Odio aenean sed adipiscing diam donec adipiscing tristique risus nec. Cursus mattis molestie a iaculis at. Arcu vitae elementum curabitur vitae nunc sed velit dignissim. Velit egestas dui id ornare arcu odio ut sem nulla.

-

-  Urna porttitor rhoncus dolor purus non enim praesent elementum facilisis. Tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada proin. Posuere morbi leo urna molestie at elementum. Cum sociis natoque penatibus et magnis dis parturient. Urna id volutpat lacus laoreet. Urna cursus eget nunc scelerisque viverra mauris in aliquam. Laoreet non curabitur gravida arcu ac tortor dignissim convallis aenean. Gravida arcu ac tortor dignissim convallis. Orci a scelerisque purus semper eget duis at. Tristique senectus et netus et malesuada fames ac turpis egestas. Ultricies lacus sed turpis tincidunt id aliquet risus feugiat in. Eu augue ut lectus arcu bibendum at varius. Vestibulum lectus mauris ultrices eros in.

-

-  Ut eu sem integer vitae justo eget magna. Non enim praesent elementum facilisis leo vel. Eget nulla facilisi etiam dignissim diam quis enim lobortis. Pellentesque pulvinar pellentesque habitant morbi. Aliquam id diam maecenas ultricies mi. Mattis molestie a iaculis at erat pellentesque adipiscing commodo elit. Justo nec ultrices dui sapien eget. Sit amet cursus sit amet. Sed risus ultricies tristique nulla aliquet enim tortor. Sit amet tellus cras adipiscing enim eu turpis. Scelerisque fermentum dui faucibus in ornare quam viverra orci. Ipsum dolor sit amet consectetur adipiscing elit ut aliquam purus. Non quam lacus suspendisse faucibus interdum. Elit pellentesque habitant morbi tristique senectus et netus et.

-

-  Vulputate odio ut enim blandit volutpat maecenas volutpat blandit. Ac orci phasellus egestas tellus rutrum tellus pellentesque eu tincidunt. Nunc congue nisi vitae suscipit tellus mauris a. Dictum non consectetur a erat. Aliquet eget sit amet tellus cras adipiscing enim. Gravida rutrum quisque non tellus orci ac auctor augue mauris. Consequat ac felis donec et. Sed vulputate odio ut enim blandit volutpat. Vulputate enim nulla aliquet porttitor lacus luctus accumsan tortor. Aenean sed adipiscing diam donec adipiscing. Nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit amet. Sed viverra ipsum nunc aliquet. Nunc aliquet bibendum enim facilisis gravida neque. Laoreet id donec ultrices tincidunt arcu. Cras fermentum odio eu feugiat pretium nibh. Egestas erat imperdiet sed euismod nisi. At tempor commodo ullamcorper a lacus vestibulum sed. Odio pellentesque diam volutpat commodo.

-

-  Suspendisse interdum consectetur libero id faucibus nisl tincidunt. Orci dapibus ultrices in iaculis nunc sed augue. In hac habitasse platea dictumst quisque sagittis purus. Elementum eu facilisis sed odio. Elementum nibh tellus molestie nunc. Vulputate ut pharetra sit amet aliquam id diam maecenas ultricies. Ut sem nulla pharetra diam sit amet nisl. Blandit massa enim nec dui nunc mattis enim ut. A scelerisque purus semper eget duis. Faucibus pulvinar elementum integer enim. Amet cursus sit amet dictum sit amet. Purus in massa tempor nec feugiat nisl pretium fusce. Sed tempus urna et pharetra pharetra. Amet risus nullam eget felis eget nunc.

-

-  Urna nunc id cursus metus aliquam eleifend. Nec feugiat nisl pretium fusce id velit ut tortor. Et malesuada fames ac turpis egestas integer eget. Aliquet sagittis id consectetur purus ut faucibus pulvinar. Tellus integer feugiat scelerisque varius morbi enim nunc. Suspendisse interdum consectetur libero id faucibus nisl tincidunt eget. At imperdiet dui accumsan sit amet. Vivamus at augue eget arcu dictum varius duis. Placerat orci nulla pellentesque dignissim enim sit amet venenatis urna. Risus ultricies tristique nulla aliquet enim. Suspendisse interdum consectetur libero id faucibus nisl tincidunt eget nullam. Ac placerat vestibulum lectus mauris ultrices.

-

-  Enim ut tellus elementum sagittis vitae et leo duis ut. Sit amet purus gravida quis blandit turpis cursus. Aliquam ut porttitor leo a diam sollicitudin tempor id eu. Auctor augue mauris augue neque gravida. Tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla. Adipiscing at in tellus integer feugiat scelerisque. Fermentum leo vel orci porta non pulvinar neque laoreet. At elementum eu facilisis sed odio morbi. Aliquam ultrices sagittis orci a scelerisque purus semper. Volutpat est velit egestas dui id. Euismod quis viverra nibh cras pulvinar mattis nunc sed blandit. Sed elementum tempus egestas sed sed.

-

-  Quisque sagittis purus sit amet volutpat consequat mauris nunc. Erat imperdiet sed euismod nisi porta lorem. Massa tempor nec feugiat nisl pretium. Erat nam at lectus urna. Fusce id velit ut tortor pretium viverra suspendisse. In vitae turpis massa sed elementum tempus egestas sed sed. Sem nulla pharetra diam sit amet nisl suscipit. In nisl nisi scelerisque eu ultrices vitae auctor. Non diam phasellus vestibulum lorem sed risus. Urna porttitor rhoncus dolor purus non enim.

-

-  Mi bibendum neque egestas congue. Ac tortor vitae purus faucibus ornare suspendisse sed nisi lacus. Quam viverra orci sagittis eu volutpat odio. Mi tempus imperdiet nulla malesuada pellentesque elit. Ultricies lacus sed turpis tincidunt. In ornare quam viverra orci sagittis eu volutpat odio facilisis. Ut eu sem integer vitae justo eget magna fermentum. Sed augue lacus viverra vitae. Quam nulla porttitor massa id neque. Ut aliquam purus sit amet luctus. Ullamcorper eget nulla facilisi etiam dignissim.

-

-  Sed faucibus turpis in eu. Massa sapien faucibus et molestie. Sed vulputate odio ut enim blandit volutpat maecenas volutpat. Quis vel eros donec ac odio tempor orci dapibus. Odio euismod lacinia at quis. Sit amet consectetur adipiscing elit duis tristique sollicitudin. Malesuada nunc vel risus commodo viverra maecenas accumsan lacus vel. Sed tempus urna et pharetra pharetra massa. Donec massa sapien faucibus et molestie ac feugiat. Convallis convallis tellus id interdum velit. Et odio pellentesque diam volutpat commodo. Aliquet lectus proin nibh nisl condimentum id venenatis. Sed nisi lacus sed viverra tellus in hac habitasse. At lectus urna duis convallis convallis tellus id interdum. Elit pellentesque habitant morbi tristique senectus et. Lorem ipsum dolor sit amet. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper. Ut pharetra sit amet aliquam id diam.

-

-  Euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis. Sit amet tellus cras adipiscing enim eu turpis egestas. Netus et malesuada fames ac turpis. Quis vel eros donec ac. Et malesuada fames ac turpis egestas integer eget. Amet est placerat in egestas erat imperdiet. Nec nam aliquam sem et tortor. Ac turpis egestas sed tempus urna et. Massa eget egestas purus viverra accumsan. Condimentum id venenatis a condimentum vitae sapien. Sagittis orci a scelerisque purus semper eget. Aliquet sagittis id consectetur purus ut faucibus pulvinar. Tempor id eu nisl nunc mi ipsum faucibus. Sed faucibus turpis in eu mi bibendum neque egestas congue. Morbi tincidunt augue interdum velit euismod in pellentesque. Amet nisl suscipit adipiscing bibendum est ultricies integer. Ut eu sem integer vitae justo eget magna fermentum. Nisi lacus sed viverra tellus. Scelerisque varius morbi enim nunc faucibus a pellentesque. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra.

-

-  Ut placerat orci nulla pellentesque dignissim enim. Tristique senectus et netus et malesuada. Diam in arcu cursus euismod quis viverra nibh cras pulvinar. Lobortis mattis aliquam faucibus purus in massa tempor. Libero id faucibus nisl tincidunt eget nullam non nisi est. Mauris pellentesque pulvinar pellentesque habitant. Est pellentesque elit ullamcorper dignissim cras tincidunt. Egestas sed sed risus pretium quam vulputate. Bibendum at varius vel pharetra. Libero nunc consequat interdum varius. Tincidunt vitae semper quis lectus nulla at volutpat diam. Augue eget arcu dictum varius duis. Varius vel pharetra vel turpis. Quam lacus suspendisse faucibus interdum posuere. Pulvinar neque laoreet suspendisse interdum consectetur libero id. Gravida arcu ac tortor dignissim convallis aenean et. Sit amet porttitor eget dolor morbi non arcu risus.

-

-  Imperdiet sed euismod nisi porta lorem mollis aliquam ut. Sit amet nulla facilisi morbi tempus iaculis. Eleifend mi in nulla posuere sollicitudin aliquam. Sed vulputate odio ut enim. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et. Lectus arcu bibendum at varius vel pharetra vel. Est ultricies integer quis auctor elit sed. Nulla facilisi cras fermentum odio eu feugiat pretium nibh. Nascetur ridiculus mus mauris vitae ultricies leo integer. Faucibus ornare suspendisse sed nisi. Netus et malesuada fames ac turpis. Scelerisque purus semper eget duis at tellus at urna condimentum. Mauris a diam maecenas sed.

-

-  Tortor id aliquet lectus proin nibh nisl condimentum. Urna nunc id cursus metus aliquam eleifend mi in. Risus commodo viverra maecenas accumsan lacus vel facilisis volutpat est. Vitae tempus quam pellentesque nec nam aliquam. Amet aliquam id diam maecenas ultricies mi. Morbi non arcu risus quis. Pharetra vel turpis nunc eget lorem. Tincidunt vitae semper quis lectus nulla at volutpat. Massa placerat duis ultricies lacus. Augue mauris augue neque gravida in fermentum. Viverra justo nec ultrices dui sapien. Semper auctor neque vitae tempus quam pellentesque. Ipsum consequat nisl vel pretium lectus quam id leo in. Dignissim cras tincidunt lobortis feugiat vivamus at augue eget arcu. Platea dictumst vestibulum rhoncus est pellentesque. Ipsum suspendisse ultrices gravida dictum fusce ut.

-

-  Euismod nisi porta lorem mollis aliquam ut porttitor leo. Ac turpis egestas integer eget aliquet nibh praesent tristique. Aliquet nec ullamcorper sit amet risus nullam eget. Id venenatis a condimentum vitae sapien pellentesque habitant morbi tristique. Placerat duis ultricies lacus sed turpis tincidunt id. Laoreet suspendisse interdum consectetur libero id faucibus nisl tincidunt eget. Convallis a cras semper auctor. Ornare aenean euismod elementum nisi quis eleifend quam adipiscing vitae. Arcu cursus vitae congue mauris rhoncus aenean vel elit scelerisque. Nec nam aliquam sem et tortor consequat id.

-

-  Risus viverra adipiscing at in tellus integer feugiat scelerisque varius. Aliquam sem et tortor consequat id. Nisi scelerisque eu ultrices vitae auctor eu augue ut. Ut morbi tincidunt augue interdum velit euismod. A scelerisque purus semper eget. Felis eget velit aliquet sagittis id consectetur purus. Blandit turpis cursus in hac habitasse platea dictumst quisque sagittis. Senectus et netus et malesuada fames ac turpis egestas integer. Urna nec tincidunt praesent semper. Quis viverra nibh cras pulvinar. Purus semper eget duis at tellus. Ante metus dictum at tempor. Eleifend mi in nulla posuere sollicitudin aliquam ultrices sagittis orci. Tincidunt eget nullam non nisi est. Dignissim sodales ut eu sem integer.

-

-  Euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis. Sit amet tellus cras adipiscing enim eu turpis egestas. Netus et malesuada fames ac turpis. Quis vel eros donec ac. Et malesuada fames ac turpis egestas integer eget. Amet est placerat in egestas erat imperdiet. Nec nam aliquam sem et tortor. Ac turpis egestas sed tempus urna et. Massa eget egestas purus viverra accumsan. Condimentum id venenatis a condimentum vitae sapien. Sagittis orci a scelerisque purus semper eget. Aliquet sagittis id consectetur purus ut faucibus pulvinar. Tempor id eu nisl nunc mi ipsum faucibus. Sed faucibus turpis in eu mi bibendum neque egestas congue. Morbi tincidunt augue interdum velit euismod in pellentesque. Amet nisl suscipit adipiscing bibendum est ultricies integer. Ut eu sem integer vitae justo eget magna fermentum. Nisi lacus sed viverra tellus. Scelerisque varius morbi enim nunc faucibus a pellentesque. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra.

-

-  Ut placerat orci nulla pellentesque dignissim enim. Tristique senectus et netus et malesuada. Diam in arcu cursus euismod quis viverra nibh cras pulvinar. Lobortis mattis aliquam faucibus purus in massa tempor. Libero id faucibus nisl tincidunt eget nullam non nisi est. Mauris pellentesque pulvinar pellentesque habitant. Est pellentesque elit ullamcorper dignissim cras tincidunt. Egestas sed sed risus pretium quam vulputate. Bibendum at varius vel pharetra. Libero nunc consequat interdum varius. Tincidunt vitae semper quis lectus nulla at volutpat diam. Augue eget arcu dictum varius duis. Varius vel pharetra vel turpis. Quam lacus suspendisse faucibus interdum posuere. Pulvinar neque laoreet suspendisse interdum consectetur libero id. Gravida arcu ac tortor dignissim convallis aenean et. Sit amet porttitor eget dolor morbi non arcu risus.

-

-  Imperdiet sed euismod nisi porta lorem mollis aliquam ut. Sit amet nulla facilisi morbi tempus iaculis. Eleifend mi in nulla posuere sollicitudin aliquam. Sed vulputate odio ut enim. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et. Lectus arcu bibendum at varius vel pharetra vel. Est ultricies integer quis auctor elit sed. Nulla facilisi cras fermentum odio eu feugiat pretium nibh. Nascetur ridiculus mus mauris vitae ultricies leo integer. Faucibus ornare suspendisse sed nisi. Netus et malesuada fames ac turpis. Scelerisque purus semper eget duis at tellus at urna condimentum. Mauris a diam maecenas sed.

-

-</home>

+<?xml version="1.0" encoding="windows-1251"?>
+<?xml-stylesheet type="text/xsl" href="resources/long-multi-byte-char.xslt"?>
+<home>
+  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vulputate odio ut enim blandit volutpat maecenas volutpat blandit aliquam. Ornare aenean euismod elementum nisi quis eleifend quam. Urna et pharetra pharetra massa massa ultricies mi quis. Id nibh tortor id aliquet lectus proin nibh nisl. Elementum eu facilisis sed odio morbi. Nibh nisl condimentum id venenatis a condimentum vitae sapien. Aliquam vestibulum morbi blandit cursus risus at ultrices. At tellus at urna condimentum mattis pellentesque id nibh tortor. Tortor id aliquet lectus proin nibh nisl condimentum id. Nulla malesuada pellentesque elit eget. Porta nibh venenatis cras sed felis eget. Volutpat est velit egestas dui id ornare. Donec ac odio tempor orci. Lectus mauris ultrices eros in. Amet dictum sit amet justo. Facilisis magna etiam tempor orci eu lobortis elementum. Pellentesque dignissim enim sit amet venenatis urna cursus eget. Sit amet facilisis magna etiam tempor. Ornare arcu odio ut sem nulla pharetra.
+
+  Porttitor massa id neque aliquam vestibulum morbi. Euismod lacinia at quis risus sed vulputate odio ut. Massa id neque aliquam vestibulum morbi blandit cursus. Tristique magna sit amet purus gravida. Felis eget nunc lobortis mattis. Placerat orci nulla pellentesque dignissim. Malesuada bibendum arcu vitae elementum curabitur vitae nunc. Fames ac turpis egestas sed. Felis eget nunc lobortis mattis aliquam. Ut faucibus pulvinar elementum integer enim neque volutpat ac. Sollicitudin tempor id eu nisl nunc mi ipsum. Platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras. Maecenas volutpat blandit aliquam etiam erat velit. Donec massa sapien faucibus et.
+
+  Duis ultricies lacus sed turpis tincidunt id aliquet risus. In tellus integer feugiat scelerisque varius morbi. Sit amet tellus cras adipiscing enim eu. Mi eget mauris pharetra et ultrices. Volutpat lacus laoreet non curabitur gravida arcu ac. Euismod quis viverra nibh cras pulvinar mattis nunc sed. In eu mi bibendum neque egestas. Fames ac turpis egestas maecenas pharetra convallis. Iaculis at erat pellentesque adipiscing commodo elit at imperdiet dui. Dui ut ornare lectus sit amet. Venenatis urna cursus eget nunc scelerisque viverra mauris in aliquam. Fermentum posuere urna nec tincidunt praesent semper feugiat nibh. Nec feugiat nisl pretium fusce id velit ut tortor pretium. Rhoncus mattis rhoncus urna neque viverra justo nec ultrices dui. Aenean pharetra magna ac placerat vestibulum lectus mauris ultrices eros. Erat nam at lectus urna duis convallis convallis. Tristique senectus et netus et malesuada fames ac. Purus in massa tempor nec feugiat nisl pretium fusce id. Et magnis dis parturient montes nascetur ridiculus.
+
+  At elementum eu facilisis sed odio morbi. Interdum velit laoreet id donec ultrices tincidunt arcu non sodales. Sapien nec sagittis aliquam malesuada bibendum. Viverra mauris in aliquam sem fringilla ut. Amet nulla facilisi morbi tempus iaculis urna id volutpat lacus. Mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus. Bibendum at varius vel pharetra vel turpis nunc eget. Arcu non odio euismod lacinia at quis risus. In massa tempor nec feugiat nisl pretium fusce id velit. Sem et tortor consequat id porta nibh venenatis cras sed. Amet risus nullam eget felis eget nunc. Imperdiet proin fermentum leo vel orci porta non pulvinar. Ac auctor augue mauris augue neque. Tellus at urna condimentum mattis. Amet luctus venenatis lectus magna fringilla urna porttitor. Tincidunt praesent semper feugiat nibh sed pulvinar.
+
+  Faucibus scelerisque eleifend donec pretium vulputate sapien nec sagittis. Elit at imperdiet dui accumsan sit amet nulla. Ut consequat semper viverra nam libero justo laoreet sit. Morbi tincidunt augue interdum velit euismod in. Platea dictumst vestibulum rhoncus est. Sem et tortor consequat id porta nibh. Tristique risus nec feugiat in fermentum posuere. Nibh cras pulvinar mattis nunc sed blandit libero volutpat sed. Velit egestas dui id ornare arcu. Amet commodo nulla facilisi nullam vehicula ipsum a arcu. Venenatis tellus in metus vulputate eu. Sollicitudin ac orci phasellus egestas tellus rutrum tellus. Faucibus nisl tincidunt eget nullam. Et netus et malesuada fames ac turpis egestas maecenas. Diam quam nulla porttitor massa id neque aliquam vestibulum.
+
+  Ac turpis egestas integer eget aliquet nibh praesent tristique magna. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras. Risus pretium quam vulputate dignissim suspendisse in. Nunc sed id semper risus in hendrerit gravida rutrum. Interdum velit euismod in pellentesque massa placerat duis. Amet mauris commodo quis imperdiet massa tincidunt. Urna duis convallis convallis tellus id. Aliquam vestibulum morbi blandit cursus. Magna ac placerat vestibulum lectus mauris ultrices eros in cursus. Vitae et leo duis ut diam. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Faucibus nisl tincidunt eget nullam non nisi est sit amet.
+
+  Vel risus commodo viverra maecenas accumsan lacus. Magna sit amet purus gravida quis blandit. Purus non enim praesent elementum facilisis leo. Purus sit amet luctus venenatis lectus magna fringilla urna porttitor. Cursus sit amet dictum sit. Tellus cras adipiscing enim eu turpis egestas pretium. Tempus imperdiet nulla malesuada pellentesque elit. Etiam non quam lacus suspendisse faucibus interdum posuere. Tempus quam pellentesque nec nam aliquam sem et. Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Maecenas sed enim ut sem. Amet venenatis urna cursus eget nunc scelerisque. Curabitur vitae nunc sed velit. Risus feugiat in ante metus dictum. Auctor elit sed vulputate mi sit amet mauris commodo. Quam adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus urna. Nibh sed pulvinar proin gravida hendrerit. Suscipit adipiscing bibendum est ultricies integer quis auctor. Odio facilisis mauris sit amet.
+
+  Turpis egestas integer eget aliquet nibh. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Adipiscing elit duis tristique sollicitudin nibh sit amet. Nec feugiat nisl pretium fusce id. Fames ac turpis egestas integer. In dictum non consectetur a erat nam at lectus. Interdum velit euismod in pellentesque massa placerat duis ultricies. Enim facilisis gravida neque convallis a cras semper auctor neque. Condimentum lacinia quis vel eros donec ac odio tempor orci. Quam id leo in vitae turpis massa sed elementum. Mauris pharetra et ultrices neque ornare aenean.
+
+  Pulvinar sapien et ligula ullamcorper malesuada proin libero nunc consequat. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Placerat orci nulla pellentesque dignissim enim sit amet venenatis. Dignissim sodales ut eu sem integer. Amet consectetur adipiscing elit pellentesque habitant morbi tristique senectus. Dignissim enim sit amet venenatis urna cursus. Nisl vel pretium lectus quam. Quis risus sed vulputate odio ut. Quam elementum pulvinar etiam non quam lacus suspendisse faucibus interdum. Faucibus et molestie ac feugiat sed. Mauris cursus mattis molestie a iaculis at erat pellentesque. Odio aenean sed adipiscing diam donec adipiscing tristique risus. Metus aliquam eleifend mi in nulla posuere sollicitudin aliquam. Pulvinar mattis nunc sed blandit libero volutpat sed cras. Massa placerat duis ultricies lacus.
+
+  Tellus id interdum velit laoreet. Sed faucibus turpis in eu mi bibendum neque egestas. Proin sagittis nisl rhoncus mattis. Arcu vitae elementum curabitur vitae nunc sed. Amet risus nullam eget felis eget nunc. Lacinia quis vel eros donec ac odio tempor. Enim eu turpis egestas pretium aenean pharetra magna ac. Suspendisse sed nisi lacus sed viverra tellus in hac. At volutpat diam ut venenatis tellus in metus vulputate. Ornare arcu odio ut sem nulla pharetra diam sit amet. Quis hendrerit dolor magna eget est. Pellentesque massa placerat duis ultricies lacus sed turpis.
+
+  Magna eget est lorem ipsum dolor sit amet consectetur adipiscing. At varius vel pharetra vel turpis nunc. Dis parturient montes nascetur ridiculus mus mauris vitae. Quam vulputate dignissim suspendisse in est ante. Neque convallis a cras semper auctor neque. Donec ultrices tincidunt arcu non sodales neque sodales ut etiam. Urna nunc id cursus metus aliquam eleifend mi in nulla. Nunc sed velit dignissim sodales ut eu sem integer vitae. Auctor eu augue ut lectus arcu. Nunc sed velit dignissim sodales ut. Cum sociis natoque penatibus et magnis dis parturient montes.
+
+  Neque aliquam vestibulum morbi blandit. Urna condimentum mattis pellentesque id. Dapibus ultrices in iaculis nunc sed augue lacus viverra. Dictum sit amet justo donec enim diam. Sit amet nulla facilisi morbi tempus. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Lacus sed turpis tincidunt id aliquet risus feugiat in ante. Sed viverra ipsum nunc aliquet bibendum enim facilisis. Consequat interdum varius sit amet mattis vulputate enim. Cum sociis natoque penatibus et magnis dis. Cursus mattis molestie a iaculis at erat. Sed sed risus pretium quam. Scelerisque fermentum dui faucibus in. Feugiat nisl pretium fusce id velit. Orci a scelerisque purus semper eget duis. Adipiscing at in tellus integer feugiat.
+
+  Dui faucibus in ornare quam viverra orci. Aliquam eleifend mi in nulla posuere. Eleifend quam adipiscing vitae proin sagittis. Amet commodo nulla facilisi nullam vehicula. Interdum consectetur libero id faucibus nisl tincidunt eget nullam. Leo vel orci porta non pulvinar neque laoreet suspendisse interdum. Posuere sollicitudin aliquam ultrices sagittis orci a. Nec ultrices dui sapien eget mi proin. Sodales neque sodales ut etiam sit amet. Ac placerat vestibulum lectus mauris ultrices eros in cursus. Amet facilisis magna etiam tempor orci.
+
+  Auctor eu augue ut lectus arcu bibendum at varius vel. Aliquam ultrices sagittis orci a scelerisque purus semper eget duis. Volutpat ac tincidunt vitae semper. Ornare lectus sit amet est placerat in egestas. Ac orci phasellus egestas tellus rutrum tellus pellentesque. Ullamcorper malesuada proin libero nunc consequat. Eget est lorem ipsum dolor sit amet. Et netus et malesuada fames ac turpis egestas. Donec massa sapien faucibus et molestie ac. Laoreet sit amet cursus sit amet dictum. Eget nullam non nisi est sit amet facilisis magna etiam. At tempor commodo ullamcorper a lacus vestibulum sed arcu non. Eget nulla facilisi etiam dignissim diam quis enim.
+
+  Ante metus dictum at tempor commodo ullamcorper. Ultricies mi quis hendrerit dolor magna eget est lorem ipsum. Nunc sed blandit libero volutpat. Tristique senectus et netus et. Nisi lacus sed viverra tellus in hac habitasse platea dictumst. Elementum facilisis leo vel fringilla. Lacus viverra vitae congue eu. Nisl condimentum id venenatis a condimentum vitae. Ipsum a arcu cursus vitae congue mauris rhoncus aenean vel. Felis imperdiet proin fermentum leo vel orci porta. Malesuada fames ac turpis egestas sed tempus. Aenean et tortor at risus viverra adipiscing at. Ultrices sagittis orci a scelerisque purus semper.
+
+  Orci eu lobortis elementum nibh tellus molestie nunc non blandit. Vel pharetra vel turpis nunc eget lorem. Diam maecenas ultricies mi eget. Consectetur libero id faucibus nisl tincidunt eget nullam non. Sit amet purus gravida quis blandit turpis cursus. Eget est lorem ipsum dolor sit amet consectetur. Pellentesque habitant morbi tristique senectus et netus. Nunc mattis enim ut tellus elementum sagittis vitae et leo. Laoreet id donec ultrices tincidunt arcu. Tellus id interdum velit laoreet id donec ultrices. Et netus et malesuada fames ac turpis egestas sed tempus. Viverra ipsum nunc aliquet bibendum enim. Mauris commodo quis imperdiet massa tincidunt nunc pulvinar sapien et. Diam vulputate ut pharetra sit amet aliquam. Eu tincidunt tortor aliquam nulla facilisi cras fermentum.
+
+  Massa sapien faucibus et molestie ac feugiat. Eget egestas purus viverra accumsan in nisl. Metus dictum at tempor commodo ullamcorper a lacus. Tempus imperdiet nulla malesuada pellentesque elit. At erat pellentesque adipiscing commodo elit at imperdiet. Lectus quam id leo in vitae turpis. Donec ultrices tincidunt arcu non sodales neque sodales. Semper eget duis at tellus at urna. Elementum sagittis vitae et leo duis ut. Imperdiet sed euismod nisi porta. Odio eu feugiat pretium nibh ipsum consequat nisl. Sit amet nulla facilisi morbi tempus iaculis. Sed pulvinar proin gravida hendrerit. Ut venenatis tellus in metus vulputate eu scelerisque felis imperdiet. Vitae semper quis lectus nulla at volutpat. Ut tortor pretium viverra suspendisse potenti nullam. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Varius quam quisque id diam vel quam elementum. Cursus mattis molestie a iaculis at erat pellentesque adipiscing.
+
+  Lectus mauris ultrices eros in cursus turpis massa. Id aliquet risus feugiat in ante metus dictum at. Parturient montes nascetur ridiculus mus. Blandit massa enim nec dui. Ornare arcu odio ut sem. Cursus in hac habitasse platea. Eu sem integer vitae justo eget magna fermentum iaculis eu. Pharetra magna ac placerat vestibulum. Aenean euismod elementum nisi quis eleifend quam adipiscing vitae proin. Mi bibendum neque egestas congue quisque egestas. Sapien faucibus et molestie ac feugiat sed lectus vestibulum. Urna id volutpat lacus laoreet non curabitur gravida arcu. Quis lectus nulla at volutpat diam ut.
+
+  Et netus et malesuada fames ac. At varius vel pharetra vel turpis. Nisi quis eleifend quam adipiscing vitae proin. Donec enim diam vulputate ut pharetra sit amet. Lectus arcu bibendum at varius vel pharetra vel turpis. Et molestie ac feugiat sed lectus. Cursus eget nunc scelerisque viverra mauris. Posuere lorem ipsum dolor sit amet consectetur adipiscing elit duis. Ultrices tincidunt arcu non sodales. Tempor orci dapibus ultrices in. Vehicula ipsum a arcu cursus vitae congue. Lectus vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt. Erat velit scelerisque in dictum non consectetur a erat nam. Risus quis varius quam quisque id. Lobortis elementum nibh tellus molestie. Pellentesque nec nam aliquam sem et tortor.
+
+  Nibh sed pulvinar proin gravida hendrerit lectus a. Consectetur a erat nam at lectus urna duis convallis. Consectetur a erat nam at lectus urna duis convallis convallis. Hac habitasse platea dictumst quisque sagittis purus sit amet. Sed odio morbi quis commodo. Cras fermentum odio eu feugiat pretium nibh ipsum consequat nisl. Consectetur libero id faucibus nisl tincidunt eget nullam. Convallis aenean et tortor at risus viverra adipiscing. At varius vel pharetra vel turpis nunc eget lorem. Tempus imperdiet nulla malesuada pellentesque elit eget gravida. Lobortis feugiat vivamus at augue eget arcu dictum varius. Bibendum ut tristique et egestas quis ipsum suspendisse ultrices. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus. Pretium nibh ipsum consequat nisl vel. Pretium aenean pharetra magna ac. Proin libero nunc consequat interdum varius sit amet. Aenean euismod elementum nisi quis eleifend quam adipiscing.
+
+  Turpis egestas maecenas pharetra convallis. Tellus in hac habitasse platea dictumst vestibulum. Est pellentesque elit ullamcorper dignissim. In pellentesque massa placerat duis ultricies lacus sed turpis tincidunt. Sed elementum tempus egestas sed sed risus pretium quam. Tellus mauris a diam maecenas. Aenean pharetra magna ac placerat vestibulum lectus mauris ultrices. Dictum at tempor commodo ullamcorper. Integer eget aliquet nibh praesent tristique magna sit amet. Venenatis tellus in metus vulputate eu scelerisque felis imperdiet proin. Risus nec feugiat in fermentum posuere urna nec tincidunt. Auctor elit sed vulputate mi sit amet mauris commodo quis. Sapien faucibus et molestie ac feugiat. Venenatis tellus in metus vulputate eu scelerisque felis. Congue mauris rhoncus aenean vel elit scelerisque mauris pellentesque. Potenti nullam ac tortor vitae purus. Ultrices gravida dictum fusce ut placerat. Ornare aenean euismod elementum nisi quis. Varius vel pharetra vel turpis. In pellentesque massa placerat duis.
+
+  Eget gravida cum sociis natoque penatibus et magnis. Diam maecenas ultricies mi eget mauris. Amet commodo nulla facilisi nullam vehicula ipsum a arcu cursus. Hendrerit gravida rutrum quisque non tellus orci ac auctor augue. Ac ut consequat semper viverra. Amet mauris commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Sagittis orci a scelerisque purus semper eget duis. Leo vel fringilla est ullamcorper eget nulla facilisi etiam dignissim. Viverra orci sagittis eu volutpat odio. Leo vel orci porta non pulvinar. Lacus luctus accumsan tortor posuere ac.
+
+  Faucibus scelerisque eleifend donec pretium vulputate sapien nec sagittis aliquam. Risus ultricies tristique nulla aliquet enim tortor at auctor urna. Odio morbi quis commodo odio aenean sed adipiscing. Lacus laoreet non curabitur gravida arcu. In aliquam sem fringilla ut. Egestas egestas fringilla phasellus faucibus scelerisque. Gravida in fermentum et sollicitudin ac orci phasellus. Enim sit amet venenatis urna cursus. Egestas erat imperdiet sed euismod nisi porta lorem mollis. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Id ornare arcu odio ut sem nulla pharetra diam sit.
+
+  Sed ullamcorper morbi tincidunt ornare massa eget egestas purus. Sagittis nisl rhoncus mattis rhoncus. Integer malesuada nunc vel risus commodo viverra maecenas. Enim nec dui nunc mattis enim. Enim eu turpis egestas pretium aenean pharetra magna ac placerat. Tortor dignissim convallis aenean et. Amet aliquam id diam maecenas ultricies mi eget. Amet mattis vulputate enim nulla aliquet porttitor lacus luctus. Vel quam elementum pulvinar etiam non quam. Tincidunt id aliquet risus feugiat in ante metus dictum. Eget sit amet tellus cras. Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus. Feugiat vivamus at augue eget arcu dictum varius duis at. Morbi blandit cursus risus at ultrices mi tempus. Lacus sed viverra tellus in hac habitasse platea dictumst. Eget nullam non nisi est sit amet facilisis magna. Augue ut lectus arcu bibendum at varius. Consectetur libero id faucibus nisl tincidunt eget nullam non nisi. Tincidunt dui ut ornare lectus sit amet est placerat in.
+
+  A erat nam at lectus urna duis convallis convallis tellus. Pretium viverra suspendisse potenti nullam ac tortor vitae purus faucibus. Sagittis id consectetur purus ut faucibus pulvinar. Praesent semper feugiat nibh sed pulvinar proin gravida. Mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare. Viverra nibh cras pulvinar mattis nunc sed. Et malesuada fames ac turpis egestas sed tempus urna. Penatibus et magnis dis parturient montes nascetur ridiculus mus mauris. Dapibus ultrices in iaculis nunc sed augue lacus. Ullamcorper sit amet risus nullam eget felis.
+
+  Faucibus et molestie ac feugiat sed lectus vestibulum mattis. Dui faucibus in ornare quam viverra orci. Vestibulum lorem sed risus ultricies tristique. Aliquet nibh praesent tristique magna sit amet purus. Interdum velit laoreet id donec ultrices tincidunt arcu. Tempor commodo ullamcorper a lacus vestibulum sed. Congue nisi vitae suscipit tellus. Sapien faucibus et molestie ac feugiat sed lectus. Nisi lacus sed viverra tellus. Nec ultrices dui sapien eget mi proin. A diam sollicitudin tempor id eu nisl nunc. Aenean sed adipiscing diam donec. Id porta nibh venenatis cras sed felis. Imperdiet massa tincidunt nunc pulvinar sapien et. Nisl pretium fusce id velit ut tortor pretium viverra. Magna eget est lorem ipsum dolor sit. Diam phasellus vestibulum lorem sed risus ultricies.
+
+  Aliquam eleifend mi in nulla posuere sollicitudin aliquam ultrices. Mauris nunc congue nisi vitae suscipit. Cras fermentum odio eu feugiat pretium nibh. Senectus et netus et malesuada. Quam nulla porttitor massa id neque aliquam vestibulum morbi blandit. Nam aliquam sem et tortor consequat. Arcu bibendum at varius vel pharetra. Faucibus purus in massa tempor nec feugiat nisl pretium fusce. Maecenas accumsan lacus vel facilisis volutpat est velit. Diam phasellus vestibulum lorem sed risus ultricies tristique. Et malesuada fames ac turpis egestas integer eget aliquet. Leo urna molestie at elementum eu facilisis. Molestie ac feugiat sed lectus vestibulum mattis ullamcorper velit. Sapien et ligula ullamcorper malesuada proin. Odio euismod lacinia at quis. Lacus viverra vitae congue eu consequat ac felis donec et. Bibendum neque egestas congue quisque egestas diam in arcu cursus. Aenean euismod elementum nisi quis. Egestas dui id ornare arcu odio ut.
+
+  Tortor pretium viverra suspendisse potenti nullam ac. Nec tincidunt praesent semper feugiat nibh sed. Nibh tortor id aliquet lectus proin nibh nisl. Gravida rutrum quisque non tellus orci ac auctor augue. Dui id ornare arcu odio. Turpis egestas sed tempus urna. Ut sem nulla pharetra diam sit amet. Cursus metus aliquam eleifend mi in nulla posuere sollicitudin aliquam. Mi sit amet mauris commodo quis. Quam id leo in vitae turpis massa sed elementum.
+
+  Quam adipiscing vitae proin sagittis. Sapien nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tellus molestie nunc non blandit massa enim nec dui. Volutpat odio facilisis mauris sit amet. Vestibulum sed arcu non odio euismod lacinia. Eget nunc scelerisque viverra mauris in aliquam sem. Aenean et tortor at risus viverra adipiscing at. Quis hendrerit dolor magna eget est lorem. Id porta nibh venenatis cras sed. Ut pharetra sit amet aliquam id diam maecenas ultricies mi.
+
+  Odio aenean sed adipiscing diam donec adipiscing tristique risus. Enim nunc faucibus a pellentesque sit amet porttitor. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Convallis convallis tellus id interdum velit laoreet. Iaculis eu non diam phasellus vestibulum lorem sed risus. Nunc vel risus commodo viverra. Malesuada nunc vel risus commodo viverra maecenas accumsan. Odio aenean sed adipiscing diam donec adipiscing tristique risus nec. Cursus mattis molestie a iaculis at. Arcu vitae elementum curabitur vitae nunc sed velit dignissim. Velit egestas dui id ornare arcu odio ut sem nulla.
+
+  Urna porttitor rhoncus dolor purus non enim praesent elementum facilisis. Tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada proin. Posuere morbi leo urna molestie at elementum. Cum sociis natoque penatibus et magnis dis parturient. Urna id volutpat lacus laoreet. Urna cursus eget nunc scelerisque viverra mauris in aliquam. Laoreet non curabitur gravida arcu ac tortor dignissim convallis aenean. Gravida arcu ac tortor dignissim convallis. Orci a scelerisque purus semper eget duis at. Tristique senectus et netus et malesuada fames ac turpis egestas. Ultricies lacus sed turpis tincidunt id aliquet risus feugiat in. Eu augue ut lectus arcu bibendum at varius. Vestibulum lectus mauris ultrices eros in.
+
+  Ut eu sem integer vitae justo eget magna. Non enim praesent elementum facilisis leo vel. Eget nulla facilisi etiam dignissim diam quis enim lobortis. Pellentesque pulvinar pellentesque habitant morbi. Aliquam id diam maecenas ultricies mi. Mattis molestie a iaculis at erat pellentesque adipiscing commodo elit. Justo nec ultrices dui sapien eget. Sit amet cursus sit amet. Sed risus ultricies tristique nulla aliquet enim tortor. Sit amet tellus cras adipiscing enim eu turpis. Scelerisque fermentum dui faucibus in ornare quam viverra orci. Ipsum dolor sit amet consectetur adipiscing elit ut aliquam purus. Non quam lacus suspendisse faucibus interdum. Elit pellentesque habitant morbi tristique senectus et netus et.
+
+  Vulputate odio ut enim blandit volutpat maecenas volutpat blandit. Ac orci phasellus egestas tellus rutrum tellus pellentesque eu tincidunt. Nunc congue nisi vitae suscipit tellus mauris a. Dictum non consectetur a erat. Aliquet eget sit amet tellus cras adipiscing enim. Gravida rutrum quisque non tellus orci ac auctor augue mauris. Consequat ac felis donec et. Sed vulputate odio ut enim blandit volutpat. Vulputate enim nulla aliquet porttitor lacus luctus accumsan tortor. Aenean sed adipiscing diam donec adipiscing. Nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit amet. Sed viverra ipsum nunc aliquet. Nunc aliquet bibendum enim facilisis gravida neque. Laoreet id donec ultrices tincidunt arcu. Cras fermentum odio eu feugiat pretium nibh. Egestas erat imperdiet sed euismod nisi. At tempor commodo ullamcorper a lacus vestibulum sed. Odio pellentesque diam volutpat commodo.
+
+  Suspendisse interdum consectetur libero id faucibus nisl tincidunt. Orci dapibus ultrices in iaculis nunc sed augue. In hac habitasse platea dictumst quisque sagittis purus. Elementum eu facilisis sed odio. Elementum nibh tellus molestie nunc. Vulputate ut pharetra sit amet aliquam id diam maecenas ultricies. Ut sem nulla pharetra diam sit amet nisl. Blandit massa enim nec dui nunc mattis enim ut. A scelerisque purus semper eget duis. Faucibus pulvinar elementum integer enim. Amet cursus sit amet dictum sit amet. Purus in massa tempor nec feugiat nisl pretium fusce. Sed tempus urna et pharetra pharetra. Amet risus nullam eget felis eget nunc.
+
+  Urna nunc id cursus metus aliquam eleifend. Nec feugiat nisl pretium fusce id velit ut tortor. Et malesuada fames ac turpis egestas integer eget. Aliquet sagittis id consectetur purus ut faucibus pulvinar. Tellus integer feugiat scelerisque varius morbi enim nunc. Suspendisse interdum consectetur libero id faucibus nisl tincidunt eget. At imperdiet dui accumsan sit amet. Vivamus at augue eget arcu dictum varius duis. Placerat orci nulla pellentesque dignissim enim sit amet venenatis urna. Risus ultricies tristique nulla aliquet enim. Suspendisse interdum consectetur libero id faucibus nisl tincidunt eget nullam. Ac placerat vestibulum lectus mauris ultrices.
+
+  Enim ut tellus elementum sagittis vitae et leo duis ut. Sit amet purus gravida quis blandit turpis cursus. Aliquam ut porttitor leo a diam sollicitudin tempor id eu. Auctor augue mauris augue neque gravida. Tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla. Adipiscing at in tellus integer feugiat scelerisque. Fermentum leo vel orci porta non pulvinar neque laoreet. At elementum eu facilisis sed odio morbi. Aliquam ultrices sagittis orci a scelerisque purus semper. Volutpat est velit egestas dui id. Euismod quis viverra nibh cras pulvinar mattis nunc sed blandit. Sed elementum tempus egestas sed sed.
+
+  Quisque sagittis purus sit amet volutpat consequat mauris nunc. Erat imperdiet sed euismod nisi porta lorem. Massa tempor nec feugiat nisl pretium. Erat nam at lectus urna. Fusce id velit ut tortor pretium viverra suspendisse. In vitae turpis massa sed elementum tempus egestas sed sed. Sem nulla pharetra diam sit amet nisl suscipit. In nisl nisi scelerisque eu ultrices vitae auctor. Non diam phasellus vestibulum lorem sed risus. Urna porttitor rhoncus dolor purus non enim.
+
+  Mi bibendum neque egestas congue. Ac tortor vitae purus faucibus ornare suspendisse sed nisi lacus. Quam viverra orci sagittis eu volutpat odio. Mi tempus imperdiet nulla malesuada pellentesque elit. Ultricies lacus sed turpis tincidunt. In ornare quam viverra orci sagittis eu volutpat odio facilisis. Ut eu sem integer vitae justo eget magna fermentum. Sed augue lacus viverra vitae. Quam nulla porttitor massa id neque. Ut aliquam purus sit amet luctus. Ullamcorper eget nulla facilisi etiam dignissim.
+
+  Sed faucibus turpis in eu. Massa sapien faucibus et molestie. Sed vulputate odio ut enim blandit volutpat maecenas volutpat. Quis vel eros donec ac odio tempor orci dapibus. Odio euismod lacinia at quis. Sit amet consectetur adipiscing elit duis tristique sollicitudin. Malesuada nunc vel risus commodo viverra maecenas accumsan lacus vel. Sed tempus urna et pharetra pharetra massa. Donec massa sapien faucibus et molestie ac feugiat. Convallis convallis tellus id interdum velit. Et odio pellentesque diam volutpat commodo. Aliquet lectus proin nibh nisl condimentum id venenatis. Sed nisi lacus sed viverra tellus in hac habitasse. At lectus urna duis convallis convallis tellus id interdum. Elit pellentesque habitant morbi tristique senectus et. Lorem ipsum dolor sit amet. Mus mauris vitae ultricies leo integer malesuada nunc vel risus. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper. Ut pharetra sit amet aliquam id diam.
+
+  Euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis. Sit amet tellus cras adipiscing enim eu turpis egestas. Netus et malesuada fames ac turpis. Quis vel eros donec ac. Et malesuada fames ac turpis egestas integer eget. Amet est placerat in egestas erat imperdiet. Nec nam aliquam sem et tortor. Ac turpis egestas sed tempus urna et. Massa eget egestas purus viverra accumsan. Condimentum id venenatis a condimentum vitae sapien. Sagittis orci a scelerisque purus semper eget. Aliquet sagittis id consectetur purus ut faucibus pulvinar. Tempor id eu nisl nunc mi ipsum faucibus. Sed faucibus turpis in eu mi bibendum neque egestas congue. Morbi tincidunt augue interdum velit euismod in pellentesque. Amet nisl suscipit adipiscing bibendum est ultricies integer. Ut eu sem integer vitae justo eget magna fermentum. Nisi lacus sed viverra tellus. Scelerisque varius morbi enim nunc faucibus a pellentesque. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra.
+
+  Ut placerat orci nulla pellentesque dignissim enim. Tristique senectus et netus et malesuada. Diam in arcu cursus euismod quis viverra nibh cras pulvinar. Lobortis mattis aliquam faucibus purus in massa tempor. Libero id faucibus nisl tincidunt eget nullam non nisi est. Mauris pellentesque pulvinar pellentesque habitant. Est pellentesque elit ullamcorper dignissim cras tincidunt. Egestas sed sed risus pretium quam vulputate. Bibendum at varius vel pharetra. Libero nunc consequat interdum varius. Tincidunt vitae semper quis lectus nulla at volutpat diam. Augue eget arcu dictum varius duis. Varius vel pharetra vel turpis. Quam lacus suspendisse faucibus interdum posuere. Pulvinar neque laoreet suspendisse interdum consectetur libero id. Gravida arcu ac tortor dignissim convallis aenean et. Sit amet porttitor eget dolor morbi non arcu risus.
+
+  Imperdiet sed euismod nisi porta lorem mollis aliquam ut. Sit amet nulla facilisi morbi tempus iaculis. Eleifend mi in nulla posuere sollicitudin aliquam. Sed vulputate odio ut enim. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et. Lectus arcu bibendum at varius vel pharetra vel. Est ultricies integer quis auctor elit sed. Nulla facilisi cras fermentum odio eu feugiat pretium nibh. Nascetur ridiculus mus mauris vitae ultricies leo integer. Faucibus ornare suspendisse sed nisi. Netus et malesuada fames ac turpis. Scelerisque purus semper eget duis at tellus at urna condimentum. Mauris a diam maecenas sed.
+
+  Tortor id aliquet lectus proin nibh nisl condimentum. Urna nunc id cursus metus aliquam eleifend mi in. Risus commodo viverra maecenas accumsan lacus vel facilisis volutpat est. Vitae tempus quam pellentesque nec nam aliquam. Amet aliquam id diam maecenas ultricies mi. Morbi non arcu risus quis. Pharetra vel turpis nunc eget lorem. Tincidunt vitae semper quis lectus nulla at volutpat. Massa placerat duis ultricies lacus. Augue mauris augue neque gravida in fermentum. Viverra justo nec ultrices dui sapien. Semper auctor neque vitae tempus quam pellentesque. Ipsum consequat nisl vel pretium lectus quam id leo in. Dignissim cras tincidunt lobortis feugiat vivamus at augue eget arcu. Platea dictumst vestibulum rhoncus est pellentesque. Ipsum suspendisse ultrices gravida dictum fusce ut.
+
+  Euismod nisi porta lorem mollis aliquam ut porttitor leo. Ac turpis egestas integer eget aliquet nibh praesent tristique. Aliquet nec ullamcorper sit amet risus nullam eget. Id venenatis a condimentum vitae sapien pellentesque habitant morbi tristique. Placerat duis ultricies lacus sed turpis tincidunt id. Laoreet suspendisse interdum consectetur libero id faucibus nisl tincidunt eget. Convallis a cras semper auctor. Ornare aenean euismod elementum nisi quis eleifend quam adipiscing vitae. Arcu cursus vitae congue mauris rhoncus aenean vel elit scelerisque. Nec nam aliquam sem et tortor consequat id.
+
+  Risus viverra adipiscing at in tellus integer feugiat scelerisque varius. Aliquam sem et tortor consequat id. Nisi scelerisque eu ultrices vitae auctor eu augue ut. Ut morbi tincidunt augue interdum velit euismod. A scelerisque purus semper eget. Felis eget velit aliquet sagittis id consectetur purus. Blandit turpis cursus in hac habitasse platea dictumst quisque sagittis. Senectus et netus et malesuada fames ac turpis egestas integer. Urna nec tincidunt praesent semper. Quis viverra nibh cras pulvinar. Purus semper eget duis at tellus. Ante metus dictum at tempor. Eleifend mi in nulla posuere sollicitudin aliquam ultrices sagittis orci. Tincidunt eget nullam non nisi est. Dignissim sodales ut eu sem integer.
+
+  Euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis. Sit amet tellus cras adipiscing enim eu turpis egestas. Netus et malesuada fames ac turpis. Quis vel eros donec ac. Et malesuada fames ac turpis egestas integer eget. Amet est placerat in egestas erat imperdiet. Nec nam aliquam sem et tortor. Ac turpis egestas sed tempus urna et. Massa eget egestas purus viverra accumsan. Condimentum id venenatis a condimentum vitae sapien. Sagittis orci a scelerisque purus semper eget. Aliquet sagittis id consectetur purus ut faucibus pulvinar. Tempor id eu nisl nunc mi ipsum faucibus. Sed faucibus turpis in eu mi bibendum neque egestas congue. Morbi tincidunt augue interdum velit euismod in pellentesque. Amet nisl suscipit adipiscing bibendum est ultricies integer. Ut eu sem integer vitae justo eget magna fermentum. Nisi lacus sed viverra tellus. Scelerisque varius morbi enim nunc faucibus a pellentesque. Vitae purus faucibus ornare suspendisse sed nisi lacus sed viverra.
+
+  Ut placerat orci nulla pellentesque dignissim enim. Tristique senectus et netus et malesuada. Diam in arcu cursus euismod quis viverra nibh cras pulvinar. Lobortis mattis aliquam faucibus purus in massa tempor. Libero id faucibus nisl tincidunt eget nullam non nisi est. Mauris pellentesque pulvinar pellentesque habitant. Est pellentesque elit ullamcorper dignissim cras tincidunt. Egestas sed sed risus pretium quam vulputate. Bibendum at varius vel pharetra. Libero nunc consequat interdum varius. Tincidunt vitae semper quis lectus nulla at volutpat diam. Augue eget arcu dictum varius duis. Varius vel pharetra vel turpis. Quam lacus suspendisse faucibus interdum posuere. Pulvinar neque laoreet suspendisse interdum consectetur libero id. Gravida arcu ac tortor dignissim convallis aenean et. Sit amet porttitor eget dolor morbi non arcu risus.
+
+  Imperdiet sed euismod nisi porta lorem mollis aliquam ut. Sit amet nulla facilisi morbi tempus iaculis. Eleifend mi in nulla posuere sollicitudin aliquam. Sed vulputate odio ut enim. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et. Lectus arcu bibendum at varius vel pharetra vel. Est ultricies integer quis auctor elit sed. Nulla facilisi cras fermentum odio eu feugiat pretium nibh. Nascetur ridiculus mus mauris vitae ultricies leo integer. Faucibus ornare suspendisse sed nisi. Netus et malesuada fames ac turpis. Scelerisque purus semper eget duis at tellus at urna condimentum. Mauris a diam maecenas sed.
+
+</home>
diff --git a/third_party/WebKit/LayoutTests/xmlviewer/resources/long-multi-byte-char.xslt b/third_party/WebKit/LayoutTests/xmlviewer/resources/long-multi-byte-char.xslt
index 76054cab2..d3de6b1 100644
--- a/third_party/WebKit/LayoutTests/xmlviewer/resources/long-multi-byte-char.xslt
+++ b/third_party/WebKit/LayoutTests/xmlviewer/resources/long-multi-byte-char.xslt
@@ -1,14 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>

-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0" xmlns:v="urn:schemas-microsoft-com:vml">

-  <xsl:output method="html" encoding="utf-8" doctype-system="about:legacy-compat" />

-

-  <xsl:template match="/">

-    <html xmlns:v="urn:schemas-microsoft-com:vml">

-      <head>

-      </head>

-      <body id="test-body">

-        Test passes if you see this line, and this line alone.

-      </body>

-    </html>

-  </xsl:template>

-</xsl:stylesheet>

+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0" xmlns:v="urn:schemas-microsoft-com:vml">
+  <xsl:output method="html" encoding="utf-8" doctype-system="about:legacy-compat" />
+
+  <xsl:template match="/">
+    <html xmlns:v="urn:schemas-microsoft-com:vml">
+      <head>
+      </head>
+      <body id="test-body">
+        Test passes if you see this line, and this line alone.
+      </body>
+    </html>
+  </xsl:template>
+</xsl:stylesheet>
diff --git a/third_party/blink/common/feature_policy/feature_policy.cc b/third_party/blink/common/feature_policy/feature_policy.cc
index 6c8f16d..4213ae8 100644
--- a/third_party/blink/common/feature_policy/feature_policy.cc
+++ b/third_party/blink/common/feature_policy/feature_policy.cc
@@ -105,20 +105,6 @@
                                 GetDefaultFeatureList());
 }
 
-// static
-std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromPolicyWithOrigin(
-    const FeaturePolicy& policy,
-    const url::Origin& origin) {
-  std::unique_ptr<FeaturePolicy> new_policy =
-      base::WrapUnique(new FeaturePolicy(origin, policy.feature_list_));
-  new_policy->inherited_policies_ = policy.inherited_policies_;
-  for (const auto& feature : policy.allowlists_) {
-    new_policy->allowlists_[feature.first] =
-        base::WrapUnique(new Allowlist(*feature.second));
-  }
-  return new_policy;
-}
-
 bool FeaturePolicy::IsFeatureEnabled(
     mojom::FeaturePolicyFeature feature) const {
   return IsFeatureEnabledForOrigin(feature, origin_);
diff --git a/third_party/blink/common/service_worker/service_worker_type_converters.cc b/third_party/blink/common/service_worker/service_worker_type_converters.cc
index 3cd483f..8119eed 100644
--- a/third_party/blink/common/service_worker/service_worker_type_converters.cc
+++ b/third_party/blink/common/service_worker/service_worker_type_converters.cc
@@ -24,4 +24,18 @@
   return blink::ServiceWorkerStatusCode::kErrorFailed;
 }
 
+blink::ServiceWorkerStatusCode
+TypeConverter<blink::ServiceWorkerStatusCode,
+              blink::mojom::ServiceWorkerStartStatus>::
+    Convert(blink::mojom::ServiceWorkerStartStatus status) {
+  switch (status) {
+    case blink::mojom::ServiceWorkerStartStatus::kNormalCompletion:
+      return blink::ServiceWorkerStatusCode::kOk;
+    case blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion:
+      return blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed;
+  }
+  NOTREACHED() << status;
+  return blink::ServiceWorkerStatusCode::kErrorFailed;
+}
+
 }  // namespace mojo
diff --git a/third_party/blink/public/common/feature_policy/feature_policy.h b/third_party/blink/public/common/feature_policy/feature_policy.h
index 249e08c..4d2f9cd 100644
--- a/third_party/blink/public/common/feature_policy/feature_policy.h
+++ b/third_party/blink/public/common/feature_policy/feature_policy.h
@@ -174,10 +174,6 @@
       const ParsedFeaturePolicy& container_policy,
       const url::Origin& origin);
 
-  static std::unique_ptr<FeaturePolicy> CreateFromPolicyWithOrigin(
-      const FeaturePolicy& policy,
-      const url::Origin& origin);
-
   bool IsFeatureEnabled(mojom::FeaturePolicyFeature feature) const;
 
   // Returns whether or not the given feature is enabled by this policy for a
diff --git a/third_party/blink/public/common/service_worker/service_worker_type_converters.h b/third_party/blink/public/common/service_worker/service_worker_type_converters.h
index 447280b..cb3f431 100644
--- a/third_party/blink/public/common/service_worker/service_worker_type_converters.h
+++ b/third_party/blink/public/common/service_worker/service_worker_type_converters.h
@@ -19,6 +19,14 @@
       blink::mojom::ServiceWorkerEventStatus status);
 };
 
+template <>
+struct BLINK_COMMON_EXPORT
+    TypeConverter<blink::ServiceWorkerStatusCode,
+                  blink::mojom::ServiceWorkerStartStatus> {
+  static blink::ServiceWorkerStatusCode Convert(
+      blink::mojom::ServiceWorkerStartStatus status);
+};
+
 }  // namespace mojo
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_
diff --git a/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom b/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom
index 3a56a211..d126f4c 100644
--- a/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom
+++ b/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom
@@ -4,6 +4,8 @@
 
 module blink.mojom;
 
+// TODO(falken): Rename this file to service_worker_status.mojom.
+
 // The result of dispatching an event to a service worker.
 enum ServiceWorkerEventStatus {
   // The event dispatch completed successfully.
@@ -29,3 +31,23 @@
 
   MAX=ABORTED
 };
+
+// The result of starting a service worker.
+//
+// Currently these all mean that start succeeded as this enum is only used in
+// EmbeddedWorkerInstanceHost.OnStarted() which indicates startup completed.
+// The plan is to expand to include error codes too.
+//
+// These names are taken from the JavaScript spec as referred to by the HTML
+// spec for running a script:
+// https://html.spec.whatwg.org/multipage/webappapis.html#calling-scripts
+enum ServiceWorkerStartStatus {
+  // The service worker thread is running and initial JavaScript
+  // evaluation completed normally.
+  kNormalCompletion,
+
+  // The service worker thread is running but initial JavaScript
+  // evaluation completed abruptly, i.e., an uncaught runtime error
+  // occurred.
+  kAbruptCompletion
+};
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom
index c1649768..b857885 100644
--- a/third_party/blink/public/platform/web_feature.mojom
+++ b/third_party/blink/public/platform/web_feature.mojom
@@ -1957,6 +1957,7 @@
   kDocumentOpenTwoArgsWithReplace = 2495,
   kDocumentOpenThreeArgs = 2496,
   kV8FunctionTokenOffsetTooLongForToString = 2497,
+  kServiceWorkerImportScriptNotInstalled = 2498,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h
index 3c7d93a..88b229a 100644
--- a/third_party/blink/public/web/web_ax_object.h
+++ b/third_party/blink/public/web/web_ax_object.h
@@ -298,7 +298,6 @@
   BLINK_EXPORT unsigned RowCount() const;
   BLINK_EXPORT WebAXObject CellForColumnAndRow(unsigned column,
                                                unsigned row) const;
-  BLINK_EXPORT WebAXObject HeaderContainerObject() const;
   BLINK_EXPORT void RowHeaders(WebVector<WebAXObject>&) const;
   BLINK_EXPORT void ColumnHeaders(WebVector<WebAXObject>&) const;
 
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
index b0aa587..f38b2661 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -287,18 +287,21 @@
       return;
     }
 
-    // Get as much data from the ResourceBuffer as we can.
-    const char* data = nullptr;
-    while (size_t length =
-               resource_buffer_->GetSomeData(data, queue_tail_position_)) {
-      // Copy the data chunks into a new buffer, since we're going to
-      // give the data to a background thread.
-      uint8_t* copied_data = new uint8_t[length];
-      memcpy(copied_data, data, length);
-      data_queue_.Produce(copied_data, length);
+    // Get as much data from the ResourceBuffer as we can in one chunk.
+    const size_t length = resource_buffer_->size() - queue_tail_position_;
 
-      queue_tail_position_ += length;
+    uint8_t* const copied_data = new uint8_t[length];
+    size_t pos = 0;
+
+    const char* data = nullptr;
+    while (size_t segment_size = resource_buffer_->GetSomeData(
+               data, queue_tail_position_ + pos)) {
+      memcpy(copied_data + pos, data, segment_size);
+      pos += segment_size;
     }
+    DCHECK_EQ(pos, length);
+    queue_tail_position_ = resource_buffer_->size();
+    data_queue_.Produce(copied_data, length);
   }
 
   // For coordinating between the main thread and background thread tasks.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index 54c0c30..7a12d35 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -52,7 +52,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
 #include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index f6eb88dc..37448d2f 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1917,6 +1917,7 @@
     "layout/layout_count_test.cc",
     "layout/layout_embedded_content_test.cc",
     "layout/layout_geometry_map_test.cc",
+    "layout/layout_image_test.cc",
     "layout/layout_inline_test.cc",
     "layout/layout_media_test.cc",
     "layout/layout_multi_column_flow_thread_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.cc b/third_party/blink/renderer/core/css/css_style_sheet.cc
index 582e4b74..7af9a18 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet.cc
+++ b/third_party/blink/renderer/core/css/css_style_sheet.cc
@@ -92,14 +92,11 @@
 }
 
 CSSStyleSheet* CSSStyleSheet::Create(Document& document,
-                                     const String& text,
                                      ExceptionState& exception_state) {
-  return CSSStyleSheet::Create(document, text, CSSStyleSheetInit(),
-                               exception_state);
+  return CSSStyleSheet::Create(document, CSSStyleSheetInit(), exception_state);
 }
 
 CSSStyleSheet* CSSStyleSheet::Create(Document& document,
-                                     const String& text,
                                      const CSSStyleSheetInit& options,
                                      ExceptionState& exception_state) {
   if (!RuntimeEnabledFeatures::ConstructableStylesheetsEnabled()) {
@@ -114,19 +111,18 @@
   sheet->SetTitle(options.title());
   sheet->ClearOwnerNode();
   sheet->ClearOwnerRule();
-  if (options.media().IsString()) {
-    MediaList* media_list = MediaList::Create(
-        MediaQuerySet::Create(), const_cast<CSSStyleSheet*>(sheet));
-    media_list->setMediaText(options.media().GetAsString());
-    sheet->SetMedia(media_list);
-  } else {
-    sheet->SetMedia(options.media().GetAsMediaList());
-  }
+  scoped_refptr<MediaQuerySet> media_query_set;
+  if (options.media().IsString())
+    media_query_set = MediaQuerySet::Create(options.media().GetAsString());
+  else
+    media_query_set = options.media().GetAsMediaList()->Queries()->Copy();
+  MediaList* media_list =
+      MediaList::Create(media_query_set, const_cast<CSSStyleSheet*>(sheet));
+  sheet->SetMedia(media_list);
   if (options.alternate())
     sheet->SetAlternateFromConstructor(true);
   if (options.disabled())
     sheet->setDisabled(true);
-  sheet->SetText(text);
   return sheet;
 }
 
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.h b/third_party/blink/renderer/core/css/css_style_sheet.h
index 2c934ae..f67b37a 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet.h
+++ b/third_party/blink/renderer/core/css/css_style_sheet.h
@@ -53,9 +53,8 @@
  public:
   static const Document* SingleOwnerDocument(const CSSStyleSheet*);
 
-  static CSSStyleSheet* Create(Document&, const String&, ExceptionState&);
+  static CSSStyleSheet* Create(Document&, ExceptionState&);
   static CSSStyleSheet* Create(Document&,
-                               const String&,
                                const CSSStyleSheetInit&,
                                ExceptionState&);
 
@@ -200,12 +199,11 @@
 
   void SetLoadCompleted(bool);
 
+  FRIEND_TEST_ALL_PREFIXES(CSSStyleSheetTest,
+                           CSSStyleSheetConstructionWithEmptyCSSStyleSheetInit);
   FRIEND_TEST_ALL_PREFIXES(
       CSSStyleSheetTest,
-      CSSStyleSheetConstructionWithEmptyCSSStyleSheetInitAndText);
-  FRIEND_TEST_ALL_PREFIXES(
-      CSSStyleSheetTest,
-      CSSStyleSheetConstructionWithoutEmptyCSSStyleSheetInitAndText);
+      CSSStyleSheetConstructionWithNonEmptyCSSStyleSheetInit);
   bool AlternateFromConstructor() const { return alternate_from_constructor_; }
 
   Member<StyleSheetContents> contents_;
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.idl b/third_party/blink/renderer/core/css/css_style_sheet.idl
index b76761a..b70b9fe6 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet.idl
+++ b/third_party/blink/renderer/core/css/css_style_sheet.idl
@@ -23,7 +23,7 @@
 [
     ConstructorCallWith=Document,
     RaisesException=Constructor,
-    Constructor(DOMString text, optional CSSStyleSheetInit options),
+    Constructor(optional CSSStyleSheetInit options),
     Exposed=Window
 ] interface CSSStyleSheet : StyleSheet {
     readonly attribute CSSRule? ownerRule;
diff --git a/third_party/blink/renderer/core/css/css_style_sheet_test.cc b/third_party/blink/renderer/core/css/css_style_sheet_test.cc
index e213a2be..5011717 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet_test.cc
+++ b/third_party/blink/renderer/core/css/css_style_sheet_test.cc
@@ -23,17 +23,13 @@
 TEST_F(CSSStyleSheetTest, ConstructorWithoutRuntimeFlagThrowsException) {
   DummyExceptionStateForTesting exception_state;
   RuntimeEnabledFeatures::SetConstructableStylesheetsEnabled(false);
-  EXPECT_EQ(CSSStyleSheet::Create(GetDocument(), "", CSSStyleSheetInit(),
-                                  exception_state),
-            nullptr);
+  EXPECT_EQ(CSSStyleSheet::Create(GetDocument(), exception_state), nullptr);
   ASSERT_TRUE(exception_state.HadException());
 }
 
-TEST_F(CSSStyleSheetTest,
-       CSSStyleSheetConstructionWithEmptyCSSStyleSheetInitAndText) {
+TEST_F(CSSStyleSheetTest, CSSStyleSheetConstructionWithEmptyCSSStyleSheetInit) {
   DummyExceptionStateForTesting exception_state;
-  CSSStyleSheet* sheet = CSSStyleSheet::Create(
-      GetDocument(), "", CSSStyleSheetInit(), exception_state);
+  CSSStyleSheet* sheet = CSSStyleSheet::Create(GetDocument(), exception_state);
   ASSERT_FALSE(exception_state.HadException());
   EXPECT_TRUE(sheet->href().IsNull());
   EXPECT_EQ(sheet->parentStyleSheet(), nullptr);
@@ -48,17 +44,15 @@
 }
 
 TEST_F(CSSStyleSheetTest,
-       CSSStyleSheetConstructionWithoutEmptyCSSStyleSheetInitAndText) {
+       CSSStyleSheetConstructionWithNonEmptyCSSStyleSheetInit) {
   DummyExceptionStateForTesting exception_state;
-  String styleText[2] = {".red { color: red; }",
-                         ".red + span + span { color: red; }"};
   CSSStyleSheetInit init;
   init.setMedia(MediaListOrString::FromString("screen, print"));
   init.setTitle("test");
   init.setAlternate(true);
   init.setDisabled(true);
-  CSSStyleSheet* sheet = CSSStyleSheet::Create(
-      GetDocument(), styleText[0] + styleText[1], init, exception_state);
+  CSSStyleSheet* sheet =
+      CSSStyleSheet::Create(GetDocument(), init, exception_state);
   ASSERT_FALSE(exception_state.HadException());
   EXPECT_TRUE(sheet->href().IsNull());
   EXPECT_EQ(sheet->parentStyleSheet(), nullptr);
@@ -69,9 +63,7 @@
   EXPECT_EQ(sheet->title(), init.title());
   EXPECT_TRUE(sheet->AlternateFromConstructor());
   EXPECT_TRUE(sheet->disabled());
-  EXPECT_EQ(sheet->cssRules(exception_state)->length(), 2U);
-  EXPECT_EQ(sheet->cssRules(exception_state)->item(0)->cssText(), styleText[0]);
-  EXPECT_EQ(sheet->cssRules(exception_state)->item(1)->cssText(), styleText[1]);
+  EXPECT_EQ(sheet->cssRules(exception_state)->length(), 0U);
   ASSERT_FALSE(exception_state.HadException());
 }
 
diff --git a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
index 0899e58a..2957bc5 100644
--- a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
@@ -46,6 +46,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/page/viewport_description.h"
@@ -197,7 +198,7 @@
 
 void ViewportStyleResolver::Resolve() {
   if (!property_set_) {
-    document_->SetViewportDescription(
+    document_->GetViewportData().SetViewportDescription(
         ViewportDescription(ViewportDescription::kUserAgentStyleSheet));
     return;
   }
@@ -218,7 +219,7 @@
   if (HasViewportFitProperty(property_set_))
     description.SetViewportFit(ViewportFitValue());
 
-  document_->SetViewportDescription(description);
+  document_->GetViewportData().SetViewportDescription(description);
 
   DCHECK(initial_style_);
   if (initial_style_->HasViewportUnits())
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc
index 538489a..53346fb3 100644
--- a/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -18,8 +18,10 @@
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/dom/shadow_root_init.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/html/html_span_element.h"
 #include "third_party/blink/renderer/core/html/html_style_element.h"
@@ -1175,29 +1177,21 @@
   Document* document =
       ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument();
 
-  float min_width =
-      document->GetViewportDescription().min_width.GetFloatValue();
-  float max_width =
-      document->GetViewportDescription().max_width.GetFloatValue();
-  float min_height =
-      document->GetViewportDescription().min_height.GetFloatValue();
-  float max_height =
-      document->GetViewportDescription().max_height.GetFloatValue();
+  auto desc = document->GetViewportData().GetViewportDescription();
+  float min_width = desc.min_width.GetFloatValue();
+  float max_width = desc.max_width.GetFloatValue();
+  float min_height = desc.min_height.GetFloatValue();
+  float max_height = desc.max_height.GetFloatValue();
 
   const float device_scale = 3.5f;
   client.set_device_scale_factor(device_scale);
   web_view_impl->UpdateAllLifecyclePhases();
 
-  EXPECT_FLOAT_EQ(device_scale * min_width,
-                  document->GetViewportDescription().min_width.GetFloatValue());
-  EXPECT_FLOAT_EQ(device_scale * max_width,
-                  document->GetViewportDescription().max_width.GetFloatValue());
-  EXPECT_FLOAT_EQ(
-      device_scale * min_height,
-      document->GetViewportDescription().min_height.GetFloatValue());
-  EXPECT_FLOAT_EQ(
-      device_scale * max_height,
-      document->GetViewportDescription().max_height.GetFloatValue());
+  desc = document->GetViewportData().GetViewportDescription();
+  EXPECT_FLOAT_EQ(device_scale * min_width, desc.min_width.GetFloatValue());
+  EXPECT_FLOAT_EQ(device_scale * max_width, desc.max_width.GetFloatValue());
+  EXPECT_FLOAT_EQ(device_scale * min_height, desc.min_height.GetFloatValue());
+  EXPECT_FLOAT_EQ(device_scale * max_height, desc.max_height.GetFloatValue());
 }
 
 TEST_F(StyleEngineTest, MediaQueryAffectingValueChanged_StyleElementNoMedia) {
diff --git a/third_party/blink/renderer/core/css/style_environment_variables.cc b/third_party/blink/renderer/core/css/style_environment_variables.cc
index 98ce2ed4..ae14172c 100644
--- a/third_party/blink/renderer/core/css/style_environment_variables.cc
+++ b/third_party/blink/renderer/core/css/style_environment_variables.cc
@@ -8,12 +8,35 @@
 
 namespace blink {
 
+namespace {
+
+// This is the default value for all safe-area-inset-* variables.
+static const char kSafeAreaInsetDefault[] = "0px";
+
+// Use this to set default values for environment variables when the root
+// instance is created.
+void SetDefaultEnvironmentVariables(StyleEnvironmentVariables* instance) {
+  instance->SetVariable(UADefinedVariable::kSafeAreaInsetTop,
+                        kSafeAreaInsetDefault);
+  instance->SetVariable(UADefinedVariable::kSafeAreaInsetLeft,
+                        kSafeAreaInsetDefault);
+  instance->SetVariable(UADefinedVariable::kSafeAreaInsetBottom,
+                        kSafeAreaInsetDefault);
+  instance->SetVariable(UADefinedVariable::kSafeAreaInsetRight,
+                        kSafeAreaInsetDefault);
+}
+
+}  // namespace.
+
 // This owns the static root instance.
 class StyleEnvironmentVariables::RootOwner {
  public:
   StyleEnvironmentVariables& GetRoot() {
-    if (!instance_)
+    if (!instance_) {
       instance_ = base::AdoptRef(new StyleEnvironmentVariables());
+      SetDefaultEnvironmentVariables(instance_.get());
+    }
+
     return *instance_.get();
   };
 
@@ -28,6 +51,25 @@
 }
 
 // static
+const AtomicString StyleEnvironmentVariables::GetVariableName(
+    UADefinedVariable variable) {
+  switch (variable) {
+    case UADefinedVariable::kSafeAreaInsetTop:
+      return "safe-area-inset-top";
+    case UADefinedVariable::kSafeAreaInsetLeft:
+      return "safe-area-inset-left";
+    case UADefinedVariable::kSafeAreaInsetBottom:
+      return "safe-area-inset-bottom";
+    case UADefinedVariable::kSafeAreaInsetRight:
+      return "safe-area-inset-right";
+    default:
+      break;
+  }
+
+  NOTREACHED();
+}
+
+// static
 scoped_refptr<StyleEnvironmentVariables> StyleEnvironmentVariables::Create(
     StyleEnvironmentVariables& parent) {
   scoped_refptr<StyleEnvironmentVariables> obj =
@@ -61,13 +103,18 @@
   Vector<CSSParserToken> tokens;
   tokens.AppendVector(tokenizer.TokenizeToEOF());
 
-  Vector<String> backing_strings(1);
+  Vector<String> backing_strings;
   backing_strings.push_back(value);
 
   SetVariable(name,
               CSSVariableData::CreateResolved(tokens, backing_strings, false));
 }
 
+void StyleEnvironmentVariables::SetVariable(const UADefinedVariable name,
+                                            const String& value) {
+  SetVariable(GetVariableName(name), value);
+}
+
 void StyleEnvironmentVariables::RemoveVariable(const AtomicString& name) {
   data_.erase(name);
   InvalidateVariable(name);
@@ -94,6 +141,14 @@
   parent_ = nullptr;
 }
 
+void StyleEnvironmentVariables::ClearForTesting() {
+  data_.clear();
+
+  // If we are the root then we should re-apply the default variables.
+  if (!parent_)
+    SetDefaultEnvironmentVariables(this);
+}
+
 void StyleEnvironmentVariables::BindToParent(
     StyleEnvironmentVariables& parent) {
   DCHECK_EQ(nullptr, parent_);
diff --git a/third_party/blink/renderer/core/css/style_environment_variables.h b/third_party/blink/renderer/core/css/style_environment_variables.h
index 93f63a7..c545247 100644
--- a/third_party/blink/renderer/core/css/style_environment_variables.h
+++ b/third_party/blink/renderer/core/css/style_environment_variables.h
@@ -14,6 +14,19 @@
 
 namespace blink {
 
+// UADefinedVariable contains all the user agent defined environment variables.
+// When adding a new variable the string equivalent needs to be added to
+// |GetVariableName|.
+enum class UADefinedVariable {
+  // The safe area insets are four environment variables that define a
+  // rectangle by its top, right, bottom, and left insets from the edge of
+  // the viewport.
+  kSafeAreaInsetTop,
+  kSafeAreaInsetLeft,
+  kSafeAreaInsetBottom,
+  kSafeAreaInsetRight,
+};
+
 // StyleEnvironmentVariables stores user agent and user defined CSS environment
 // variables. It has a static root instance that stores global values and
 // each document has a child that stores document level values.
@@ -22,6 +35,9 @@
  public:
   static StyleEnvironmentVariables& GetRootInstance();
 
+  // Gets the name of a |UADefinedVariable| as a string.
+  static const AtomicString GetVariableName(UADefinedVariable);
+
   // Create a new instance bound to |parent|.
   static scoped_refptr<StyleEnvironmentVariables> Create(
       StyleEnvironmentVariables& parent);
@@ -34,6 +50,7 @@
 
   // Tokenize |value| and set it.
   void SetVariable(const AtomicString& name, const String& value);
+  void SetVariable(const UADefinedVariable name, const String& value);
 
   // Remove the variable |name| and invalidate any dependents.
   void RemoveVariable(const AtomicString& name);
@@ -48,7 +65,7 @@
  protected:
   friend class StyleEnvironmentVariablesTest;
 
-  void ClearForTesting() { data_.clear(); }
+  void ClearForTesting();
 
   // Bind this instance to a |parent|. This should only be called once.
   void BindToParent(StyleEnvironmentVariables& parent);
diff --git a/third_party/blink/renderer/core/css/style_environment_variables_test.cc b/third_party/blink/renderer/core/css/style_environment_variables_test.cc
index a4fb69a..a36a902 100644
--- a/third_party/blink/renderer/core/css/style_environment_variables_test.cc
+++ b/third_party/blink/renderer/core/css/style_environment_variables_test.cc
@@ -31,6 +31,8 @@
 // no set
 static const Color kNoColor = Color(0, 0, 0, 0);
 
+static const char kSafeAreaInsetExpectedDefault[] = "0px";
+
 }  // namespace
 
 class StyleEnvironmentVariablesTest : public PageTestBase {
@@ -71,6 +73,12 @@
                            "</div>");
   }
 
+  void InitializeTestPageWithVariableNamed(LocalFrame& frame,
+                                           const UADefinedVariable name) {
+    InitializeTestPageWithVariableNamed(
+        frame, StyleEnvironmentVariables::GetVariableName(name));
+  }
+
   void SimulateNavigation() {
     const KURL& url = KURL(NullURL(), "https://www.example.com");
     FrameLoadRequest request(nullptr, ResourceRequest(url),
@@ -79,6 +87,14 @@
     blink::test::RunPendingTasks();
     ASSERT_EQ(url.GetString(), GetDocument().Url().GetString());
   }
+
+  const String& GetRootVariableValue(UADefinedVariable name) {
+    CSSVariableData* data =
+        StyleEnvironmentVariables::GetRootInstance().ResolveVariable(
+            StyleEnvironmentVariables::GetVariableName(name));
+    EXPECT_NE(nullptr, data);
+    return data->BackingStrings()[0];
+  }
 };
 
 TEST_F(StyleEnvironmentVariablesTest, DocumentVariable_AfterLoad) {
@@ -296,6 +312,21 @@
                                GetCSSPropertyBackgroundColor()));
 }
 
+TEST_F(StyleEnvironmentVariablesTest, GlobalVariable_DefaultsPresent) {
+  EXPECT_EQ(kSafeAreaInsetExpectedDefault,
+            GetRootVariableValue(UADefinedVariable::kSafeAreaInsetTop));
+  EXPECT_EQ(kSafeAreaInsetExpectedDefault,
+            GetRootVariableValue(UADefinedVariable::kSafeAreaInsetLeft));
+  EXPECT_EQ(kSafeAreaInsetExpectedDefault,
+            GetRootVariableValue(UADefinedVariable::kSafeAreaInsetBottom));
+  EXPECT_EQ(kSafeAreaInsetExpectedDefault,
+            GetRootVariableValue(UADefinedVariable::kSafeAreaInsetRight));
+
+  EXPECT_EQ(
+      nullptr,
+      StyleEnvironmentVariables::GetRootInstance().ResolveVariable("test"));
+}
+
 TEST_F(StyleEnvironmentVariablesTest, GlobalVariable_Preset) {
   StyleEnvironmentVariables::GetRootInstance().SetVariable(kVariableName,
                                                            kVariableTestColor);
@@ -331,10 +362,14 @@
 
 TEST_F(StyleEnvironmentVariablesTest,
        DISABLED_PrintExpectedVariableNameHashes) {
-  const AtomicString kVariableNames[] = {
-      "safe-area-inset-top", "safe-area-inset-left", "safe-area-inset-bottom",
-      "safe-area-inset-right"};
-  for (const auto& name : kVariableNames) {
+  const UADefinedVariable variables[] = {
+      UADefinedVariable::kSafeAreaInsetTop,
+      UADefinedVariable::kSafeAreaInsetLeft,
+      UADefinedVariable::kSafeAreaInsetRight,
+      UADefinedVariable::kSafeAreaInsetBottom};
+  for (const auto& variable : variables) {
+    const AtomicString name =
+        StyleEnvironmentVariables::GetVariableName(variable);
     printf("0x%x\n",
            DocumentStyleEnvironmentVariables::GenerateHashFromName(name));
   }
@@ -368,7 +403,8 @@
 }
 
 TEST_F(StyleEnvironmentVariablesTest, RecordUseCounter_SafeAreaInsetBottom) {
-  InitializeTestPageWithVariableNamed(GetFrame(), "safe-area-inset-bottom");
+  InitializeTestPageWithVariableNamed(GetFrame(),
+                                      UADefinedVariable::kSafeAreaInsetBottom);
 
   EXPECT_TRUE(UseCounter::IsCounted(GetDocument(),
                                     WebFeature::kCSSEnvironmentVariable));
@@ -377,7 +413,8 @@
 }
 
 TEST_F(StyleEnvironmentVariablesTest, RecordUseCounter_SafeAreaInsetLeft) {
-  InitializeTestPageWithVariableNamed(GetFrame(), "safe-area-inset-left");
+  InitializeTestPageWithVariableNamed(GetFrame(),
+                                      UADefinedVariable::kSafeAreaInsetLeft);
 
   EXPECT_TRUE(UseCounter::IsCounted(GetDocument(),
                                     WebFeature::kCSSEnvironmentVariable));
@@ -386,7 +423,8 @@
 }
 
 TEST_F(StyleEnvironmentVariablesTest, RecordUseCounter_SafeAreaInsetRight) {
-  InitializeTestPageWithVariableNamed(GetFrame(), "safe-area-inset-right");
+  InitializeTestPageWithVariableNamed(GetFrame(),
+                                      UADefinedVariable::kSafeAreaInsetRight);
 
   EXPECT_TRUE(UseCounter::IsCounted(GetDocument(),
                                     WebFeature::kCSSEnvironmentVariable));
@@ -395,7 +433,8 @@
 }
 
 TEST_F(StyleEnvironmentVariablesTest, RecordUseCounter_SafeAreaInsetTop) {
-  InitializeTestPageWithVariableNamed(GetFrame(), "safe-area-inset-top");
+  InitializeTestPageWithVariableNamed(GetFrame(),
+                                      UADefinedVariable::kSafeAreaInsetTop);
 
   EXPECT_TRUE(UseCounter::IsCounted(GetDocument(),
                                     WebFeature::kCSSEnvironmentVariable));
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn
index 7128c2a2..9038a73 100644
--- a/third_party/blink/renderer/core/dom/BUILD.gn
+++ b/third_party/blink/renderer/core/dom/BUILD.gn
@@ -114,8 +114,6 @@
     "element_visibility_observer.h",
     "empty_node_list.cc",
     "empty_node_list.h",
-    "event_dispatch_forbidden_scope.cc",
-    "event_dispatch_forbidden_scope.h",
     "events/add_event_listener_options_defaults.h",
     "events/add_event_listener_options_resolved.cc",
     "events/add_event_listener_options_resolved.h",
@@ -123,6 +121,8 @@
     "events/custom_event.h",
     "events/event.cc",
     "events/event.h",
+    "events/event_dispatch_forbidden_scope.cc",
+    "events/event_dispatch_forbidden_scope.h",
     "events/event_dispatch_result.h",
     "events/event_dispatcher.cc",
     "events/event_dispatcher.h",
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc
index 087145b..0f5fe8a 100644
--- a/third_party/blink/renderer/core/dom/container_node.cc
+++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -30,7 +30,7 @@
 #include "third_party/blink/renderer/core/dom/child_list_mutation_scope.h"
 #include "third_party/blink/renderer/core/dom/class_collection.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/name_node_list.h"
 #include "third_party/blink/renderer/core/dom/node_child_removal_tracker.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index cb767c9..4783cd2 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -83,6 +83,7 @@
 #include "third_party/blink/renderer/core/dom/comment.h"
 #include "third_party/blink/renderer/core/dom/context_features.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_parser_timing.h"
 #include "third_party/blink/renderer/core/dom/document_type.h"
 #include "third_party/blink/renderer/core/dom/dom_implementation.h"
@@ -91,8 +92,8 @@
 #include "third_party/blink/renderer/core/dom/element_data_cache.h"
 #include "third_party/blink/renderer/core/dom/element_registration_options.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event_listener.h"
 #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
@@ -145,6 +146,7 @@
 #include "third_party/blink/renderer/core/frame/performance_monitor.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
@@ -577,6 +579,10 @@
       online_observer_handle_;
 };
 
+Document* Document::CreateForTest() {
+  return new Document(DocumentInit::Create());
+}
+
 Document* Document::Create(Document& document) {
   Document* new_document = new Document(
       DocumentInit::Create().WithContextDocument(&document).WithURL(
@@ -684,7 +690,8 @@
 #if DCHECK_IS_ON()
       slot_assignment_recalc_forbidden_recursion_depth_(0),
 #endif
-      needs_to_record_ukm_outlive_time_(false) {
+      needs_to_record_ukm_outlive_time_(false),
+      viewport_data_(new ViewportData(*this)) {
   if (frame_) {
     DCHECK(frame_->GetPage());
     ProvideContextFeaturesToDocumentFrom(*this, *frame_->GetPage());
@@ -2694,9 +2701,7 @@
   if (!IsActive())
     return;
 
-  // TODO(https://crbug.com/800641): Use InterfaceInvalidator once it works with
-  // associated interfaces.
-  display_cutout_host_.reset();
+  GetViewportData().Shutdown();
 
   // Frame navigation can cause a new Document to be attached. Don't allow that,
   // since that will cause a situation where LocalFrame still has a Document
@@ -3405,7 +3410,7 @@
   // No need to repeat if we've already notified this load as finished.
   if (!Loader()->SentDidFinishLoad()) {
     if (frame_->IsMainFrame())
-      GetViewportDescription().ReportMobilePageStats(frame_);
+      GetViewportData().GetViewportDescription().ReportMobilePageStats(frame_);
     Loader()->SetSentDidFinishLoad();
     frame_->Client()->DispatchDidFinishLoad();
     if (!frame_)
@@ -4084,86 +4089,6 @@
                                                     http_refresh_type);
 }
 
-bool Document::ShouldMergeWithLegacyDescription(
-    ViewportDescription::Type origin) const {
-  return GetSettings() && GetSettings()->GetViewportMetaMergeContentQuirk() &&
-         legacy_viewport_description_.IsMetaViewportType() &&
-         legacy_viewport_description_.type == origin;
-}
-
-void Document::SetViewportDescription(
-    const ViewportDescription& viewport_description) {
-  if (viewport_description.IsLegacyViewportType()) {
-    if (viewport_description == legacy_viewport_description_)
-      return;
-    legacy_viewport_description_ = viewport_description;
-  } else {
-    if (viewport_description == viewport_description_)
-      return;
-    viewport_description_ = viewport_description;
-
-    // The UA-defined min-width is considered specifically by Android WebView
-    // quirks mode.
-    if (!viewport_description.IsSpecifiedByAuthor())
-      viewport_default_min_width_ = viewport_description.min_width;
-  }
-
-  UpdateViewportDescription();
-}
-
-ViewportDescription Document::GetViewportDescription() const {
-  ViewportDescription applied_viewport_description = viewport_description_;
-  bool viewport_meta_enabled =
-      GetSettings() && GetSettings()->GetViewportMetaEnabled();
-  if (legacy_viewport_description_.type !=
-          ViewportDescription::kUserAgentStyleSheet &&
-      viewport_meta_enabled)
-    applied_viewport_description = legacy_viewport_description_;
-  if (ShouldOverrideLegacyDescription(viewport_description_.type))
-    applied_viewport_description = viewport_description_;
-
-  return applied_viewport_description;
-}
-
-void Document::UpdateViewportDescription() {
-  if (!GetFrame())
-    return;
-
-  // If the viewport_fit has changed we should send this to the browser. We
-  // use the legacy viewport description which contains the viewport_fit
-  // defined from the layout meta tag.
-  mojom::ViewportFit current_viewport_fit =
-      GetViewportDescription().GetViewportFit();
-
-  // If we are forcing to expand into the display cutout then we should override
-  // the viewport fit value.
-  if (force_expand_display_cutout_)
-    current_viewport_fit = mojom::ViewportFit::kCover;
-
-  if (viewport_fit_ != current_viewport_fit) {
-    if (frame_->Client()->GetRemoteNavigationAssociatedInterfaces()) {
-      // Bind the mojo interface.
-      if (!display_cutout_host_.is_bound()) {
-        frame_->Client()
-            ->GetRemoteNavigationAssociatedInterfaces()
-            ->GetInterface(&display_cutout_host_);
-        DCHECK(display_cutout_host_.is_bound());
-      }
-
-      // Even though we bind the mojo interface above there still may be cases
-      // where this will fail (e.g. unit tests).
-      display_cutout_host_->NotifyViewportFitChanged(current_viewport_fit);
-    }
-
-    viewport_fit_ = current_viewport_fit;
-  }
-
-  if (GetFrame()->IsMainFrame()) {
-    GetPage()->GetChromeClient().DispatchViewportPropertiesDidChange(
-        GetViewportDescription());
-  }
-}
-
 // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
 String Document::OutgoingReferrer() const {
   // Step 3.1: "If environment's global object is a Window object, then"
@@ -7433,6 +7358,7 @@
   visitor->Trace(network_state_observer_);
   visitor->Trace(policy_);
   visitor->Trace(slot_assignment_engine_);
+  visitor->Trace(viewport_data_);
   Supplementable<Document>::Trace(visitor);
   TreeScope::Trace(visitor);
   ContainerNode::Trace(visitor);
@@ -7495,14 +7421,6 @@
   return false;
 }
 
-void Document::SetExpandIntoDisplayCutout(bool expand) {
-  if (force_expand_display_cutout_ == expand)
-    return;
-
-  force_expand_display_cutout_ = expand;
-  UpdateViewportDescription();
-}
-
 template class CORE_TEMPLATE_EXPORT Supplement<Document>;
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 1fded5aa..cbba5b6 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -34,14 +34,12 @@
 #include <utility>
 
 #include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.h"
 #include "third_party/blink/public/platform/web_focus_type.h"
 #include "third_party/blink/public/platform/web_insecure_request_policy.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/container_node.h"
 #include "third_party/blink/renderer/core/dom/create_element_flags.h"
 #include "third_party/blink/renderer/core/dom/document_encoding_data.h"
-#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_lifecycle.h"
 #include "third_party/blink/renderer/core/dom/document_shutdown_notifier.h"
 #include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
@@ -51,20 +49,18 @@
 #include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
 #include "third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h"
 #include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
-#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/dom/text_link_colors.h"
 #include "third_party/blink/renderer/core/dom/tree_scope.h"
 #include "third_party/blink/renderer/core/dom/user_action_element_set.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/security_context.h"
 #include "third_party/blink/renderer/core/frame/dom_timer_coordinator.h"
 #include "third_party/blink/renderer/core/frame/hosts_using_features.h"
 #include "third_party/blink/renderer/core/html/custom/v0_custom_element.h"
 #include "third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h"
-#include "third_party/blink/renderer/core/page/viewport_description.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
-#include "third_party/blink/renderer/platform/length.h"
 #include "third_party/blink/renderer/platform/scroll/scroll_types.h"
 #include "third_party/blink/renderer/platform/timer.h"
 #include "third_party/blink/renderer/platform/web_task_runner.h"
@@ -102,6 +98,7 @@
 class DOMImplementation;
 class DOMWindow;
 class DocumentFragment;
+class DocumentInit;
 class DocumentLoader;
 class DocumentMarkerController;
 class DocumentNameCollection;
@@ -161,6 +158,7 @@
 class RootScrollerController;
 class SVGDocumentExtensions;
 class SVGUseElement;
+class Text;
 class TrustedHTML;
 class ScriptElementBase;
 class ScriptRunner;
@@ -181,6 +179,7 @@
 class TransformSource;
 class TreeWalker;
 class V8NodeFilter;
+class ViewportData;
 class VisitedLinkState;
 class WebMouseEvent;
 class WorkletAnimationController;
@@ -261,9 +260,7 @@
   static Document* Create(const DocumentInit& init) {
     return new Document(init);
   }
-  static Document* CreateForTest() {
-    return new Document(DocumentInit::Create());
-  }
+  static Document* CreateForTest();
   // Factory for web-exposed Document constructor. The argument document must be
   // a document instance representing window.document, and it works as the
   // source of ExecutionContext and security origin of the new document.
@@ -312,11 +309,7 @@
   DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(visibilitychange);
 
-  bool ShouldMergeWithLegacyDescription(ViewportDescription::Type) const;
-  bool ShouldOverrideLegacyDescription(ViewportDescription::Type) const;
-  void SetViewportDescription(const ViewportDescription&);
-  ViewportDescription GetViewportDescription() const;
-  Length ViewportDefaultMinWidth() const { return viewport_default_min_width_; }
+  ViewportData& GetViewportData() const { return *viewport_data_; }
 
   String OutgoingReferrer() const override;
   ReferrerPolicy GetReferrerPolicy() const override;
@@ -869,8 +862,6 @@
   }
   ResizeObserverController& EnsureResizeObserverController();
 
-  void UpdateViewportDescription();
-
   // Returns the owning element in the parent document. Returns nullptr if
   // this is the top level document or the owner is remote.
   HTMLFrameOwnerElement* LocalOwner() const;
@@ -1415,13 +1406,6 @@
   }
 #endif
 
-  // When true this will force a kCover viewport fit value which will result in
-  // the document expanding into the display cutout area.
-  void SetExpandIntoDisplayCutout(bool expand);
-  mojom::ViewportFit GetCurrentViewportFitForTests() const {
-    return viewport_fit_;
-  }
-
   bool IsVerticalScrollEnforced() const { return is_vertical_scroll_enforced_; }
 
  protected:
@@ -1743,10 +1727,6 @@
   TaskRunnerTimer<Document> load_event_delay_timer_;
   TaskRunnerTimer<Document> plugin_loading_timer_;
 
-  ViewportDescription viewport_description_;
-  ViewportDescription legacy_viewport_description_;
-  Length viewport_default_min_width_;
-
   DocumentTiming document_timing_;
   Member<MediaQueryMatcher> media_query_matcher_;
   bool write_recursion_is_too_deep_;
@@ -1841,26 +1821,15 @@
   // Used for legacy layout tree fallback
   ReattachLegacyLayoutObjectList* reattach_legacy_object_list_;
 
-  // Stores the current value viewport-fit value.
-  mojom::ViewportFit viewport_fit_ = blink::mojom::ViewportFit::kAuto;
-  bool force_expand_display_cutout_ = false;
+  // TODO(tkent): Should it be moved to LocalFrame or LocalFrameView?
+  Member<ViewportData> viewport_data_;
 
   // This is set through feature policy 'vertical-scroll'.
   bool is_vertical_scroll_enforced_ = false;
-
-  mojom::blink::DisplayCutoutHostAssociatedPtr display_cutout_host_;
 };
 
 extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Document>;
 
-inline bool Document::ShouldOverrideLegacyDescription(
-    ViewportDescription::Type origin) const {
-  // The different (legacy) meta tags have different priorities based on the
-  // type regardless of which order they appear in the DOM. The priority is
-  // given by the ViewportDescription::Type enum.
-  return origin >= legacy_viewport_description_.type;
-}
-
 inline void Document::ScheduleLayoutTreeUpdateIfNeeded() {
   // Inline early out to avoid the function calls below.
   if (HasPendingVisualUpdate())
diff --git a/third_party/blink/renderer/core/dom/document_shutdown_observer.cc b/third_party/blink/renderer/core/dom/document_shutdown_observer.cc
index 321bbd8..76f3327 100644
--- a/third_party/blink/renderer/core/dom/document_shutdown_observer.cc
+++ b/third_party/blink/renderer/core/dom/document_shutdown_observer.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
 
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_shutdown_notifier.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/dom/document_shutdown_observer.h b/third_party/blink/renderer/core/dom/document_shutdown_observer.h
index 3e0a78db..e7321eca 100644
--- a/third_party/blink/renderer/core/dom/document_shutdown_observer.h
+++ b/third_party/blink/renderer/core/dom/document_shutdown_observer.h
@@ -6,11 +6,12 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_SHUTDOWN_OBSERVER_H_
 
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/platform/lifecycle_observer.h"
 
 namespace blink {
 
+class Document;
+
 // This class is a base class for classes which observe Document shutdown
 // synchronously.
 // Note: this functionality is also provided by SynchronousMutationObserver,
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc
index 5eb974f..f1b37fd 100644
--- a/third_party/blink/renderer/core/dom/document_test.cc
+++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/html/forms/html_input_element.h"
 #include "third_party/blink/renderer/core/html/html_head_element.h"
 #include "third_party/blink/renderer/core/html/html_link_element.h"
@@ -1066,7 +1067,7 @@
   }
 
   mojom::ViewportFit GetViewportFit() const {
-    return GetDocument().GetCurrentViewportFitForTests();
+    return GetDocument().GetViewportData().GetCurrentViewportFitForTests();
   }
 };
 
@@ -1099,7 +1100,7 @@
   EXPECT_EQ(mojom::ViewportFit::kContain, GetViewportFit());
 
   // Now override the viewport fit value and expect it to be kCover.
-  GetDocument().SetExpandIntoDisplayCutout(true);
+  GetDocument().GetViewportData().SetExpandIntoDisplayCutout(true);
   EXPECT_EQ(mojom::ViewportFit::kCover, GetViewportFit());
 
   // Test that even if we change the value we ignore it.
@@ -1107,7 +1108,7 @@
   EXPECT_EQ(mojom::ViewportFit::kCover, GetViewportFit());
 
   // Now remove the override and check that it went back to the previous value.
-  GetDocument().SetExpandIntoDisplayCutout(false);
+  GetDocument().GetViewportData().SetExpandIntoDisplayCutout(false);
   EXPECT_EQ(mojom::ViewportFit::kAuto, GetViewportFit());
 }
 
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 0a2f995a..21accab 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -58,7 +58,7 @@
 #include "third_party/blink/renderer/core/dom/element_data_cache.h"
 #include "third_party/blink/renderer/core/dom/element_rare_data.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
 #include "third_party/blink/renderer/core/dom/first_letter_pseudo_element.h"
 #include "third_party/blink/renderer/core/dom/layout_tree_builder.h"
diff --git a/third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.cc b/third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.cc
similarity index 77%
rename from third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.cc
rename to third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.cc
index ef7bd04..73ab12b 100644
--- a/third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.cc
+++ b/third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h b/third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h
similarity index 85%
rename from third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h
rename to third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h
index ab645cc..4a5462c6 100644
--- a/third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h
+++ b/third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_
 
 #include "base/auto_reset.h"
 #include "base/macros.h"
@@ -72,4 +72,4 @@
 
 }  // namespace blink
 
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_
diff --git a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
index ac95f4c..9253754 100644
--- a/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
+++ b/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
@@ -32,7 +32,7 @@
 #include "third_party/blink/renderer/core/dom/container_node.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
 #include "third_party/blink/renderer/core/dom/events/window_event_context.h"
 #include "third_party/blink/renderer/core/events/mouse_event.h"
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc
index 7b90ecfa..261acd0 100644
--- a/third_party/blink/renderer/core/dom/events/event_target.cc
+++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -39,8 +39,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/event_listener_options_or_boolean.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event_target_impl.h"
 #include "third_party/blink/renderer/core/editing/editor.h"
 #include "third_party/blink/renderer/core/events/event_util.h"
diff --git a/third_party/blink/renderer/core/dom/events/event_target.h b/third_party/blink/renderer/core/dom/events/event_target.h
index 5f0f727..eb021cc3 100644
--- a/third_party/blink/renderer/core/dom/events/event_target.h
+++ b/third_party/blink/renderer/core/dom/events/event_target.h
@@ -242,7 +242,7 @@
   // EventTargetData is a GCed object, so it should not be used as a part of
   // object. However, we intentionally use it as a part of object for
   // performance, assuming that no one extracts a pointer of
-  // EventTargetWithInlineData::m_eventTargetData and store it to a Member etc.
+  // EventTargetWithInlineData::event_target_data_ and store it to a Member etc.
   GC_PLUGIN_IGNORE("513199") EventTargetData event_target_data_;
 };
 
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index c71d42c2..0f03ab0e 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -43,8 +43,8 @@
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/element_rare_data.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
 #include "third_party/blink/renderer/core/dom/events/event_listener.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc
index 57330dca..63774b8 100644
--- a/third_party/blink/renderer/core/dom/range.cc
+++ b/third_party/blink/renderer/core/dom/range.cc
@@ -28,7 +28,7 @@
 #include "third_party/blink/renderer/core/dom/character_data.h"
 #include "third_party/blink/renderer/core/dom/container_node.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
diff --git a/third_party/blink/renderer/core/dom/range_boundary_point.h b/third_party/blink/renderer/core/dom/range_boundary_point.h
index 3b92cd6..8c3a071c 100644
--- a/third_party/blink/renderer/core/dom/range_boundary_point.h
+++ b/third_party/blink/renderer/core/dom/range_boundary_point.h
@@ -26,6 +26,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_RANGE_BOUNDARY_POINT_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_RANGE_BOUNDARY_POINT_H_
 
+#include "third_party/blink/renderer/core/dom/character_data.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 #include "third_party/blink/renderer/core/editing/position.h"
diff --git a/third_party/blink/renderer/core/dom/shadow_root.cc b/third_party/blink/renderer/core/dom/shadow_root.cc
index f8d81f8..dfc0422 100644
--- a/third_party/blink/renderer/core/dom/shadow_root.cc
+++ b/third_party/blink/renderer/core/dom/shadow_root.cc
@@ -33,7 +33,7 @@
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/css/style_sheet_list.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/shadow_root_v0.h"
 #include "third_party/blink/renderer/core/dom/slot_assignment.h"
 #include "third_party/blink/renderer/core/dom/slot_assignment_engine.h"
diff --git a/third_party/blink/renderer/core/dom/slot_assignment_test.cc b/third_party/blink/renderer/core/dom/slot_assignment_test.cc
index e4b668c..5ae7336d 100644
--- a/third_party/blink/renderer/core/dom/slot_assignment_test.cc
+++ b/third_party/blink/renderer/core/dom/slot_assignment_test.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/html/html_collection.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/html/html_slot_element.h"
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc
index 6395b14..00ce0d5 100644
--- a/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc
+++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
diff --git a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
index 942ba3c..fe65f08c 100644
--- a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
+++ b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h"
 
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/commands/selection_for_undo_step.h"
 #include "third_party/blink/renderer/core/editing/commands/typing_command.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
diff --git a/third_party/blink/renderer/core/editing/editing_style_utilities.cc b/third_party/blink/renderer/core/editing/editing_style_utilities.cc
index d5608a3e..14692dc4 100644
--- a/third_party/blink/renderer/core/editing/editing_style_utilities.cc
+++ b/third_party/blink/renderer/core/editing/editing_style_utilities.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/css_property_names.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/editing_style.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
 #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.h b/third_party/blink/renderer/core/editing/ime/input_method_controller.h
index 34f9ed9..9f2ed35 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller.h
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.h
@@ -31,6 +31,7 @@
 #include "third_party/blink/public/platform/web_text_input_info.h"
 #include "third_party/blink/public/platform/web_text_input_type.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
 #include "third_party/blink/renderer/core/editing/ime/ime_text_span.h"
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
index 7170b04b..494c141 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h"
 
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
 #include "third_party/blink/renderer/core/editing/iterators/backwards_text_buffer.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
diff --git a/third_party/blink/renderer/core/editing/selection_controller.h b/third_party/blink/renderer/core/editing/selection_controller.h
index 4919e87f..e16e007 100644
--- a/third_party/blink/renderer/core/editing/selection_controller.h
+++ b/third_party/blink/renderer/core/editing/selection_controller.h
@@ -29,6 +29,7 @@
 
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/position_with_affinity.h"
diff --git a/third_party/blink/renderer/core/editing/serializers/serialization.cc b/third_party/blink/renderer/core/editing/serializers/serialization.cc
index aea3d26..4aacc70 100644
--- a/third_party/blink/renderer/core/editing/serializers/serialization.cc
+++ b/third_party/blink/renderer/core/editing/serializers/serialization.cc
@@ -38,6 +38,7 @@
 #include "third_party/blink/renderer/core/dom/comment.h"
 #include "third_party/blink/renderer/core/dom/context_features.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 #include "third_party/blink/renderer/core/dom/range.h"
diff --git a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h
index 96b6440..31237ed 100644
--- a/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h
+++ b/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CALLBACK_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CALLBACK_H_
 
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
 #include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
diff --git a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h
index 255153ea..43754fa 100644
--- a/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h
+++ b/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/platform/input_host.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
 #include "third_party/blink/renderer/core/editing/markers/document_marker.h"
diff --git a/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc b/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc
index 05c851dcd..dbbcd24 100644
--- a/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc
+++ b/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/editing/testing/selection_sample.h"
 
 #include "third_party/blink/renderer/core/dom/processing_instruction.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/selection_template.h"
 #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
 
diff --git a/third_party/blink/renderer/core/execution_context/security_context.cc b/third_party/blink/renderer/core/execution_context/security_context.cc
index 4b098f3..1ec0c65 100644
--- a/third_party/blink/renderer/core/execution_context/security_context.cc
+++ b/third_party/blink/renderer/core/execution_context/security_context.cc
@@ -63,7 +63,6 @@
 void SecurityContext::SetSecurityOrigin(
     scoped_refptr<SecurityOrigin> security_origin) {
   security_origin_ = std::move(security_origin);
-  UpdateFeaturePolicyOrigin();
 }
 
 void SecurityContext::SetContentSecurityPolicy(
@@ -121,11 +120,4 @@
   feature_policy_->SetHeaderPolicy(parsed_header);
 }
 
-void SecurityContext::UpdateFeaturePolicyOrigin() {
-  if (!feature_policy_)
-    return;
-  feature_policy_ = FeaturePolicy::CreateFromPolicyWithOrigin(
-      *feature_policy_, security_origin_->ToUrlOrigin());
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/execution_context/security_context.h b/third_party/blink/renderer/core/execution_context/security_context.h
index 3d259b13..195a58d 100644
--- a/third_party/blink/renderer/core/execution_context/security_context.h
+++ b/third_party/blink/renderer/core/execution_context/security_context.h
@@ -122,7 +122,6 @@
   void InitializeFeaturePolicy(const ParsedFeaturePolicy& parsed_header,
                                const ParsedFeaturePolicy& container_policy,
                                const FeaturePolicy* parent_feature_policy);
-  void UpdateFeaturePolicyOrigin();
 
   // Apply the sandbox flag. In addition, if the origin is not already opaque,
   // the origin is updated to a newly created unique opaque origin, setting the
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index a3f40b2c..6c710c0c 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -111,6 +111,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/remote_frame.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -1304,7 +1305,8 @@
 
   EXPECT_TRUE(SetTextAutosizingMultiplier(document, 2));
 
-  ViewportDescription description = document->GetViewportDescription();
+  ViewportDescription description =
+      document->GetViewportData().GetViewportDescription();
   // Choose a width that's not going match the viewport width of the loaded
   // document.
   description.min_width = Length(100, blink::kFixed);
@@ -1537,12 +1539,13 @@
 
   EXPECT_EQ(0.25f, web_view_helper.GetWebView()->PageScaleFactor());
 
-  Document* document =
+  ViewportData& viewport =
       ToLocalFrame(web_view_helper.GetWebView()->GetPage()->MainFrame())
-          ->GetDocument();
-  ViewportDescription description = document->GetViewportDescription();
+          ->GetDocument()
+          ->GetViewportData();
+  ViewportDescription description = viewport.GetViewportDescription();
   description.zoom = 2;
-  document->SetViewportDescription(description);
+  viewport.SetViewportDescription(description);
   web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
   EXPECT_EQ(2, web_view_helper.GetWebView()->PageScaleFactor());
 }
@@ -2104,16 +2107,17 @@
   settings->SetShrinksViewportContentToFit(true);
   web_view_helper.Resize(WebSize(viewport_width, viewport_height));
 
-  Document* document =
+  ViewportData& viewport =
       ToLocalFrame(web_view_helper.GetWebView()->GetPage()->MainFrame())
-          ->GetDocument();
-  EXPECT_FALSE(document->GetViewportDescription().IsLegacyViewportType());
+          ->GetDocument()
+          ->GetViewportData();
+  EXPECT_FALSE(viewport.GetViewportDescription().IsLegacyViewportType());
 
   settings->SetViewportMetaEnabled(true);
-  EXPECT_TRUE(document->GetViewportDescription().IsLegacyViewportType());
+  EXPECT_TRUE(viewport.GetViewportDescription().IsLegacyViewportType());
 
   settings->SetViewportMetaEnabled(false);
-  EXPECT_FALSE(document->GetViewportDescription().IsLegacyViewportType());
+  EXPECT_FALSE(viewport.GetViewportDescription().IsLegacyViewportType());
 }
 
 TEST_F(WebFrameTest,
@@ -2375,13 +2379,14 @@
 
   // The magic number to snap to device-width is 320, so test that 321 is
   // respected.
-  Document* document =
+  ViewportData& viewport =
       ToLocalFrame(web_view_helper.GetWebView()->GetPage()->MainFrame())
-          ->GetDocument();
-  ViewportDescription description = document->GetViewportDescription();
+          ->GetDocument()
+          ->GetViewportData();
+  ViewportDescription description = viewport.GetViewportDescription();
   description.min_width = Length(321, blink::kFixed);
   description.max_width = Length(321, blink::kFixed);
-  document->SetViewportDescription(description);
+  viewport.SetViewportDescription(description);
   web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
   EXPECT_EQ(321, web_view_helper.GetWebView()
                      ->MainFrameImpl()
@@ -2391,7 +2396,7 @@
 
   description.min_width = Length(320, blink::kFixed);
   description.max_width = Length(320, blink::kFixed);
-  document->SetViewportDescription(description);
+  viewport.SetViewportDescription(description);
   web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
   EXPECT_EQ(600, web_view_helper.GetWebView()
                      ->MainFrameImpl()
@@ -2399,9 +2404,9 @@
                      ->GetLayoutSize()
                      .Width());
 
-  description = document->GetViewportDescription();
+  description = viewport.GetViewportDescription();
   description.max_height = Length(1000, blink::kFixed);
-  document->SetViewportDescription(description);
+  viewport.SetViewportDescription(description);
   web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
   EXPECT_EQ(1000, web_view_helper.GetWebView()
                       ->MainFrameImpl()
@@ -2410,7 +2415,7 @@
                       .Height());
 
   description.max_height = Length(320, blink::kFixed);
-  document->SetViewportDescription(description);
+  viewport.SetViewportDescription(description);
   web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
   EXPECT_EQ(800, web_view_helper.GetWebView()
                      ->MainFrameImpl()
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index cda8436d..46f5627 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -39,7 +39,7 @@
 #include "third_party/blink/public/web/web_widget_client.h"
 #include "third_party/blink/renderer/core/dom/ax_object_cache_base.h"
 #include "third_party/blink/renderer/core/dom/context_features.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/events/message_event.h"
 #include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
 #include "third_party/blink/renderer/core/exported/web_settings_impl.h"
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
index 33475af7..0f23452d 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -211,6 +211,7 @@
   security_origin->SetOpaqueOriginIsPotentiallyTrustworthy(
       is_potentially_trustworthy_opaque_origin);
   GetFrame()->GetSecurityContext()->SetReplicatedOrigin(security_origin);
+  ApplyReplicatedFeaturePolicyHeader();
 
   // If the origin of a remote frame changed, the accessibility object for the
   // owner element now points to a different child.
@@ -241,6 +242,11 @@
 
 void WebRemoteFrameImpl::SetReplicatedFeaturePolicyHeader(
     const ParsedFeaturePolicy& parsed_header) {
+  feature_policy_header_ = parsed_header;
+  ApplyReplicatedFeaturePolicyHeader();
+}
+
+void WebRemoteFrameImpl::ApplyReplicatedFeaturePolicyHeader() {
   FeaturePolicy* parent_feature_policy = nullptr;
   if (Parent()) {
     Frame* parent_frame = GetFrame()->Client()->Parent();
@@ -251,7 +257,7 @@
   if (GetFrame()->Owner())
     container_policy = GetFrame()->Owner()->ContainerPolicy();
   GetFrame()->GetSecurityContext()->InitializeFeaturePolicy(
-      parsed_header, container_policy, parent_feature_policy);
+      feature_policy_header_, container_policy, parent_feature_policy);
 }
 
 void WebRemoteFrameImpl::AddReplicatedContentSecurityPolicyHeader(
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
index 48f2ade..fac141d 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
@@ -107,6 +107,7 @@
   WebRemoteFrameImpl(WebTreeScopeType, WebRemoteFrameClient*);
 
   void SetCoreFrame(RemoteFrame*);
+  void ApplyReplicatedFeaturePolicyHeader();
 
   // Inherited from WebFrame, but intentionally hidden: it never makes sense
   // to call these on a WebRemoteFrameImpl.
@@ -120,6 +121,8 @@
   Member<RemoteFrameClientImpl> frame_client_;
   Member<RemoteFrame> frame_;
 
+  ParsedFeaturePolicy feature_policy_header_;
+
   // Oilpan: WebRemoteFrameImpl must remain alive until close() is called.
   // Accomplish that by keeping a self-referential Persistent<>. It is
   // cleared upon close().
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index d873b10..be1a9bde 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -105,6 +105,7 @@
 #include "third_party/blink/renderer/core/frame/rotation_viewport_anchor.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -1551,8 +1552,11 @@
 
   GetPageScaleConstraintsSet().DidChangeInitialContainingBlockSize(icb_size);
 
-  UpdatePageDefinedViewportConstraints(
-      MainFrameImpl()->GetFrame()->GetDocument()->GetViewportDescription());
+  UpdatePageDefinedViewportConstraints(MainFrameImpl()
+                                           ->GetFrame()
+                                           ->GetDocument()
+                                           ->GetViewportData()
+                                           .GetViewportDescription());
   UpdateMainFrameLayoutSize();
 
   GetPage()->GetVisualViewport().SetSize(size_);
@@ -2694,8 +2698,11 @@
     return;
   LocalFrameView* view = GetPage()->DeprecatedLocalMainFrame()->View();
 
-  UpdatePageDefinedViewportConstraints(
-      MainFrameImpl()->GetFrame()->GetDocument()->GetViewportDescription());
+  UpdatePageDefinedViewportConstraints(MainFrameImpl()
+                                           ->GetFrame()
+                                           ->GetDocument()
+                                           ->GetViewportData()
+                                           .GetViewportDescription());
   GetPageScaleConstraintsSet().ComputeFinalConstraints();
 
   int vertical_scrollbar_width = 0;
@@ -2748,7 +2755,8 @@
         matches_heuristics_for_gpu_rasterization_);
   }
 
-  Length default_min_width = document->ViewportDefaultMinWidth();
+  Length default_min_width =
+      document->GetViewportData().ViewportDefaultMinWidth();
   if (default_min_width.IsAuto())
     default_min_width = Length(kExtendToZoom);
 
diff --git a/third_party/blink/renderer/core/frame/BUILD.gn b/third_party/blink/renderer/core/frame/BUILD.gn
index acbef4a6f..9343b9ac 100644
--- a/third_party/blink/renderer/core/frame/BUILD.gn
+++ b/third_party/blink/renderer/core/frame/BUILD.gn
@@ -160,6 +160,8 @@
     "use_counter.h",
     "user_activation.cc",
     "user_activation.h",
+    "viewport_data.cc",
+    "viewport_data.h",
     "visual_viewport.cc",
     "visual_viewport.h",
     "web_feature.h",
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 35f1c0a..d6238113 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -46,8 +46,9 @@
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 #include "third_party/blink/renderer/core/css/style_media.h"
 #include "third_party/blink/renderer/core/dom/computed_accessible_node.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/dom_implementation.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
 #include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
 #include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
@@ -75,6 +76,7 @@
 #include "third_party/blink/renderer/core/frame/screen.h"
 #include "third_party/blink/renderer/core/frame/scroll_to_options.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/html/custom/custom_element_registry.h"
 #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
@@ -315,7 +317,7 @@
     return document_;
 
   GetFrame()->GetScriptController().UpdateDocument();
-  document_->UpdateViewportDescription();
+  document_->GetViewportData().UpdateViewportDescription();
 
   if (GetFrame()->GetPage() && GetFrame()->View()) {
     GetFrame()->GetPage()->GetChromeClient().InstallSupplements(*GetFrame());
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 11508d7..cfe07f6 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -43,6 +43,7 @@
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/child_frame_disconnector.h"
 #include "third_party/blink/renderer/core/dom/computed_accessible_node.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_parser.h"
 #include "third_party/blink/renderer/core/dom/document_type.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
index 096963d..3dc134c 100644
--- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc
+++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -525,6 +525,13 @@
   return LayoutViewport().GetCompositorElementId();
 }
 
+CompositorElementId RootFrameViewport::GetScrollbarElementId(
+    ScrollbarOrientation orientation) {
+  return VisualViewport().VisualViewportSuppliesScrollbars()
+             ? VisualViewport().GetScrollbarElementId(orientation)
+             : LayoutViewport().GetScrollbarElementId(orientation);
+}
+
 PlatformChromeClient* RootFrameViewport::GetChromeClient() const {
   return LayoutViewport().GetChromeClient();
 }
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.h b/third_party/blink/renderer/core/frame/root_frame_viewport.h
index 8b80c27..6dd9770 100644
--- a/third_party/blink/renderer/core/frame/root_frame_viewport.h
+++ b/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -103,6 +103,8 @@
           kIgnorePlatformOverlayScrollbarSize) const override;
   ScrollResult UserScroll(ScrollGranularity, const FloatSize&) override;
   CompositorElementId GetCompositorElementId() const override;
+  CompositorElementId GetScrollbarElementId(
+      ScrollbarOrientation orientation) override;
   bool ScrollAnimatorEnabled() const override;
   PlatformChromeClient* GetChromeClient() const override;
   SmoothScrollSequencer* GetSmoothScrollSequencer() const override;
diff --git a/third_party/blink/renderer/core/frame/viewport_data.cc b/third_party/blink/renderer/core/frame/viewport_data.cc
new file mode 100644
index 0000000..a01b956d
--- /dev/null
+++ b/third_party/blink/renderer/core/frame/viewport_data.cc
@@ -0,0 +1,120 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
+
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame_client.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/page/page.h"
+
+namespace blink {
+
+ViewportData::ViewportData(Document& document) : document_(document) {}
+
+void ViewportData::Trace(Visitor* visitor) {
+  visitor->Trace(document_);
+}
+
+void ViewportData::Shutdown() {
+  // TODO(https://crbug.com/800641): Use InterfaceInvalidator once it works with
+  // associated interfaces.
+  display_cutout_host_.reset();
+}
+
+bool ViewportData::ShouldMergeWithLegacyDescription(
+    ViewportDescription::Type origin) const {
+  return document_->GetSettings() &&
+         document_->GetSettings()->GetViewportMetaMergeContentQuirk() &&
+         legacy_viewport_description_.IsMetaViewportType() &&
+         legacy_viewport_description_.type == origin;
+}
+
+void ViewportData::SetViewportDescription(
+    const ViewportDescription& viewport_description) {
+  if (viewport_description.IsLegacyViewportType()) {
+    if (viewport_description == legacy_viewport_description_)
+      return;
+    legacy_viewport_description_ = viewport_description;
+  } else {
+    if (viewport_description == viewport_description_)
+      return;
+    viewport_description_ = viewport_description;
+
+    // The UA-defined min-width is considered specifically by Android WebView
+    // quirks mode.
+    if (!viewport_description.IsSpecifiedByAuthor())
+      viewport_default_min_width_ = viewport_description.min_width;
+  }
+
+  UpdateViewportDescription();
+}
+
+ViewportDescription ViewportData::GetViewportDescription() const {
+  ViewportDescription applied_viewport_description = viewport_description_;
+  bool viewport_meta_enabled =
+      document_->GetSettings() &&
+      document_->GetSettings()->GetViewportMetaEnabled();
+  if (legacy_viewport_description_.type !=
+          ViewportDescription::kUserAgentStyleSheet &&
+      viewport_meta_enabled)
+    applied_viewport_description = legacy_viewport_description_;
+  if (ShouldOverrideLegacyDescription(viewport_description_.type))
+    applied_viewport_description = viewport_description_;
+
+  return applied_viewport_description;
+}
+
+void ViewportData::UpdateViewportDescription() {
+  if (!document_->GetFrame())
+    return;
+
+  // If the viewport_fit has changed we should send this to the browser. We
+  // use the legacy viewport description which contains the viewport_fit
+  // defined from the layout meta tag.
+  mojom::ViewportFit current_viewport_fit =
+      GetViewportDescription().GetViewportFit();
+
+  // If we are forcing to expand into the display cutout then we should override
+  // the viewport fit value.
+  if (force_expand_display_cutout_)
+    current_viewport_fit = mojom::ViewportFit::kCover;
+
+  if (viewport_fit_ != current_viewport_fit) {
+    if (AssociatedInterfaceProvider* provider =
+            document_->GetFrame()
+                ->Client()
+                ->GetRemoteNavigationAssociatedInterfaces()) {
+      // Bind the mojo interface.
+      if (!display_cutout_host_.is_bound()) {
+        provider->GetInterface(&display_cutout_host_);
+        DCHECK(display_cutout_host_.is_bound());
+      }
+
+      // Even though we bind the mojo interface above there still may be cases
+      // where this will fail (e.g. unit tests).
+      display_cutout_host_->NotifyViewportFitChanged(current_viewport_fit);
+    }
+
+    viewport_fit_ = current_viewport_fit;
+  }
+
+  if (document_->GetFrame()->IsMainFrame()) {
+    document_->GetPage()->GetChromeClient().DispatchViewportPropertiesDidChange(
+        GetViewportDescription());
+  }
+}
+
+void ViewportData::SetExpandIntoDisplayCutout(bool expand) {
+  if (force_expand_display_cutout_ == expand)
+    return;
+
+  force_expand_display_cutout_ = expand;
+  UpdateViewportDescription();
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/viewport_data.h b/third_party/blink/renderer/core/frame/viewport_data.h
new file mode 100644
index 0000000..e3f539089
--- /dev/null
+++ b/third_party/blink/renderer/core/frame/viewport_data.h
@@ -0,0 +1,61 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIEWPORT_DATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIEWPORT_DATA_H_
+
+#include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/page/viewport_description.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class Document;
+
+class ViewportData : public GarbageCollectedFinalized<ViewportData> {
+ public:
+  ViewportData(Document& document);
+  void Trace(Visitor* visitor);
+  void Shutdown();
+
+  bool ShouldMergeWithLegacyDescription(ViewportDescription::Type) const;
+  bool ShouldOverrideLegacyDescription(ViewportDescription::Type) const;
+  CORE_EXPORT void SetViewportDescription(const ViewportDescription&);
+  CORE_EXPORT ViewportDescription GetViewportDescription() const;
+  Length ViewportDefaultMinWidth() const { return viewport_default_min_width_; }
+
+  void UpdateViewportDescription();
+
+  // When true this will force a kCover viewport fit value which will result in
+  // the document expanding into the display cutout area.
+  CORE_EXPORT void SetExpandIntoDisplayCutout(bool expand);
+  mojom::ViewportFit GetCurrentViewportFitForTests() const {
+    return viewport_fit_;
+  }
+
+ private:
+  Member<Document> document_;
+
+  ViewportDescription viewport_description_;
+  ViewportDescription legacy_viewport_description_;
+  Length viewport_default_min_width_;
+
+  // Stores the current value viewport-fit value.
+  mojom::ViewportFit viewport_fit_ = blink::mojom::ViewportFit::kAuto;
+  bool force_expand_display_cutout_ = false;
+
+  mojom::blink::DisplayCutoutHostAssociatedPtr display_cutout_host_;
+};
+
+inline bool ViewportData::ShouldOverrideLegacyDescription(
+    ViewportDescription::Type origin) const {
+  // The different (legacy) meta tags have different priorities based on the
+  // type regardless of which order they appear in the DOM. The priority is
+  // given by the ViewportDescription::Type enum.
+  return origin >= legacy_viewport_description_.type;
+}
+
+}  // namespace blink
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_VIEWPORT_DATA_H_
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc
index 23888327..ef85c8c8 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -572,8 +572,10 @@
   if (!scrollbar_layer_group) {
     ScrollingCoordinator* coordinator = GetPage().GetScrollingCoordinator();
     DCHECK(coordinator);
+
     scrollbar_layer_group = coordinator->CreateSolidColorScrollbarLayer(
-        orientation, thumb_thickness, scrollbar_margin, false);
+        orientation, thumb_thickness, scrollbar_margin, false,
+        GetScrollbarElementId(orientation));
 
     // The compositor will control the scrollbar's visibility. Set to invisible
     // by default so scrollbars don't show up in layout tests.
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.h b/third_party/blink/renderer/core/frame/visual_viewport.h
index 09c8a3eb..77fdb9a3 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport.h
+++ b/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -250,6 +250,7 @@
   bool ShouldDisableDesktopWorkarounds() const;
 
   ScrollbarTheme& GetPageScrollbarTheme() const override;
+  bool VisualViewportSuppliesScrollbars() const override;
 
   TransformPaintPropertyNode* GetPageScaleNode() const;
   TransformPaintPropertyNode* GetScrollTranslationNode() const;
@@ -268,7 +269,6 @@
 
   bool DidSetScaleOrLocation(float scale, const FloatPoint& location);
 
-  bool VisualViewportSuppliesScrollbars() const;
 
   void UpdateStyleAndLayoutIgnorePendingStylesheets() const;
 
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc b/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc
index 02b98e6..b3654203 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc
@@ -437,9 +437,7 @@
   RuntimeEnabledFeatures::SetConstructableStylesheetsEnabled(true);
   NonThrowableExceptionState should_not_throw;
   ElementDefinitionOptions options;
-  CSSStyleSheet* sheet =
-      CSSStyleSheet::Create(GetDocument(), ":host { color: red; }",
-                            CSSStyleSheetInit(), should_not_throw);
+  CSSStyleSheet* sheet = CSSStyleSheet::Create(GetDocument(), should_not_throw);
   options.setStyle(sheet);
   TestCustomElementDefinitionBuilder builder(sheet);
   CustomElementDefinition* definition_a =
diff --git a/third_party/blink/renderer/core/html/forms/html_field_set_element.cc b/third_party/blink/renderer/core/html/forms/html_field_set_element.cc
index 67d3c3d..e365835 100644
--- a/third_party/blink/renderer/core/html/forms/html_field_set_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_field_set_element.cc
@@ -25,7 +25,7 @@
 #include "third_party/blink/renderer/core/html/forms/html_field_set_element.h"
 
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
 #include "third_party/blink/renderer/core/html/forms/html_legend_element.h"
 #include "third_party/blink/renderer/core/html/html_collection.h"
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
index d66b208..ae4f309 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -27,8 +27,8 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/core/dom/ax_object_cache.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/html/forms/html_data_list_element.h"
 #include "third_party/blink/renderer/core/html/forms/html_field_set_element.h"
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element_test.cc b/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
index 8b2b775..cf430c80 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
@@ -8,6 +8,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/position.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
index a611bbcd..430db9f5 100644
--- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -32,7 +32,7 @@
 #include "third_party/blink/renderer/core/html/forms/text_field_input_type.h"
 
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/events/before_text_inserted_event.h"
diff --git a/third_party/blink/renderer/core/html/html_document.cc b/third_party/blink/renderer/core/html/html_document.cc
index 028badd9..ab5c2a6 100644
--- a/third_party/blink/renderer/core/html/html_document.cc
+++ b/third_party/blink/renderer/core/html/html_document.cc
@@ -55,6 +55,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/html_names.h"
 
@@ -72,6 +73,14 @@
   }
 }
 
+HTMLDocument* HTMLDocument::Create(const DocumentInit& initializer) {
+  return new HTMLDocument(initializer);
+}
+
+HTMLDocument* HTMLDocument::CreateForTest() {
+  return new HTMLDocument(DocumentInit::Create());
+}
+
 HTMLDocument::~HTMLDocument() = default;
 
 Document* HTMLDocument::CloneDocumentWithoutChildren() const {
diff --git a/third_party/blink/renderer/core/html/html_document.h b/third_party/blink/renderer/core/html/html_document.h
index 641233a3..5db2931 100644
--- a/third_party/blink/renderer/core/html/html_document.h
+++ b/third_party/blink/renderer/core/html/html_document.h
@@ -33,12 +33,8 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static HTMLDocument* Create(const DocumentInit& initializer) {
-    return new HTMLDocument(initializer);
-  }
-  static HTMLDocument* CreateForTest() {
-    return new HTMLDocument(DocumentInit::Create());
-  }
+  static HTMLDocument* Create(const DocumentInit& initializer);
+  static HTMLDocument* CreateForTest();
   ~HTMLDocument() override;
 
   void AddNamedItem(const AtomicString& name);
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc
index 0011eeb..2553e8d 100644
--- a/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -30,7 +30,7 @@
 #include "third_party/blink/renderer/core/css_property_names.h"
 #include "third_party/blink/renderer/core/dom/attribute.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
diff --git a/third_party/blink/renderer/core/html/html_meta_element.cc b/third_party/blink/renderer/core/html/html_meta_element.cc
index 4edfdc5..dbd3151 100644
--- a/third_party/blink/renderer/core/html/html_meta_element.cc
+++ b/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -27,6 +27,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/html/html_head_element.h"
 #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
 #include "third_party/blink/renderer/core/html_names.h"
@@ -457,19 +458,20 @@
     ViewportDescription::Type origin) {
   DCHECK(!content.IsNull());
 
-  if (!GetDocument().ShouldOverrideLegacyDescription(origin))
+  ViewportData& viewport_data = GetDocument().GetViewportData();
+  if (!viewport_data.ShouldOverrideLegacyDescription(origin))
     return;
 
   ViewportDescription description_from_legacy_tag(origin);
-  if (GetDocument().ShouldMergeWithLegacyDescription(origin))
-    description_from_legacy_tag = GetDocument().GetViewportDescription();
+  if (viewport_data.ShouldMergeWithLegacyDescription(origin))
+    description_from_legacy_tag = viewport_data.GetViewportDescription();
 
   GetViewportDescriptionFromContentAttribute(
       content, description_from_legacy_tag, &GetDocument(),
       GetDocument().GetSettings() &&
           GetDocument().GetSettings()->GetViewportMetaZeroValuesQuirk());
 
-  GetDocument().SetViewportDescription(description_from_legacy_tag);
+  viewport_data.SetViewportDescription(description_from_legacy_tag);
 }
 
 void HTMLMetaElement::ParseAttribute(
diff --git a/third_party/blink/renderer/core/html/html_meta_element_test.cc b/third_party/blink/renderer/core/html/html_meta_element_test.cc
index 63cbd885..6bae8ac 100644
--- a/third_party/blink/renderer/core/html/html_meta_element_test.cc
+++ b/third_party/blink/renderer/core/html/html_meta_element_test.cc
@@ -7,6 +7,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 
@@ -23,7 +24,10 @@
 
   mojom::ViewportFit LoadTestPageAndReturnViewportFit(const String& value) {
     LoadTestPageWithViewportFitValue(value);
-    return GetDocument().GetViewportDescription().GetViewportFit();
+    return GetDocument()
+        .GetViewportData()
+        .GetViewportDescription()
+        .GetViewportFit();
   }
 
  private:
diff --git a/third_party/blink/renderer/core/html/image_document_test.cc b/third_party/blink/renderer/core/html/image_document_test.cc
index f5b475e7..97a78a6a 100644
--- a/third_party/blink/renderer/core/html/image_document_test.cc
+++ b/third_party/blink/renderer/core/html/image_document_test.cc
@@ -7,6 +7,7 @@
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_parser.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
diff --git a/third_party/blink/renderer/core/html/imports/html_import_loader.cc b/third_party/blink/renderer/core/html/imports/html_import_loader.cc
index 6a211bea..3d83cdf 100644
--- a/third_party/blink/renderer/core/html/imports/html_import_loader.cc
+++ b/third_party/blink/renderer/core/html/imports/html_import_loader.cc
@@ -33,6 +33,7 @@
 #include <memory>
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_parser.h"
 #include "third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h"
 #include "third_party/blink/renderer/core/html/html_document.h"
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
index d9b7c61c..3feabddb 100644
--- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
+++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/html/cross_origin_attribute.h"
 #include "third_party/blink/renderer/core/html/html_image_element.h"
 #include "third_party/blink/renderer/core/html/html_meta_element.h"
@@ -936,7 +937,8 @@
   do_html_preload_scanning =
       !document->GetSettings() ||
       document->GetSettings()->GetDoHtmlPreloadScanning();
-  default_viewport_min_width = document->ViewportDefaultMinWidth();
+  default_viewport_min_width =
+      document->GetViewportData().ViewportDefaultMinWidth();
   viewport_meta_zero_values_quirk =
       document->GetSettings() &&
       document->GetSettings()->GetViewportMetaZeroValuesQuirk();
diff --git a/third_party/blink/renderer/core/inspector/dom_patch_support.cc b/third_party/blink/renderer/core/inspector/dom_patch_support.cc
index d477c6d..7806f4d 100644
--- a/third_party/blink/renderer/core/inspector/dom_patch_support.cc
+++ b/third_party/blink/renderer/core/inspector/dom_patch_support.cc
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/core/dom/context_features.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 #include "third_party/blink/renderer/core/dom/xml_document.h"
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc
index dac6399..46c2078 100644
--- a/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -353,7 +353,7 @@
                               const HitTestLocation& location_in_container,
                               const LayoutPoint& accumulated_offset,
                               HitTestAction hit_test_action) {
-  HitTestResult temp_result(result.GetHitTestRequest(), location_in_container);
+  HitTestResult temp_result(result);
   bool inside = LayoutReplaced::NodeAtPoint(
       temp_result, location_in_container, accumulated_offset, hit_test_action);
 
diff --git a/third_party/blink/renderer/core/layout/layout_image_test.cc b/third_party/blink/renderer/core/layout/layout_image_test.cc
new file mode 100644
index 0000000..3258c1e
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/layout_image_test.cc
@@ -0,0 +1,31 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/layout/layout_geometry_map.h"
+#include "third_party/blink/renderer/core/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+
+namespace blink {
+
+using LayoutImageTest = RenderingTest;
+
+TEST_F(LayoutImageTest, HitTestUnderTransform) {
+  SetBodyInnerHTML(R"HTML(
+    <div style='transform: translateX(50px)'>
+      <img id=target style='width: 20px; height: 20px'/>
+    </div>
+  )HTML");
+
+  const auto& target = *GetDocument().getElementById("target");
+  HitTestLocation location(LayoutPoint(60, 10));
+  HitTestResult result(
+      HitTestRequest(HitTestRequest::kReadOnly | HitTestRequest::kActive |
+                     HitTestRequest::kAllowChildFrameContent),
+      location);
+  GetLayoutView().HitTest(location, result);
+  EXPECT_EQ(LayoutPoint(60, 10), result.PointInInnerNodeFrame());
+  EXPECT_EQ(target, result.InnerNode());
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
index 74de0db..7449871 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -215,7 +215,7 @@
 void NGLineBreaker::BreakLine(NGLineInfo* line_info) {
   NGInlineItemResults* item_results = &line_info->Results();
   const Vector<NGInlineItem>& items = line_info->ItemsData().items;
-  LineBreakState state = LineBreakState::kContinue;
+  LineBreakState state = LineBreakState::kLeading;
   while (state != LineBreakState::kDone) {
     // Check overflow even if |item_index_| is at the end of the block, because
     // the last item of the block may have caused overflow. In that case,
@@ -265,6 +265,8 @@
 
     if (item.Type() == NGInlineItem::kAtomicInline) {
       HandleAtomicInline(item, line_info);
+      if (state == LineBreakState::kLeading)
+        state = LineBreakState::kContinue;
     } else if (item.Type() == NGInlineItem::kOpenTag) {
       HandleOpenTag(item, AddItem(item, item_results));
     } else if (item.Type() == NGInlineItem::kFloating) {
@@ -325,6 +327,24 @@
     return HandleTrailingSpaces(item, line_info);
   }
 
+  // Skip leading collapsible spaces.
+  // Most cases such spaces are handled as trailing spaces of the previous line,
+  // but there are some cases doing so is too complex.
+  if (state == LineBreakState::kLeading) {
+    if (item.Style()->CollapseWhiteSpace() &&
+        Text()[offset_] == kSpaceCharacter) {
+      // Skipping one whitespace removes all collapsible spaces because
+      // collapsible spaces are collapsed to single space in
+      // NGInlineItemBuilder.
+      ++offset_;
+      if (offset_ == item.EndOffset()) {
+        MoveToNextOf(item);
+        return LineBreakState::kContinue;
+      }
+    }
+    state = LineBreakState::kContinue;
+  }
+
   line_.should_create_line_box = true;
   NGInlineItemResult* item_result = AddItem(item, item_results);
   LayoutUnit available_width = line_.AvailableWidthToFit();
@@ -1036,7 +1056,7 @@
     override_break_anywhere_ = true;
     break_iterator_.SetBreakType(LineBreakType::kBreakCharacter);
     Rewind(line_info, 0);
-    return LineBreakState::kContinue;
+    return LineBreakState::kLeading;
   }
 
   // Let this line overflow.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
index b5eee977..d30ba5b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -136,7 +136,10 @@
     // when it is overflowing.
     kTrailing,
 
-    // The initial state. Looking for items to break the line.
+    // The initial state, until the first character is found.
+    kLeading,
+
+    // Looking for more items to fit into the current line.
     kContinue,
   };
 
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.cc b/third_party/blink/renderer/core/layout/text_autosizer.cc
index e212d492..e819f7b4 100644
--- a/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
 #include "third_party/blink/renderer/core/layout/layout_block.h"
@@ -602,7 +603,8 @@
     // If the page has a meta viewport or @viewport, don't apply the device
     // scale adjustment.
     if (!main_frame.GetDocument()
-             ->GetViewportDescription()
+             ->GetViewportData()
+             .GetViewportDescription()
              .IsSpecifiedByAuthor()) {
       page_info_.device_scale_adjustment_ =
           document_->GetSettings()->GetDeviceScaleAdjustment();
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index c5d64e06..9382563 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -36,6 +36,7 @@
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/public/web/web_history_commit_type.h"
 #include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_parser.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/dom/scriptable_document_parser.h"
diff --git a/third_party/blink/renderer/core/loader/resource/document_resource.cc b/third_party/blink/renderer/core/loader/resource/document_resource.cc
index b10e13e7..8ca4629e 100644
--- a/third_party/blink/renderer/core/loader/resource/document_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/document_resource.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/core/loader/resource/document_resource.h"
 
 #include "services/network/public/mojom/request_context_frame_type.mojom-blink.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/xml_document.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 46c75bff..6bac0cb 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/frame/remote_frame.h"
 #include "third_party/blink/renderer/core/frame/remote_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
 #include "third_party/blink/renderer/core/geometry/dom_rect_list.h"
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
@@ -202,7 +203,8 @@
                  DeprecatedLocalMainFrame()->GetDocument()
              ? DeprecatedLocalMainFrame()
                    ->GetDocument()
-                   ->GetViewportDescription()
+                   ->GetViewportData()
+                   .GetViewportDescription()
              : ViewportDescription();
 }
 
@@ -544,7 +546,10 @@
       break;
     case SettingsDelegate::kViewportDescriptionChange:
       if (MainFrame() && MainFrame()->IsLocalFrame()) {
-        DeprecatedLocalMainFrame()->GetDocument()->UpdateViewportDescription();
+        DeprecatedLocalMainFrame()
+            ->GetDocument()
+            ->GetViewportData()
+            .UpdateViewportDescription();
         // The text autosizer has dependencies on the viewport.
         if (TextAutosizer* text_autosizer =
                 DeprecatedLocalMainFrame()->GetDocument()->GetTextAutosizer())
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index f7902415..90aaf9c 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -365,15 +365,13 @@
   if (theme.UsesOverlayScrollbars() && theme.UsesNinePatchThumbResource()) {
     auto scrollbar_layer = cc::PaintedOverlayScrollbarLayer::Create(
         std::move(scrollbar_delegate), /*scroll_element_id=*/cc::ElementId());
-    scrollbar_layer->SetElementId(
-        CompositorElementIdFromUniqueObjectId(NewUniqueObjectId()));
+    scrollbar_layer->SetElementId(scrollbar.GetElementId());
     layer_group->scrollbar_layer = scrollbar_layer.get();
     layer_group->layer = std::move(scrollbar_layer);
   } else {
     auto scrollbar_layer = cc::PaintedScrollbarLayer::Create(
         std::move(scrollbar_delegate), /*scroll_element_id=*/cc::ElementId());
-    scrollbar_layer->SetElementId(
-        CompositorElementIdFromUniqueObjectId(NewUniqueObjectId()));
+    scrollbar_layer->SetElementId(scrollbar.GetElementId());
     layer_group->scrollbar_layer = scrollbar_layer.get();
     layer_group->layer = std::move(scrollbar_layer);
   }
@@ -388,14 +386,14 @@
     ScrollbarOrientation orientation,
     int thumb_thickness,
     int track_start,
-    bool is_left_side_vertical_scrollbar) {
+    bool is_left_side_vertical_scrollbar,
+    cc::ElementId element_id) {
   cc::ScrollbarOrientation cc_orientation =
       orientation == kHorizontalScrollbar ? cc::HORIZONTAL : cc::VERTICAL;
   auto scrollbar_layer = cc::SolidColorScrollbarLayer::Create(
       cc_orientation, thumb_thickness, track_start,
       is_left_side_vertical_scrollbar, cc::ElementId());
-  scrollbar_layer->SetElementId(
-      CompositorElementIdFromUniqueObjectId(NewUniqueObjectId()));
+  scrollbar_layer->SetElementId(element_id);
 
   auto layer_group = std::make_unique<ScrollbarLayerGroup>();
   layer_group->scrollbar_layer = scrollbar_layer.get();
@@ -486,7 +484,8 @@
         group = CreateSolidColorScrollbarLayer(
             orientation, scrollbar.GetTheme().ThumbThickness(scrollbar),
             scrollbar.GetTheme().TrackPosition(scrollbar),
-            scrollable_area->ShouldPlaceVerticalScrollbarOnLeft());
+            scrollable_area->ShouldPlaceVerticalScrollbarOnLeft(),
+            scrollable_area->GetScrollbarElementId(orientation));
       } else {
         group = CreateScrollbarLayer(scrollbar,
                                      page_->DeviceScaleFactorDeprecated());
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
index e60573c..68c9153 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
@@ -123,7 +123,8 @@
       ScrollbarOrientation,
       int thumb_thickness,
       int track_start,
-      bool is_left_side_vertical_scrollbar);
+      bool is_left_side_vertical_scrollbar,
+      cc::ElementId);
 
   void WillDestroyScrollableArea(ScrollableArea*);
 
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
index d27606af..3d1acd5 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
@@ -9,6 +9,14 @@
 #include "third_party/blink/renderer/core/paint/fragment_data.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 
+namespace {
+enum class ScrollbarOrCorner {
+  kHorizontalScrollbar,
+  kVerticalScrollbar,
+  kScrollbarCorner,
+};
+}
+
 namespace blink {
 
 void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
@@ -68,38 +76,48 @@
   SetContainerLayerState(mapping->DecorationOutlineLayer());
   SetContainerLayerState(mapping->ChildClippingMaskLayer());
 
-  base::Optional<PropertyTreeState> scrollbar_layer_state;
-
   auto SetContainerLayerStateForScrollbars =
-      [&fragment_data, &snapped_paint_offset, &container_layer_state,
-       &scrollbar_layer_state](GraphicsLayer* graphics_layer) {
-        if (graphics_layer) {
-          if (!scrollbar_layer_state) {
-            // OverflowControlsClip should be applied within the scrollbar
-            // layers.
-            if (container_layer_state) {
-              scrollbar_layer_state = container_layer_state;
-            } else {
-              scrollbar_layer_state = fragment_data.LocalBorderBoxProperties();
-            }
+      [&fragment_data, &snapped_paint_offset, &container_layer_state](
+          GraphicsLayer* graphics_layer,
+          ScrollbarOrCorner scrollbar_or_corner) {
+        if (!graphics_layer)
+          return;
+        PropertyTreeState scrollbar_layer_state =
+            container_layer_state.value_or(
+                fragment_data.LocalBorderBoxProperties());
+        // OverflowControlsClip should be applied within the scrollbar
+        // layers.
+        if (const auto* properties = fragment_data.PaintProperties()) {
+          if (const auto* clip = properties->OverflowControlsClip()) {
+            scrollbar_layer_state.SetClip(clip);
+          } else if (const auto* css_clip = properties->CssClip()) {
+            scrollbar_layer_state.SetClip(css_clip->Parent());
+          }
+        }
 
-            if (const auto* properties = fragment_data.PaintProperties()) {
-              if (const auto* clip = properties->OverflowControlsClip()) {
-                scrollbar_layer_state->SetClip(clip);
-              } else if (const auto* css_clip = properties->CssClip()) {
-                scrollbar_layer_state->SetClip(css_clip->Parent());
-              }
+        if (const auto* properties = fragment_data.PaintProperties()) {
+          if (scrollbar_or_corner == ScrollbarOrCorner::kHorizontalScrollbar) {
+            if (const auto* effect = properties->HorizontalScrollbarEffect()) {
+              scrollbar_layer_state.SetEffect(effect);
             }
           }
-          graphics_layer->SetLayerState(
-              *scrollbar_layer_state,
-              snapped_paint_offset + graphics_layer->OffsetFromLayoutObject());
+
+          if (scrollbar_or_corner == ScrollbarOrCorner::kVerticalScrollbar) {
+            if (const auto* effect = properties->VerticalScrollbarEffect())
+              scrollbar_layer_state.SetEffect(effect);
+          }
         }
+        graphics_layer->SetLayerState(
+            scrollbar_layer_state,
+            snapped_paint_offset + graphics_layer->OffsetFromLayoutObject());
       };
 
-  SetContainerLayerStateForScrollbars(mapping->LayerForHorizontalScrollbar());
-  SetContainerLayerStateForScrollbars(mapping->LayerForVerticalScrollbar());
-  SetContainerLayerStateForScrollbars(mapping->LayerForScrollCorner());
+  SetContainerLayerStateForScrollbars(mapping->LayerForHorizontalScrollbar(),
+                                      ScrollbarOrCorner::kHorizontalScrollbar);
+  SetContainerLayerStateForScrollbars(mapping->LayerForVerticalScrollbar(),
+                                      ScrollbarOrCorner::kVerticalScrollbar);
+  SetContainerLayerStateForScrollbars(mapping->LayerForScrollCorner(),
+                                      ScrollbarOrCorner::kScrollbarCorner);
 
   if (mapping->ScrollingContentsLayer()) {
     auto paint_offset = snapped_paint_offset;
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
index a00370c9..61ef996 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
@@ -2,12 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
+
+#include "cc/layers/picture_layer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
-#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
+#include "third_party/blink/renderer/platform/testing/use_mock_scrollbar_settings.h"
 
 namespace blink {
 
@@ -41,4 +45,68 @@
             mask_layer->layer_state_->state.Clip());
 }
 
+TEST_F(CompositingLayerPropertyUpdaterTest,
+       EnsureOverlayScrollbarLayerHasEffectNode) {
+  GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
+      true);
+  UseMockScrollbarSettings mock_scrollbar(false, true);
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      #scroller {
+        width: 100px;
+        height: 100px;
+        overflow: scroll;
+      }
+      #big {
+        width: 200px;
+        height: 200px;
+      }
+    </style>
+    <div id='scroller'>
+      <div id='big'></div>
+    </div>
+  )HTML");
+
+  ASSERT_TRUE(
+      GetDocument().GetPage()->GetScrollbarTheme().UsesOverlayScrollbars());
+
+  PaintLayer* scroller_layer =
+      ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"))->Layer();
+  PaintLayerScrollableArea* scrollable_area =
+      scroller_layer->GetScrollableArea();
+  ASSERT_TRUE(scrollable_area);
+
+  auto* horizontal_scrollbar_layer =
+      scrollable_area->LayerForHorizontalScrollbar();
+  auto* vertical_scrollbar_layer = scrollable_area->LayerForVerticalScrollbar();
+  ASSERT_TRUE(horizontal_scrollbar_layer);
+  ASSERT_TRUE(vertical_scrollbar_layer);
+
+  auto* paint_properties =
+      scroller_layer->GetLayoutObject().FirstFragment().PaintProperties();
+
+  // Ensure each overlay scrollbar has its own effect node and effect node has
+  // correct element_id.
+  EXPECT_EQ(paint_properties->HorizontalScrollbarEffect(),
+            horizontal_scrollbar_layer->GetPropertyTreeState().Effect());
+  EXPECT_EQ(paint_properties->VerticalScrollbarEffect(),
+            vertical_scrollbar_layer->GetPropertyTreeState().Effect());
+  EXPECT_NE(horizontal_scrollbar_layer->GetPropertyTreeState().Effect(),
+            vertical_scrollbar_layer->GetPropertyTreeState().Effect());
+  EXPECT_NE(horizontal_scrollbar_layer->GetPropertyTreeState()
+                .Effect()
+                ->GetCompositorElementId(),
+            vertical_scrollbar_layer->GetPropertyTreeState()
+                .Effect()
+                ->GetCompositorElementId());
+  EXPECT_EQ(horizontal_scrollbar_layer->GetPropertyTreeState()
+                .Effect()
+                ->GetCompositorElementId(),
+            horizontal_scrollbar_layer->ContentsLayer()->element_id());
+  EXPECT_EQ(vertical_scrollbar_layer->GetPropertyTreeState()
+                .Effect()
+                ->GetCompositorElementId(),
+            vertical_scrollbar_layer->ContentsLayer()->element_id());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/find_properties_needing_update.h b/third_party/blink/renderer/core/paint/find_properties_needing_update.h
index 2caa889..f27d8d9 100644
--- a/third_party/blink/renderer/core/paint/find_properties_needing_update.h
+++ b/third_party/blink/renderer/core/paint/find_properties_needing_update.h
@@ -107,6 +107,12 @@
                                 object_properties->Effect());
       DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Filter(),
                                 object_properties->Filter());
+      DCHECK_OBJECT_PROPERTY_EQ(object_,
+                                original_properties_->VerticalScrollbarEffect(),
+                                object_properties->VerticalScrollbarEffect());
+      DCHECK_OBJECT_PROPERTY_EQ(
+          object_, original_properties_->HorizontalScrollbarEffect(),
+          object_properties->HorizontalScrollbarEffect());
       DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Mask(),
                                 object_properties->Mask());
       DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->ClipPath(),
diff --git a/third_party/blink/renderer/core/paint/object_paint_properties.h b/third_party/blink/renderer/core/paint/object_paint_properties.h
index 2e15a08f..736b174 100644
--- a/third_party/blink/renderer/core/paint/object_paint_properties.h
+++ b/third_party/blink/renderer/core/paint/object_paint_properties.h
@@ -81,6 +81,9 @@
   // |   backdrop-dependent children are present.
   // +-[ filter ]
   // |     Isolated group for CSS filter.
+  // +-[ vertical/horizontal scrollbar effect ]
+  // |     Overlay Scrollbars on Aura and Android need effect node for fade
+  // |     animation.
   // +-[ mask ]
   // |     Isolated group for painting the CSS mask. This node will have
   // |     SkBlendMode::kDstIn and shall paint last, i.e. after masked contents.
@@ -90,6 +93,12 @@
   //       contents.
   const EffectPaintPropertyNode* Effect() const { return effect_.get(); }
   const EffectPaintPropertyNode* Filter() const { return filter_.get(); }
+  const EffectPaintPropertyNode* VerticalScrollbarEffect() const {
+    return vertical_scrollbar_effect_.get();
+  }
+  const EffectPaintPropertyNode* HorizontalScrollbarEffect() const {
+    return horizontal_scrollbar_effect_.get();
+  }
   const EffectPaintPropertyNode* Mask() const { return mask_.get(); }
   const EffectPaintPropertyNode* ClipPath() const { return clip_path_.get(); }
 
@@ -157,6 +166,12 @@
   bool ClearTransform() { return Clear(transform_); }
   bool ClearEffect() { return Clear(effect_); }
   bool ClearFilter() { return Clear(filter_); }
+  bool ClearVerticalScrollbarEffect() {
+    return Clear(vertical_scrollbar_effect_);
+  }
+  bool ClearHorizontalScrollbarEffect() {
+    return Clear(horizontal_scrollbar_effect_);
+  }
   bool ClearMask() { return Clear(mask_); }
   bool ClearClipPath() { return Clear(clip_path_); }
   bool ClearFragmentClip() { return Clear(fragment_clip_); }
@@ -227,6 +242,16 @@
                             EffectPaintPropertyNode::State&& state) {
     return Update(filter_, parent, std::move(state));
   }
+  UpdateResult UpdateVerticalScrollbarEffect(
+      const EffectPaintPropertyNode& parent,
+      EffectPaintPropertyNode::State&& state) {
+    return Update(vertical_scrollbar_effect_, parent, std::move(state));
+  }
+  UpdateResult UpdateHorizontalScrollbarEffect(
+      const EffectPaintPropertyNode& parent,
+      EffectPaintPropertyNode::State&& state) {
+    return Update(horizontal_scrollbar_effect_, parent, std::move(state));
+  }
   UpdateResult UpdateMask(const EffectPaintPropertyNode& parent,
                           EffectPaintPropertyNode::State&& state) {
     return Update(mask_, parent, std::move(state));
@@ -283,6 +308,12 @@
       cloned->effect_ = effect_->Clone();
     if (filter_)
       cloned->filter_ = filter_->Clone();
+    if (vertical_scrollbar_effect_)
+      cloned->vertical_scrollbar_effect_ = vertical_scrollbar_effect_->Clone();
+    if (horizontal_scrollbar_effect_) {
+      cloned->horizontal_scrollbar_effect_ =
+          horizontal_scrollbar_effect_->Clone();
+    }
     if (mask_)
       cloned->mask_ = mask_->Clone();
     if (clip_path_)
@@ -354,6 +385,8 @@
   scoped_refptr<TransformPaintPropertyNode> transform_;
   scoped_refptr<EffectPaintPropertyNode> effect_;
   scoped_refptr<EffectPaintPropertyNode> filter_;
+  scoped_refptr<EffectPaintPropertyNode> vertical_scrollbar_effect_;
+  scoped_refptr<EffectPaintPropertyNode> horizontal_scrollbar_effect_;
   scoped_refptr<EffectPaintPropertyNode> mask_;
   scoped_refptr<EffectPaintPropertyNode> clip_path_;
   scoped_refptr<ClipPaintPropertyNode> fragment_clip_;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
index 2514625..01312e5 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -549,6 +549,8 @@
   void DidScrollWithScrollbar(ScrollbarPart, ScrollbarOrientation) override;
   CompositorElementId GetCompositorElementId() const override;
 
+  bool VisualViewportSuppliesScrollbars() const override;
+
   void Trace(blink::Visitor*) override;
 
  private:
@@ -556,7 +558,6 @@
 
   bool HasHorizontalOverflow() const;
   bool HasVerticalOverflow() const;
-  bool VisualViewportSuppliesScrollbars() const;
 
   bool NeedsScrollbarReconstruction() const;
 
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 296f1f42..b1a44f0 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1239,8 +1239,38 @@
 
       OnUpdate(properties_->UpdateScroll(*context_.current.scroll,
                                          std::move(state)));
+
+      if (scrollable_area->VerticalScrollbar() ||
+          scrollable_area->HasLayerForVerticalScrollbar()) {
+        EffectPaintPropertyNode::State state;
+        state.local_transform_space = context_.current.transform;
+        state.direct_compositing_reasons =
+            CompositingReason::kActiveOpacityAnimation;
+        state.compositor_element_id = scrollable_area->GetScrollbarElementId(
+            ScrollbarOrientation::kVerticalScrollbar);
+        OnUpdate(properties_->UpdateVerticalScrollbarEffect(
+            *context_.current_effect, std::move(state)));
+      } else {
+        OnClear(properties_->ClearVerticalScrollbarEffect());
+      }
+
+      if (scrollable_area->HorizontalScrollbar() ||
+          scrollable_area->HasLayerForHorizontalScrollbar()) {
+        EffectPaintPropertyNode::State state;
+        state.local_transform_space = context_.current.transform;
+        state.direct_compositing_reasons =
+            CompositingReason::kActiveOpacityAnimation;
+        state.compositor_element_id = scrollable_area->GetScrollbarElementId(
+            ScrollbarOrientation::kHorizontalScrollbar);
+        OnUpdate(properties_->UpdateHorizontalScrollbarEffect(
+            *context_.current_effect, std::move(state)));
+      } else {
+        OnClear(properties_->ClearHorizontalScrollbarEffect());
+      }
     } else {
       OnClear(properties_->ClearScroll());
+      OnClear(properties_->ClearVerticalScrollbarEffect());
+      OnClear(properties_->ClearHorizontalScrollbarEffect());
     }
 
     // A scroll translation node is created for static offset (e.g., overflow
diff --git a/third_party/blink/renderer/core/probe/CoreProbes.json5 b/third_party/blink/renderer/core/probe/CoreProbes.json5
index aa6f43e..455befa6 100644
--- a/third_party/blink/renderer/core/probe/CoreProbes.json5
+++ b/third_party/blink/renderer/core/probe/CoreProbes.json5
@@ -6,6 +6,7 @@
     includes: [
       "third_party/blink/renderer/core/CoreProbeSink.h",
       "third_party/blink/renderer/core/animation/animation.h",
+      "third_party/blink/renderer/core/dom/character_data.h",
       "third_party/blink/renderer/core/dom/pseudo_element.h",
       "third_party/blink/renderer/core/html/html_slot_element.h",
       "third_party/blink/renderer/core/page/chrome_client.h",
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index fb0c7eb..65967f6 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -31,7 +31,7 @@
 #include "third_party/blink/renderer/core/animation/document_animations.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/dom/document_parser.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
diff --git a/third_party/blink/renderer/core/timing/window_performance_test.cc b/third_party/blink/renderer/core/timing/window_performance_test.cc
index a24145c..6384287c 100644
--- a/third_party/blink/renderer/core/timing/window_performance_test.cc
+++ b/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/string_or_double.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_double_or_performance_measure_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/performance_monitor.h"
 #include "third_party/blink/renderer/core/loader/document_load_timing.h"
diff --git a/third_party/blink/renderer/core/xml/dom_parser.cc b/third_party/blink/renderer/core/xml/dom_parser.cc
index 7189bb2..9676c56 100644
--- a/third_party/blink/renderer/core/xml/dom_parser.cc
+++ b/third_party/blink/renderer/core/xml/dom_parser.cc
@@ -19,6 +19,7 @@
 
 #include "third_party/blink/renderer/core/xml/dom_parser.h"
 
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/dom_implementation.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/core/xml/xslt_processor.cc b/third_party/blink/renderer/core/xml/xslt_processor.cc
index 9e74930b..b59f7fc 100644
--- a/third_party/blink/renderer/core/xml/xslt_processor.cc
+++ b/third_party/blink/renderer/core/xml/xslt_processor.cc
@@ -24,6 +24,7 @@
 
 #include "third_party/blink/renderer/core/dom/document_encoding_data.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
+#include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/dom_implementation.h"
 #include "third_party/blink/renderer/core/editing/serializers/serialization.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
diff --git a/third_party/blink/renderer/modules/accessibility/BUILD.gn b/third_party/blink/renderer/modules/accessibility/BUILD.gn
index a7dbded..3aadcb0 100644
--- a/third_party/blink/renderer/modules/accessibility/BUILD.gn
+++ b/third_party/blink/renderer/modules/accessibility/BUILD.gn
@@ -54,10 +54,6 @@
     "ax_sparse_attribute_setter.h",
     "ax_svg_root.cc",
     "ax_svg_root.h",
-    "ax_table_column.cc",
-    "ax_table_column.h",
-    "ax_table_header_container.cc",
-    "ax_table_header_container.h",
     "ax_virtual_object.cc",
     "ax_virtual_object.h",
     "inspector_accessibility_agent.cc",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index 8a8e790d..ebae2b3 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -96,9 +96,9 @@
 #include "third_party/blink/renderer/core/svg/svg_svg_element.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_image_map_link.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_mock_object.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_svg_root.h"
-#include "third_party/blink/renderer/modules/accessibility/ax_table_column.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
 #include "third_party/blink/renderer/platform/text/platform_locale.h"
@@ -3101,18 +3101,6 @@
     AXNodeObject::RowHeaders(headers);
 }
 
-AXObject* AXLayoutObject::HeaderContainer() {
-  for (const auto& child : Children()) {
-    if (child->RoleValue() == kTableHeaderContainerRole)
-      return child;
-  }
-
-  AXMockObject* header_container =
-      ToAXMockObject(AXObjectCache().GetOrCreate(kTableHeaderContainerRole));
-  header_container->SetParent(this);
-  return header_container;
-}
-
 AXObject* AXLayoutObject::HeaderObject() const {
   LayoutObject* layout_object = GetLayoutObject();
   if (!layout_object || !layout_object->IsTableRow())
@@ -3413,21 +3401,6 @@
       }
     }
   }
-
-  for (unsigned i = 0; i < ColumnCount(); i++) {
-    AXTableColumn* column = ToAXTableColumn(ax_cache.GetOrCreate(kColumnRole));
-    column->SetColumnIndex(i);
-    column->SetParent(this);
-    if (!column->AccessibilityIsIgnored())
-      children_.push_back(column);
-  }
-
-  AXObject* header_container_object = HeaderContainer();
-  if (header_container_object &&
-      !header_container_object->AccessibilityIsIgnored()) {
-    children_.push_back(header_container_object);
-    header_container_object->SetParent(this);
-  }
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
index ec52265a..13ae790 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
@@ -197,7 +197,6 @@
   void ColumnHeaders(AXObjectVector&) const override;
   void RowHeaders(AXObjectVector&) const override;
   AXObject* CellForColumnAndRow(unsigned column, unsigned row) const override;
-  AXObject* HeaderContainer() override;
 
   // For a table cell.
   unsigned ColumnIndex() const override;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index 29df157a..16c101e3 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -877,8 +877,6 @@
   virtual void ColumnHeaders(AXObjectVector&) const;
   virtual void RowHeaders(AXObjectVector&) const;
   virtual AXObject* CellForColumnAndRow(unsigned column, unsigned row) const;
-  // an object that contains, as children, all the objects that act as headers
-  virtual AXObject* HeaderContainer() { return nullptr; }
 
   // For a cell.
   virtual unsigned ColumnIndex() const;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index a06314c..f6378fe 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -81,8 +81,6 @@
 #include "third_party/blink/renderer/modules/accessibility/ax_relation_cache.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_slider.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_svg_root.h"
-#include "third_party/blink/renderer/modules/accessibility/ax_table_column.h"
-#include "third_party/blink/renderer/modules/accessibility/ax_table_header_container.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_virtual_object.h"
 #include "third_party/blink/renderer/modules/permissions/permission_utils.h"
 
@@ -465,12 +463,6 @@
   AXObject* obj = nullptr;
 
   switch (role) {
-    case kColumnRole:
-      obj = AXTableColumn::Create(*this);
-      break;
-    case kTableHeaderContainerRole:
-      obj = AXTableHeaderContainer::Create(*this);
-      break;
     case kSliderThumbRole:
       obj = AXSliderThumb::Create(*this);
       break;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_position_test.cc b/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
index 4b6d0be..505af19e 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
@@ -994,8 +994,8 @@
   const auto ax_position_at_end =
       AXPosition::CreateLastPositionInObject(*ax_table);
   const auto position_at_end = ax_position_at_end.ToPositionWithAffinity();
-  EXPECT_EQ(last_cell_text, position_at_end.AnchorNode());
-  EXPECT_EQ(3, position_at_end.GetPosition().OffsetInContainerNode());
+  EXPECT_EQ(table, position_at_end.AnchorNode());
+  EXPECT_TRUE(position_at_end.GetPosition().IsAfterChildren());
 
   const auto ax_position_at_end_from_dom =
       AXPosition::FromPosition(position_at_end);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_table_column.cc b/third_party/blink/renderer/modules/accessibility/ax_table_column.cc
deleted file mode 100644
index e8ec20f..0000000
--- a/third_party/blink/renderer/modules/accessibility/ax_table_column.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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.
- */
-
-#include "third_party/blink/renderer/modules/accessibility/ax_table_column.h"
-
-#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
-#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
-
-namespace blink {
-
-using namespace HTMLNames;
-
-AXTableColumn::AXTableColumn(AXObjectCacheImpl& ax_object_cache)
-    : AXMockObject(ax_object_cache) {}
-
-AXTableColumn::~AXTableColumn() = default;
-
-AXTableColumn* AXTableColumn::Create(AXObjectCacheImpl& ax_object_cache) {
-  return new AXTableColumn(ax_object_cache);
-}
-
-void AXTableColumn::SetParent(AXObject* parent) {
-  AXMockObject::SetParent(parent);
-
-  ClearChildren();
-}
-
-void AXTableColumn::HeaderObjectsForColumn(AXObjectVector& headers) const {
-  if (!parent_)
-    return;
-
-  LayoutObject* layout_object = parent_->GetLayoutObject();
-  if (!layout_object)
-    return;
-
-  if (!parent_->IsTableLikeRole())
-    return;
-
-  for (const auto& cell : Children()) {
-    if (cell->RoleValue() == kColumnHeaderRole)
-      headers.push_back(cell);
-  }
-}
-
-AXObject* AXTableColumn::HeaderObject() const {
-  AXObjectVector headers;
-  HeaderObjectsForColumn(headers);
-  if (!headers.size())
-    return nullptr;
-
-  return headers[0].Get();
-}
-
-bool AXTableColumn::ComputeAccessibilityIsIgnored(
-    IgnoredReasons* ignored_reasons) const {
-  if (!parent_)
-    return true;
-
-  if (!parent_->AccessibilityIsIgnored())
-    return false;
-
-  if (ignored_reasons)
-    parent_->ComputeAccessibilityIsIgnored(ignored_reasons);
-
-  return true;
-}
-
-AccessibilityRole AXTableColumn::RoleValue() const {
-  return parent_ && parent_->IsDataTable() ? kColumnRole
-                                           : kLayoutTableColumnRole;
-}
-
-void AXTableColumn::AddChildren() {
-  DCHECK(!IsDetached());
-  DCHECK(!have_children_);
-
-  have_children_ = true;
-  if (!parent_ || !parent_->IsTableLikeRole())
-    return;
-
-  unsigned num_rows = parent_->RowCount();
-  for (unsigned i = 0; i < num_rows; i++) {
-    AXObject* cell = parent_->CellForColumnAndRow(column_index_, i);
-    if (!cell)
-      continue;
-
-    // make sure the last one isn't the same as this one (rowspan cells)
-    if (children_.size() > 0 && children_.back() == cell)
-      continue;
-
-    children_.push_back(cell);
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/accessibility/ax_table_column.h b/third_party/blink/renderer/modules/accessibility/ax_table_column.h
deleted file mode 100644
index 42361595..0000000
--- a/third_party/blink/renderer/modules/accessibility/ax_table_column.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_TABLE_COLUMN_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_TABLE_COLUMN_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/modules/accessibility/ax_mock_object.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-
-namespace blink {
-
-class AXObjectCacheImpl;
-
-class MODULES_EXPORT AXTableColumn final : public AXMockObject {
- private:
-  explicit AXTableColumn(AXObjectCacheImpl&);
-
- public:
-  static AXTableColumn* Create(AXObjectCacheImpl&);
-  ~AXTableColumn() override;
-
-  // retrieves the topmost "column" header (th)
-  AXObject* HeaderObject() const override;
-
-  void SetColumnIndex(unsigned column_index) { column_index_ = column_index; }
-  unsigned ColumnIndex() const override { return column_index_; }
-
-  void AddChildren() override;
-  void SetParent(AXObject*) override;
-
- protected:
-  // retrieves the "column" headers (th, scope) from top to bottom
-  void HeaderObjectsForColumn(AXObjectVector&) const;
-
-  bool CanSetSelectedAttribute() const override { return false; }
-
-  // Set the role via RoleValue() instead of DetermineAccessibilityRole(),
-  // because the role depends on the parent, and DetermineAccessibilityRole()
-  // is called before SetParent().
-  AccessibilityRole RoleValue() const final;
-
- private:
-  unsigned column_index_;
-
-  bool IsTableCol() const override { return true; }
-  bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override;
-
-  DISALLOW_COPY_AND_ASSIGN(AXTableColumn);
-};
-
-DEFINE_AX_OBJECT_TYPE_CASTS(AXTableColumn, IsTableCol());
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_TABLE_COLUMN_H_
diff --git a/third_party/blink/renderer/modules/accessibility/ax_table_header_container.cc b/third_party/blink/renderer/modules/accessibility/ax_table_header_container.cc
deleted file mode 100644
index 7a03541..0000000
--- a/third_party/blink/renderer/modules/accessibility/ax_table_header_container.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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.
- */
-
-#include "third_party/blink/renderer/modules/accessibility/ax_table_header_container.h"
-
-#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
-
-namespace blink {
-
-AXTableHeaderContainer::AXTableHeaderContainer(
-    AXObjectCacheImpl& ax_object_cache)
-    : AXMockObject(ax_object_cache) {}
-
-AXTableHeaderContainer::~AXTableHeaderContainer() = default;
-
-AXTableHeaderContainer* AXTableHeaderContainer::Create(
-    AXObjectCacheImpl& ax_object_cache) {
-  return new AXTableHeaderContainer(ax_object_cache);
-}
-
-bool AXTableHeaderContainer::ComputeAccessibilityIsIgnored(
-    IgnoredReasons* ignored_reasons) const {
-  if (!parent_)
-    return true;
-
-  if (!parent_->AccessibilityIsIgnored())
-    return false;
-
-  if (ignored_reasons)
-    parent_->ComputeAccessibilityIsIgnored(ignored_reasons);
-
-  return true;
-}
-
-void AXTableHeaderContainer::AddChildren() {
-  DCHECK(!IsDetached());
-  DCHECK(!have_children_);
-
-  have_children_ = true;
-  if (!parent_ || !parent_->IsTableLikeRole())
-    return;
-
-  parent_->ColumnHeaders(children_);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/accessibility/ax_table_header_container.h b/third_party/blink/renderer/modules/accessibility/ax_table_header_container.h
deleted file mode 100644
index 3fe3e16..0000000
--- a/third_party/blink/renderer/modules/accessibility/ax_table_header_container.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_TABLE_HEADER_CONTAINER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_TABLE_HEADER_CONTAINER_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/modules/accessibility/ax_mock_object.h"
-
-namespace blink {
-
-class AXObjectCacheImpl;
-
-// This is an object only needed on macOS - on that platform it's a child of the
-// table, and it contains every column header cell in the entire table as its
-// children.
-//
-// TODO: remove this from Blink, implement it on the client side only for macOS.
-class AXTableHeaderContainer final : public AXMockObject {
- private:
-  explicit AXTableHeaderContainer(AXObjectCacheImpl&);
-
- public:
-  static AXTableHeaderContainer* Create(AXObjectCacheImpl&);
-  ~AXTableHeaderContainer() override;
-
-  AccessibilityRole RoleValue() const override {
-    return kTableHeaderContainerRole;
-  }
-
-  void AddChildren() override;
-
- private:
-  bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override;
-
-  DISALLOW_COPY_AND_ASSIGN(AXTableHeaderContainer);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_TABLE_HEADER_CONTAINER_H_
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc
index 2689baf..d998979d 100644
--- a/third_party/blink/renderer/modules/exported/web_ax_object.cc
+++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -1142,16 +1142,6 @@
   return WebAXObject(private_->CellForColumnAndRow(column, row));
 }
 
-WebAXObject WebAXObject::HeaderContainerObject() const {
-  if (IsDetached())
-    return WebAXObject();
-
-  if (!private_->IsTableLikeRole())
-    return WebAXObject();
-
-  return WebAXObject(private_->HeaderContainer());
-}
-
 unsigned WebAXObject::RowIndex() const {
   if (IsDetached())
     return 0;
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation.cc b/third_party/blink/renderer/modules/geolocation/geolocation.cc
index 73f4288..102af1a7 100644
--- a/third_party/blink/renderer/modules/geolocation/geolocation.cc
+++ b/third_party/blink/renderer/modules/geolocation/geolocation.cc
@@ -104,7 +104,8 @@
 
 Geolocation::Geolocation(ExecutionContext* context)
     : ContextLifecycleObserver(context),
-      PageVisibilityObserver(GetDocument()->GetPage()) {}
+      PageVisibilityObserver(GetDocument()->GetPage()),
+      watchers_(new GeolocationWatchers()) {}
 
 Geolocation::~Geolocation() = default;
 
@@ -130,7 +131,7 @@
 void Geolocation::ContextDestroyed(ExecutionContext*) {
   StopTimers();
   one_shots_.clear();
-  watchers_.Clear();
+  watchers_->Clear();
 
   StopUpdating();
 
@@ -216,7 +217,7 @@
   // have.
   do {
     watch_id = GetExecutionContext()->CircularSequentialID();
-  } while (!watchers_.Add(watch_id, notifier));
+  } while (!watchers_->Add(watch_id, notifier));
 
   StartRequest(notifier);
 
@@ -261,7 +262,7 @@
 
   // This request has failed fatally. Remove it from our lists.
   one_shots_.erase(notifier);
-  watchers_.Remove(notifier);
+  watchers_->Remove(notifier);
 
   if (!HasListeners())
     StopUpdating();
@@ -276,7 +277,7 @@
   // exists, start the service to get updates.
   if (one_shots_.Contains(notifier)) {
     one_shots_.erase(notifier);
-  } else if (watchers_.Contains(notifier)) {
+  } else if (watchers_->Contains(notifier)) {
     if (notifier->Options().timeout() > 0)
       StartUpdating(notifier);
     notifier->StartTimer();
@@ -299,7 +300,7 @@
 bool Geolocation::DoesOwnNotifier(GeoNotifier* notifier) const {
   return one_shots_.Contains(notifier) ||
          one_shots_being_invoked_.Contains(notifier) ||
-         watchers_.Contains(notifier) ||
+         watchers_->Contains(notifier) ||
          watchers_being_invoked_.Contains(notifier);
 }
 
@@ -318,12 +319,12 @@
   if (watch_id <= 0)
     return;
 
-  GeoNotifier* notifier = watchers_.Find(watch_id);
+  GeoNotifier* notifier = watchers_->Find(watch_id);
   if (!notifier)
     return;
 
   notifier->StopTimer();
-  watchers_.Remove(watch_id);
+  watchers_->Remove(watch_id);
 
   if (!HasListeners())
     StopUpdating();
@@ -334,7 +335,7 @@
     notifier->StopTimer();
   }
 
-  for (const auto& notifier : watchers_.Notifiers()) {
+  for (const auto& notifier : watchers_->Notifiers()) {
     notifier->StopTimer();
   }
 }
@@ -357,11 +358,11 @@
   // by a callback through getCurrentPosition, watchPosition, and/or
   // clearWatch.
   swap(one_shots_, one_shots_being_invoked_);
-  watchers_.CopyNotifiersToVector(watchers_being_invoked_);
+  watchers_->CopyNotifiersToVector(watchers_being_invoked_);
 
   if (error->IsFatal()) {
     // Clear the watchers before invoking the callbacks.
-    watchers_.Clear();
+    watchers_->Clear();
   }
 
   // Invoke the callbacks. Do not send a non-fatal error to the notifiers
@@ -414,7 +415,7 @@
   // by a callback through getCurrentPosition, watchPosition, and/or
   // clearWatch.
   swap(one_shots_, one_shots_being_invoked_);
-  watchers_.CopyNotifiersToVector(watchers_being_invoked_);
+  watchers_->CopyNotifiersToVector(watchers_being_invoked_);
 
   // Invoke the callbacks.
   //
@@ -507,7 +508,7 @@
 
 bool Geolocation::HasPendingActivity() const {
   return !one_shots_.IsEmpty() || !one_shots_being_invoked_.IsEmpty() ||
-         !watchers_.IsEmpty() || !watchers_being_invoked_.IsEmpty();
+         !watchers_->IsEmpty() || !watchers_being_invoked_.IsEmpty();
 }
 
 void Geolocation::OnGeolocationConnectionError() {
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation.h b/third_party/blink/renderer/modules/geolocation/geolocation.h
index 67c9141..9a59a4e3 100644
--- a/third_party/blink/renderer/modules/geolocation/geolocation.h
+++ b/third_party/blink/renderer/modules/geolocation/geolocation.h
@@ -156,7 +156,7 @@
   explicit Geolocation(ExecutionContext*);
 
   bool HasListeners() const {
-    return !one_shots_.IsEmpty() || !watchers_.IsEmpty();
+    return !one_shots_.IsEmpty() || !watchers_->IsEmpty();
   }
 
   void StopTimers();
@@ -196,7 +196,7 @@
   void OnGeolocationConnectionError();
 
   GeoNotifierSet one_shots_;
-  GeolocationWatchers watchers_;
+  TraceWrapperMember<GeolocationWatchers> watchers_;
   // GeoNotifiers that are in the middle of invocation.
   //
   // |HandleError(error)| and |MakeSuccessCallbacks| need to clear |one_shots_|
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h b/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h
index 72b71c3b..e51910a 100644
--- a/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h
+++ b/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h
@@ -12,9 +12,8 @@
 
 class GeoNotifier;
 
-class GeolocationWatchers : public TraceWrapperBase {
-  DISALLOW_NEW();
-
+class GeolocationWatchers : public GarbageCollected<GeolocationWatchers>,
+                            public TraceWrapperBase {
  public:
   GeolocationWatchers() = default;
   void Trace(blink::Visitor*);
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc
index bcd121f..bee8c4b 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc
@@ -4,8 +4,8 @@
 
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h"
 
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/html/forms/html_input_element.h"
 #include "third_party/blink/renderer/core/html/forms/html_label_element.h"
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc
index c9604bc..c7306b25 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/events/touch_event.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
@@ -74,7 +75,7 @@
 }
 
 void MediaControlsDisplayCutoutDelegate::DidExitFullscreen() {
-  GetDocument().SetExpandIntoDisplayCutout(false);
+  GetDocument().GetViewportData().SetExpandIntoDisplayCutout(false);
 
   video_element_->removeEventListener(EventTypeNames::touchstart, this, true);
   video_element_->removeEventListener(EventTypeNames::touchend, this, true);
@@ -147,8 +148,8 @@
 
     UseCounter::Count(GetDocument(),
                       WebFeature::kMediaControlsDisplayCutoutGesture);
-    GetDocument().SetExpandIntoDisplayCutout(direction ==
-                                             Direction::kExpanding);
+    GetDocument().GetViewportData().SetExpandIntoDisplayCutout(
+        direction == Direction::kExpanding);
   }
 
   // If we are finishing a touch then clear any stored value, otherwise store
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
index c1974b6..1de4394 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.h"
 #include "third_party/blink/renderer/core/events/touch_event.h"
 #include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/frame/viewport_data.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
@@ -148,6 +149,10 @@
                          FloatSize(1, 1), 90, 0, "test");
   }
 
+  mojom::ViewportFit CurrentViewportFit() const {
+    return GetDocument().GetViewportData().GetCurrentViewportFitForTests();
+  }
+
  private:
   MediaControlsDisplayCutoutDelegate& GetDelegate() {
     MediaControlsImpl* controls =
@@ -172,16 +177,14 @@
   SimulateEvent(CreateTouchEventWithList(EventTypeNames::touchmove, list));
 
   // Check the viewport fit value has been correctly set.
-  EXPECT_EQ(mojom::ViewportFit::kCover,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kCover, CurrentViewportFit());
 
   // Finish the gesture by contracting.
   list = CreateTouchListWithTwoPoints(0, 0, 0, 0);
   SimulateEvent(CreateTouchEventWithList(EventTypeNames::touchend, list));
 
   // Check the viewport fit value has been correctly set.
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 
   // Make sure we recorded a UseCounter metric.
   EXPECT_TRUE(UseCounter::IsCounted(
@@ -194,13 +197,11 @@
   SimulateExpandingGesture();
 
   // Check the viewport fit value has been correctly set.
-  EXPECT_EQ(mojom::ViewportFit::kCover,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kCover, CurrentViewportFit());
 
   // Simulate a contracting gesture and check the value has been restored.
   SimulateContractingGesture();
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 
   // Make sure we recorded a UseCounter metric.
   EXPECT_TRUE(UseCounter::IsCounted(
@@ -213,8 +214,7 @@
   SimulateContractingGesture();
 
   // Check that the value did not change.
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 }
 
 TEST_F(MediaControlsDisplayCutoutDelegateTest, ExpandingGesture) {
@@ -223,13 +223,11 @@
   SimulateExpandingGesture();
 
   // Check the viewport fit value has been correctly set.
-  EXPECT_EQ(mojom::ViewportFit::kCover,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kCover, CurrentViewportFit());
 
   // Exit fullscreen and check the value has been restored.
   SimulateExitFullscreen();
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 
   // Make sure we recorded a UseCounter metric.
   EXPECT_TRUE(UseCounter::IsCounted(
@@ -242,13 +240,11 @@
   SimulateExpandingGesture();
 
   // Check the viewport fit value has been correctly set.
-  EXPECT_EQ(mojom::ViewportFit::kCover,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kCover, CurrentViewportFit());
 
   // Simulate another expanding gesture and make sure nothing changed.
   SimulateExpandingGesture();
-  EXPECT_EQ(mojom::ViewportFit::kCover,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kCover, CurrentViewportFit());
 }
 
 TEST_F(MediaControlsDisplayCutoutDelegateTest, IncompleteGestureClearsState) {
@@ -276,16 +272,14 @@
 TEST_F(MediaControlsDisplayCutoutDelegateTest, NoFullscreen_Noop) {
   // Simulate an expanding gesture and make sure it had no effect.
   SimulateExpandingGesture();
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 }
 
 TEST_F(MediaControlsDisplayCutoutDelegateTest, SingleTouchGesture_Noop) {
   // Simulate a single touch gesture and make sure it had no effect.
   SimulateEnterFullscreen();
   SimulateSingleTouchGesture();
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 }
 
 TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchCancelShouldClearState) {
@@ -300,8 +294,7 @@
   list = CreateTouchListWithTwoPoints(1, 1, -1, -1);
   SimulateEvent(CreateTouchEventWithList(EventTypeNames::touchcancel, list));
   EXPECT_FALSE(HasGestureState());
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 }
 
 TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchEndShouldClearState) {
@@ -316,8 +309,7 @@
   list = CreateTouchListWithTwoPoints(1, 1, -1, -1);
   SimulateEvent(CreateTouchEventWithList(EventTypeNames::touchend, list));
   EXPECT_FALSE(HasGestureState());
-  EXPECT_EQ(mojom::ViewportFit::kAuto,
-            GetDocument().GetCurrentViewportFitForTests());
+  EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
index 104dab0..86311ce5 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -30,7 +30,7 @@
 #include "third_party/blink/public/platform/web_size.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
 #include "third_party/blink/renderer/core/css/css_style_declaration.h"
-#include "third_party/blink/renderer/core/dom/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
 #include "third_party/blink/renderer/core/dom/mutation_observer.h"
 #include "third_party/blink/renderer/core/dom/mutation_observer_init.h"
 #include "third_party/blink/renderer/core/dom/mutation_record.h"
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index 8474a6ad..4bd7bae 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/geometry/dom_rect.h"
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
diff --git a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc
index 4bb6c38..ef7c9db 100644
--- a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc
@@ -43,6 +43,7 @@
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fetch/global_fetch.h"
+#include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/inspector/worker_inspector_controller.h"
 #include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h"
@@ -317,11 +318,25 @@
 
 void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls,
                                              ExceptionState& exception_state) {
-  // Bust the MemoryCache to ensure script requests reach the browser-side
-  // and get added to and retrieved from the ServiceWorker's script cache.
-  // FIXME: Revisit in light of the solution to crbug/388375.
-  for (Vector<String>::const_iterator it = urls.begin(); it != urls.end(); ++it)
-    GetExecutionContext()->RemoveURLFromMemoryCache(CompleteURL(*it));
+  InstalledScriptsManager* installed_scripts_manager =
+      GetThread()->GetInstalledScriptsManager();
+  for (auto& url : urls) {
+    KURL completed_url = CompleteURL(url);
+    // Counts the usage of importScripts() of new scripts after installation
+    // because we want to deprecate such usage (https://crbug.com/719052).
+    // This will undercount because installed scripts manager is only provided
+    // to installed service workers on startup, but this gives us an idea of
+    // the usage.
+    if (installed_scripts_manager &&
+        !installed_scripts_manager->IsScriptInstalled(completed_url)) {
+      DCHECK(installed_scripts_manager->IsScriptInstalled(Url()));
+      CountFeature(WebFeature::kServiceWorkerImportScriptNotInstalled);
+    }
+    // Bust the MemoryCache to ensure script requests reach the browser-side
+    // and get added to and retrieved from the ServiceWorker's script cache.
+    // FIXME: Revisit in light of the solution to crbug/388375.
+    RemoveURLFromMemoryCache(completed_url);
+  }
   WorkerGlobalScope::importScripts(urls, exception_state);
 }
 
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
index e97e470..5de9d664 100644
--- a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
+++ b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
@@ -15,9 +15,9 @@
 class XRFrame;
 class XRSession;
 
-class XRFrameRequestCallbackCollection final : public TraceWrapperBase {
-  DISALLOW_NEW();
-
+class XRFrameRequestCallbackCollection final
+    : public GarbageCollectedFinalized<XRFrameRequestCallbackCollection>,
+      public TraceWrapperBase {
  public:
   explicit XRFrameRequestCallbackCollection(ExecutionContext*);
 
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index 7335307..acde21d 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -96,7 +96,8 @@
     : device_(device),
       exclusive_(exclusive),
       output_context_(output_context),
-      callback_collection_(device->xr()->GetExecutionContext()) {
+      callback_collection_(new XRFrameRequestCallbackCollection(
+          device->xr()->GetExecutionContext())) {
   blurred_ = !HasAppropriateFocus();
 
   // When an output context is provided, monitor it for resize events.
@@ -229,7 +230,7 @@
   if (!base_layer_)
     return 0;
 
-  int id = callback_collection_.RegisterCallback(callback);
+  int id = callback_collection_->RegisterCallback(callback);
   if (!pending_frame_) {
     // Kick off a request for a new XR frame.
     device_->frameProvider()->RequestFrame(this);
@@ -239,7 +240,7 @@
 }
 
 void XRSession::cancelAnimationFrame(int id) {
-  callback_collection_.CancelCallback(id);
+  callback_collection_->CancelCallback(id);
 }
 
 HeapVector<Member<XRInputSource>> XRSession::getInputSources() const {
@@ -498,7 +499,7 @@
     // happen within these calls. resolving_frame_ will be true for the duration
     // of the callbacks.
     base::AutoReset<bool> resolving(&resolving_frame_, true);
-    callback_collection_.ExecuteCallbacks(this, presentation_frame);
+    callback_collection_->ExecuteCallbacks(this, presentation_frame);
 
     // The session might have ended in the middle of the frame. Only call
     // OnFrameEnd if it's still valid.
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h
index 83e3e29b..f461bae 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.h
+++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -174,7 +174,7 @@
   Member<ResizeObserver> resize_observer_;
   Member<XRCanvasInputProvider> canvas_input_provider_;
 
-  XRFrameRequestCallbackCollection callback_collection_;
+  TraceWrapperMember<XRFrameRequestCallbackCollection> callback_collection_;
   std::unique_ptr<TransformationMatrix> base_pose_matrix_;
 
   WTF::Vector<float> non_exclusive_projection_matrix_;
diff --git a/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h b/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h
index f82d144..5312a0e1 100644
--- a/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h
+++ b/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h
@@ -11,7 +11,7 @@
 
 namespace blink {
 
-class GC_PLUGIN_IGNORE("crbug.com/841830") PLATFORM_EXPORT TraceWrapperBase {
+class PLATFORM_EXPORT TraceWrapperBase {
   WTF_MAKE_NONCOPYABLE(TraceWrapperBase);
 
  public:
diff --git a/third_party/blink/renderer/platform/graphics/compositor_element_id.cc b/third_party/blink/renderer/platform/graphics/compositor_element_id.cc
index 271bf44f..320b454 100644
--- a/third_party/blink/renderer/platform/graphics/compositor_element_id.cc
+++ b/third_party/blink/renderer/platform/graphics/compositor_element_id.cc
@@ -33,7 +33,9 @@
          namespace_id == CompositorElementIdNamespace::kScroll ||
          namespace_id == CompositorElementIdNamespace::kEffectFilter ||
          namespace_id == CompositorElementIdNamespace::kEffectMask ||
-         namespace_id == CompositorElementIdNamespace::kEffectClipPath);
+         namespace_id == CompositorElementIdNamespace::kEffectClipPath ||
+         namespace_id == CompositorElementIdNamespace::kVerticalScrollbar ||
+         namespace_id == CompositorElementIdNamespace::kHorizontalScrollbar);
   return CreateCompositorElementId(id, namespace_id);
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositor_element_id.h b/third_party/blink/renderer/platform/graphics/compositor_element_id.h
index d3c2d94..878f83e 100644
--- a/third_party/blink/renderer/platform/graphics/compositor_element_id.h
+++ b/third_party/blink/renderer/platform/graphics/compositor_element_id.h
@@ -13,7 +13,7 @@
 
 namespace blink {
 
-const int kCompositorNamespaceBitCount = 3;
+const int kCompositorNamespaceBitCount = 4;
 
 enum class CompositorElementIdNamespace {
   kPrimary,
@@ -23,6 +23,8 @@
   kEffectFilter,
   kEffectMask,
   kEffectClipPath,
+  kVerticalScrollbar,
+  kHorizontalScrollbar,
   // A sentinel to indicate the maximum representable namespace id
   // (the maximum is one less than this value).
   kMaxRepresentableNamespaceId = 1 << kCompositorNamespaceBitCount
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc
index 066faf5d..83128b0 100644
--- a/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -1771,32 +1771,40 @@
 #pragma warning(disable : 4319)
 #endif
 
-  const uintptr_t random1 = ~(RotateLeft16(reinterpret_cast<uintptr_t>(
+  // Get an ASLR'd address from one of our own DLLs/.sos, and then another from
+  // a system DLL/.so:
+
+  const uint32_t random1 = ~(RotateLeft16(reinterpret_cast<uintptr_t>(
       base::trace_event::MemoryAllocatorDump::kNameSize)));
 
 #if defined(OS_WIN)
-  const uintptr_t random2 =
-      ~(RotateLeft16(reinterpret_cast<uintptr_t>(::ReadFile)));
+  uintptr_t random2 = reinterpret_cast<uintptr_t>(::ReadFile);
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-  const uintptr_t random2 =
-      ~(RotateLeft16(reinterpret_cast<uintptr_t>(::read)));
+  uintptr_t random2 = reinterpret_cast<uintptr_t>(::read);
+#else
+#error platform not supported
 #endif
 
 #if defined(ARCH_CPU_64_BITS)
   static_assert(sizeof(uintptr_t) == sizeof(uint64_t),
                 "uintptr_t is not uint64_t");
-  const uint32_t random = static_cast<uint32_t>(
-      (random1 & 0x0FFFFULL) | ((random2 >> 32) & 0x0FFFF0000ULL));
+  // Shift in some high-order bits.
+  random2 = random2 >> 16;
 #elif defined(ARCH_CPU_32_BITS)
   // Although we don't use heap metadata canaries on 32-bit due to memory
   // pressure, keep this code around just in case we do, someday.
   static_assert(sizeof(uintptr_t) == sizeof(uint32_t),
                 "uintptr_t is not uint32_t");
-  const uint32_t random = (random1 & 0x0FFFFUL) | (random2 & 0xFFFF0000UL);
 #else
 #error architecture not supported
 #endif
 
+  random2 = ~(RotateLeft16(random2));
+
+  // Combine the 2 values:
+  const uint32_t random = (random1 & 0x0000FFFFUL) |
+                          (static_cast<uint32_t>(random2) & 0xFFFF0000UL);
+
 #if defined(COMPILER_MSVC)
 #pragma warning(pop)
 #endif
diff --git a/third_party/blink/renderer/platform/scroll/scrollable_area.cc b/third_party/blink/renderer/platform/scroll/scrollable_area.cc
index b054cc2..18752a52 100644
--- a/third_party/blink/renderer/platform/scroll/scrollable_area.cc
+++ b/third_party/blink/renderer/platform/scroll/scrollable_area.cc
@@ -710,6 +710,18 @@
   SetScrollOffset(new_offset, kCompositorScroll);
 }
 
+CompositorElementId ScrollableArea::GetScrollbarElementId(
+    ScrollbarOrientation orientation) {
+  CompositorElementId scrollable_element_id = GetCompositorElementId();
+  DCHECK(scrollable_element_id);
+  CompositorElementIdNamespace element_id_namespace =
+      orientation == kHorizontalScrollbar
+          ? CompositorElementIdNamespace::kHorizontalScrollbar
+          : CompositorElementIdNamespace::kVerticalScrollbar;
+  return CompositorElementIdFromUniqueObjectId(
+      scrollable_element_id.ToInternalValue(), element_id_namespace);
+}
+
 void ScrollableArea::Trace(blink::Visitor* visitor) {
   visitor->Trace(scroll_animator_);
   visitor->Trace(programmatic_scroll_animator_);
diff --git a/third_party/blink/renderer/platform/scroll/scrollable_area.h b/third_party/blink/renderer/platform/scroll/scrollable_area.h
index 87b60bc..d373c283 100644
--- a/third_party/blink/renderer/platform/scroll/scrollable_area.h
+++ b/third_party/blink/renderer/platform/scroll/scrollable_area.h
@@ -271,6 +271,10 @@
   virtual IntRect ScrollableAreaBoundingBox() const = 0;
 
   virtual CompositorElementId GetCompositorElementId() const = 0;
+
+  virtual CompositorElementId GetScrollbarElementId(
+      ScrollbarOrientation orientation);
+
   virtual bool ScrollAnimatorEnabled() const { return false; }
 
   // NOTE: Only called from Internals for testing.
@@ -366,6 +370,8 @@
   virtual bool IsPaintLayerScrollableArea() const { return false; }
   virtual bool IsRootFrameViewport() const { return false; }
 
+  virtual bool VisualViewportSuppliesScrollbars() const { return false; }
+
   // Returns true if the scroller adjusts the scroll offset to compensate
   // for layout movements (bit.ly/scroll-anchoring).
   virtual bool ShouldPerformScrollAnchoring() const { return false; }
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar.cc b/third_party/blink/renderer/platform/scroll/scrollbar.cc
index 63dfde8..221f201 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar.cc
+++ b/third_party/blink/renderer/platform/scroll/scrollbar.cc
@@ -644,6 +644,11 @@
     scrollable_area_->SetScrollbarNeedsPaintInvalidation(Orientation());
 }
 
+CompositorElementId Scrollbar::GetElementId() {
+  DCHECK(scrollable_area_);
+  return scrollable_area_->GetScrollbarElementId(orientation_);
+}
+
 STATIC_ASSERT_ENUM(kWebScrollbarOverlayColorThemeDark,
                    kScrollbarOverlayColorThemeDark);
 STATIC_ASSERT_ENUM(kWebScrollbarOverlayColorThemeLight,
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar.h b/third_party/blink/renderer/platform/scroll/scrollbar.h
index 20eac35..d558b1a0 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar.h
+++ b/third_party/blink/renderer/platform/scroll/scrollbar.h
@@ -26,6 +26,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_H_
 
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
 #include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/scroll/scroll_types.h"
@@ -186,6 +187,8 @@
   // part.
   void SetNeedsPaintInvalidation(ScrollbarPart invalid_parts);
 
+  CompositorElementId GetElementId();
+
   // Promptly unregister from the theme manager + run finalizers of derived
   // Scrollbars.
   EAGERLY_FINALIZE();
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.ext b/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.ext
index fffe067..76e71d4 100644
--- a/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.ext
+++ b/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.ext
@@ -1,6 +1,6 @@
 basicConstraints = CA:FALSE
 # OID required for sxg since d54c469
-1.3.6.1.4.1.11129.2.1.22 = critical,ASN1:NULL
+1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL
 keyUsage = nonRepudiation, digitalSignature, keyEncipherment
 subjectKeyIdentifier = hash
 authorityKeyIdentifier = keyid,issuer
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.pem b/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.pem
index 01cad03..dd8871d 100644
--- a/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.pem
+++ b/third_party/blink/tools/blinkpy/third_party/wpt/certs/127.0.0.1.sxg.pem
@@ -1,17 +1,17 @@
 -----BEGIN CERTIFICATE-----
-MIICozCCAYugAwIBAgIBAzANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJ3ZWIt
-cGxhdGZvcm0tdGVzdHMwHhcNMTgwNjExMDcyMjE0WhcNMjgwNjA4MDcyMjE0WjAw
+MIICoDCCAYigAwIBAgIBAzANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJ3ZWIt
+cGxhdGZvcm0tdGVzdHMwHhcNMTgwNjI5MDUxMjAzWhcNMjgwNjI2MDUxMjAzWjAw
 MRIwEAYDVQQDDAkxMjcuMC4wLjExDTALBgNVBAoMBFRlc3QxCzAJBgNVBAYTAlVT
 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEf65JWX4duOedwlkjDlySWlTHityN
-qk+6yY0ROSbgExZCeipj+kwWSdtf258psdmuW+8E/wYIo2WPuzAP+KJtSKOBpTCB
-ojAJBgNVHRMEAjAAMBMGCisGAQQB1nkCARYBAf8EAgUAMAsGA1UdDwQEAwIF4DAd
-BgNVHQ4EFgQUhaNqMIY0BH36Ed7DQxtCGGzyIt4wHwYDVR0jBBgwFoAUTmUNO5Kz
-Wks0dfspJspTa6FlFX4wMwYDVR0RBCwwKoIJMTI3LjAuMC4xgg13d3cuMTI3LjAu
-MC4xgg53d3cyLjEyNy4wLjAuMTANBgkqhkiG9w0BAQsFAAOCAQEAqX5K+K6tCY+V
-QM72wwcXA9dP3ZrHsYv+t30FzBcNk7CDNjbeg1IF+4N3G8wC5hCeejGscO4Go/MA
-lgparmtut0SVXnVBzcsu2b/HZp786wjMPIkc4BbE4jLA1+XwubHFhNcUa+hOB/0e
-snHE6Wq5TNfpO3d1fNF84oJTQoo421yvDUYGAbWv3eDaQ+melncMpK4jsG6DtA9y
-ztY2E4rM6+RRYHze5IB0MEkkJCHS10q00aVntwPU83YDjTBimGpY0POQVW2lE9LC
-RO8hdDK5UQePR58YcPjHxc6fRE7NBj4DZKf0OzSqzkCO1WNbRCvYZ5uMFBsr0UUT
-z9M0h2jl2g==
+qk+6yY0ROSbgExZCeipj+kwWSdtf258psdmuW+8E/wYIo2WPuzAP+KJtSKOBojCB
+nzAJBgNVHRMEAjAAMBAGCisGAQQB1nkCARYEAgUAMAsGA1UdDwQEAwIF4DAdBgNV
+HQ4EFgQUhaNqMIY0BH36Ed7DQxtCGGzyIt4wHwYDVR0jBBgwFoAUTmUNO5KzWks0
+dfspJspTa6FlFX4wMwYDVR0RBCwwKoIJMTI3LjAuMC4xgg13d3cuMTI3LjAuMC4x
+gg53d3cyLjEyNy4wLjAuMTANBgkqhkiG9w0BAQsFAAOCAQEAsaHDMyEfjS+6OKam
+SZEbGOm67hDW/zxbXVMenWmGFFa1l6Y4gUoLY9QjEvi/9qIRXJ6VNny7VgoUKf9Y
+qsP9gN4MzJyE67fxE8kK909H4nnnQZkVxR91o710BhjZVvYw/l8300aEkBWJb5lu
+BEPVDiqD8ziwWX43oEZshpqjXQ24Lb5WoIfemZj2uFEz7mLarxktx9KU3myG6iFG
+1kPH/hlwTBeNR7z4rmFK87bvAR/VrGRu0W4XEgn63hX9/u5MLsW1v8e6eGxarTlQ
+oHDE2tPCkKSK4F5AYrRU20AV6CwzWgtCqm33xKzrqbIwIQkXkIax9a+T6jUmIj9f
+wttqSQ==
 -----END CERTIFICATE-----
diff --git a/third_party/libxml/win32/include/libxml/xmlversion.h b/third_party/libxml/win32/include/libxml/xmlversion.h
index e0a744e9..e73e434 100644
--- a/third_party/libxml/win32/include/libxml/xmlversion.h
+++ b/third_party/libxml/win32/include/libxml/xmlversion.h
@@ -1,486 +1,486 @@
-/*

- * Summary: compile-time version informations

- * Description: compile-time version informations for the XML library

- *

- * Copy: See Copyright for the status of this software.

- *

- * Author: Daniel Veillard

- */

-

-#ifndef __XML_VERSION_H__

-#define __XML_VERSION_H__

-

-#include <libxml/xmlexports.h>

-

-#ifdef __cplusplus

-extern "C" {

-#endif

-

-/*

- * use those to be sure nothing nasty will happen if

- * your library and includes mismatch

- */

-#ifndef LIBXML2_COMPILING_MSCCDEF

-XMLPUBFUN void XMLCALL xmlCheckVersion(int version);

-#endif /* LIBXML2_COMPILING_MSCCDEF */

-

-/**

- * LIBXML_DOTTED_VERSION:

- *

- * the version string like "1.2.3"

- */

-#define LIBXML_DOTTED_VERSION "2.9.8"

-

-/**

- * LIBXML_VERSION:

- *

- * the version number: 1.2.3 value is 10203

- */

-#define LIBXML_VERSION 20908

-

-/**

- * LIBXML_VERSION_STRING:

- *

- * the version number string, 1.2.3 value is "10203"

- */

-#define LIBXML_VERSION_STRING "20908"

-

-/**

- * LIBXML_VERSION_EXTRA:

- *

- * extra version information, used to show a CVS compilation

- */

-#define LIBXML_VERSION_EXTRA ""

-

-/**

- * LIBXML_TEST_VERSION:

- *

- * Macro to check that the libxml version in use is compatible with

- * the version the software has been compiled against

- */

-#define LIBXML_TEST_VERSION xmlCheckVersion(20908);

-

-#ifndef VMS

-#if 0

-/**

- * WITH_TRIO:

- *

- * defined if the trio support need to be configured in

- */

-#define WITH_TRIO

-#else

-/**

- * WITHOUT_TRIO:

- *

- * defined if the trio support should not be configured in

- */

-#define WITHOUT_TRIO

-#endif

-#else /* VMS */

-/**

- * WITH_TRIO:

- *

- * defined if the trio support need to be configured in

- */

-#define WITH_TRIO 1

-#endif /* VMS */

-

-/**

- * LIBXML_THREAD_ENABLED:

- *

- * Whether the thread support is configured in

- */

-#if 0

-#if defined(_REENTRANT) || defined(__MT__) || \

-    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))

-#define LIBXML_THREAD_ENABLED

-#endif

-#endif

-

-/**

- * LIBXML_THREAD_ALLOC_ENABLED:

- *

- * Whether the allocation hooks are per-thread

- */

-#if 0

-#define LIBXML_THREAD_ALLOC_ENABLED

-#endif

-

-/**

- * LIBXML_TREE_ENABLED:

- *

- * Whether the DOM like tree manipulation API support is configured in

- */

-#if 1

-#define LIBXML_TREE_ENABLED

-#endif

-

-/**

- * LIBXML_OUTPUT_ENABLED:

- *

- * Whether the serialization/saving support is configured in

- */

-#if 1

-#define LIBXML_OUTPUT_ENABLED

-#endif

-

-/**

- * LIBXML_PUSH_ENABLED:

- *

- * Whether the push parsing interfaces are configured in

- */

-#if 1

-#define LIBXML_PUSH_ENABLED

-#endif

-

-/**

- * LIBXML_READER_ENABLED:

- *

- * Whether the xmlReader parsing interface is configured in

- */

-#if 1

-#define LIBXML_READER_ENABLED

-#endif

-

-/**

- * LIBXML_PATTERN_ENABLED:

- *

- * Whether the xmlPattern node selection interface is configured in

- */

-#if 0

-#define LIBXML_PATTERN_ENABLED

-#endif

-

-/**

- * LIBXML_WRITER_ENABLED:

- *

- * Whether the xmlWriter saving interface is configured in

- */

-#if 1

-#define LIBXML_WRITER_ENABLED

-#endif

-

-/**

- * LIBXML_SAX1_ENABLED:

- *

- * Whether the older SAX1 interface is configured in

- */

-#if 1

-#define LIBXML_SAX1_ENABLED

-#endif

-

-/**

- * LIBXML_FTP_ENABLED:

- *

- * Whether the FTP support is configured in

- */

-#if 0

-#define LIBXML_FTP_ENABLED

-#endif

-

-/**

- * LIBXML_HTTP_ENABLED:

- *

- * Whether the HTTP support is configured in

- */

-#if 0

-#define LIBXML_HTTP_ENABLED

-#endif

-

-/**

- * LIBXML_VALID_ENABLED:

- *

- * Whether the DTD validation support is configured in

- */

-#if 0

-#define LIBXML_VALID_ENABLED

-#endif

-

-/**

- * LIBXML_HTML_ENABLED:

- *

- * Whether the HTML support is configured in

- */

-#if 1

-#define LIBXML_HTML_ENABLED

-#endif

-

-/**

- * LIBXML_LEGACY_ENABLED:

- *

- * Whether the deprecated APIs are compiled in for compatibility

- */

-#if 0

-#define LIBXML_LEGACY_ENABLED

-#endif

-

-/**

- * LIBXML_C14N_ENABLED:

- *

- * Whether the Canonicalization support is configured in

- */

-#if 0

-#define LIBXML_C14N_ENABLED

-#endif

-

-/**

- * LIBXML_CATALOG_ENABLED:

- *

- * Whether the Catalog support is configured in

- */

-#if 0

-#define LIBXML_CATALOG_ENABLED

-#endif

-

-/**

- * LIBXML_DOCB_ENABLED:

- *

- * Whether the SGML Docbook support is configured in

- */

-#if 0

-#define LIBXML_DOCB_ENABLED

-#endif

-

-/**

- * LIBXML_XPATH_ENABLED:

- *

- * Whether XPath is configured in

- */

-#if 1

-#define LIBXML_XPATH_ENABLED

-#endif

-

-/**

- * LIBXML_XPTR_ENABLED:

- *

- * Whether XPointer is configured in

- */

-#if 0

-#define LIBXML_XPTR_ENABLED

-#endif

-

-/**

- * LIBXML_XINCLUDE_ENABLED:

- *

- * Whether XInclude is configured in

- */

-#if 0

-#define LIBXML_XINCLUDE_ENABLED

-#endif

-

-/**

- * LIBXML_ICONV_ENABLED:

- *

- * Whether iconv support is available

- */

-#if 0

-#define LIBXML_ICONV_ENABLED

-#endif

-

-/**

- * LIBXML_ICU_ENABLED:

- *

- * Whether icu support is available

- */

-#if 1

-#define LIBXML_ICU_ENABLED

-#endif

-

-/**

- * LIBXML_ISO8859X_ENABLED:

- *

- * Whether ISO-8859-* support is made available in case iconv is not

- */

-#if 0

-#define LIBXML_ISO8859X_ENABLED

-#endif

-

-/**

- * LIBXML_DEBUG_ENABLED:

- *

- * Whether Debugging module is configured in

- */

-#if 0

-#define LIBXML_DEBUG_ENABLED

-#endif

-

-/**

- * DEBUG_MEMORY_LOCATION:

- *

- * Whether the memory debugging is configured in

- */

-#if 0

-#define DEBUG_MEMORY_LOCATION

-#endif

-

-/**

- * LIBXML_DEBUG_RUNTIME:

- *

- * Whether the runtime debugging is configured in

- */

-#if 0

-#define LIBXML_DEBUG_RUNTIME

-#endif

-

-/**

- * LIBXML_UNICODE_ENABLED:

- *

- * Whether the Unicode related interfaces are compiled in

- */

-#if 0

-#define LIBXML_UNICODE_ENABLED

-#endif

-

-/**

- * LIBXML_REGEXP_ENABLED:

- *

- * Whether the regular expressions interfaces are compiled in

- */

-#if 0

-#define LIBXML_REGEXP_ENABLED

-#endif

-

-/**

- * LIBXML_AUTOMATA_ENABLED:

- *

- * Whether the automata interfaces are compiled in

- */

-#if 0

-#define LIBXML_AUTOMATA_ENABLED

-#endif

-

-/**

- * LIBXML_EXPR_ENABLED:

- *

- * Whether the formal expressions interfaces are compiled in

- */

-#if 0

-#define LIBXML_EXPR_ENABLED

-#endif

-

-/**

- * LIBXML_SCHEMAS_ENABLED:

- *

- * Whether the Schemas validation interfaces are compiled in

- */

-#if 0

-#define LIBXML_SCHEMAS_ENABLED

-#endif

-

-/**

- * LIBXML_SCHEMATRON_ENABLED:

- *

- * Whether the Schematron validation interfaces are compiled in

- */

-#if 0

-#define LIBXML_SCHEMATRON_ENABLED

-#endif

-

-/**

- * LIBXML_MODULES_ENABLED:

- *

- * Whether the module interfaces are compiled in

- */

-#if 0

-#define LIBXML_MODULES_ENABLED

-/**

- * LIBXML_MODULE_EXTENSION:

- *

- * the string suffix used by dynamic modules (usually shared libraries)

- */

-#define LIBXML_MODULE_EXTENSION ".dll" 

-#endif

-

-/**

- * LIBXML_ZLIB_ENABLED:

- *

- * Whether the Zlib support is compiled in

- */

-#if 0

-#define LIBXML_ZLIB_ENABLED

-#endif

-

-/**

- * LIBXML_LZMA_ENABLED:

- *

- * Whether the Lzma support is compiled in

- */

-#if 0

-#define LIBXML_LZMA_ENABLED

-#endif

-

-#ifdef __GNUC__

-

-/**

- * ATTRIBUTE_UNUSED:

- *

- * Macro used to signal to GCC unused function parameters

- */

-

-#ifndef ATTRIBUTE_UNUSED

-# if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))

-#  define ATTRIBUTE_UNUSED __attribute__((unused))

-# else

-#  define ATTRIBUTE_UNUSED

-# endif

-#endif

-

-/**

- * LIBXML_ATTR_ALLOC_SIZE:

- *

- * Macro used to indicate to GCC this is an allocator function

- */

-

-#ifndef LIBXML_ATTR_ALLOC_SIZE

-# if (!defined(__clang__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))

-#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))

-# else

-#  define LIBXML_ATTR_ALLOC_SIZE(x)

-# endif

-#else

-# define LIBXML_ATTR_ALLOC_SIZE(x)

-#endif

-

-/**

- * LIBXML_ATTR_FORMAT:

- *

- * Macro used to indicate to GCC the parameter are printf like

- */

-

-#ifndef LIBXML_ATTR_FORMAT

-# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))

-#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))

-# else

-#  define LIBXML_ATTR_FORMAT(fmt,args)

-# endif

-#else

-# define LIBXML_ATTR_FORMAT(fmt,args)

-#endif

-

-#else /* ! __GNUC__ */

-/**

- * ATTRIBUTE_UNUSED:

- *

- * Macro used to signal to GCC unused function parameters

- */

-#define ATTRIBUTE_UNUSED

-/**

- * LIBXML_ATTR_ALLOC_SIZE:

- *

- * Macro used to indicate to GCC this is an allocator function

- */

-#define LIBXML_ATTR_ALLOC_SIZE(x)

-/**

- * LIBXML_ATTR_FORMAT:

- *

- * Macro used to indicate to GCC the parameter are printf like

- */

-#define LIBXML_ATTR_FORMAT(fmt,args)

-#endif /* __GNUC__ */

-

-#ifdef __cplusplus

-}

-#endif /* __cplusplus */

-#endif

-

-

+/*
+ * Summary: compile-time version informations
+ * Description: compile-time version informations for the XML library
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: Daniel Veillard
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+#include <libxml/xmlexports.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * use those to be sure nothing nasty will happen if
+ * your library and includes mismatch
+ */
+#ifndef LIBXML2_COMPILING_MSCCDEF
+XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
+#endif /* LIBXML2_COMPILING_MSCCDEF */
+
+/**
+ * LIBXML_DOTTED_VERSION:
+ *
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "2.9.8"
+
+/**
+ * LIBXML_VERSION:
+ *
+ * the version number: 1.2.3 value is 10203
+ */
+#define LIBXML_VERSION 20908
+
+/**
+ * LIBXML_VERSION_STRING:
+ *
+ * the version number string, 1.2.3 value is "10203"
+ */
+#define LIBXML_VERSION_STRING "20908"
+
+/**
+ * LIBXML_VERSION_EXTRA:
+ *
+ * extra version information, used to show a CVS compilation
+ */
+#define LIBXML_VERSION_EXTRA ""
+
+/**
+ * LIBXML_TEST_VERSION:
+ *
+ * Macro to check that the libxml version in use is compatible with
+ * the version the software has been compiled against
+ */
+#define LIBXML_TEST_VERSION xmlCheckVersion(20908);
+
+#ifndef VMS
+#if 0
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO
+#else
+/**
+ * WITHOUT_TRIO:
+ *
+ * defined if the trio support should not be configured in
+ */
+#define WITHOUT_TRIO
+#endif
+#else /* VMS */
+/**
+ * WITH_TRIO:
+ *
+ * defined if the trio support need to be configured in
+ */
+#define WITH_TRIO 1
+#endif /* VMS */
+
+/**
+ * LIBXML_THREAD_ENABLED:
+ *
+ * Whether the thread support is configured in
+ */
+#if 0
+#if defined(_REENTRANT) || defined(__MT__) || \
+    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
+#define LIBXML_THREAD_ENABLED
+#endif
+#endif
+
+/**
+ * LIBXML_THREAD_ALLOC_ENABLED:
+ *
+ * Whether the allocation hooks are per-thread
+ */
+#if 0
+#define LIBXML_THREAD_ALLOC_ENABLED
+#endif
+
+/**
+ * LIBXML_TREE_ENABLED:
+ *
+ * Whether the DOM like tree manipulation API support is configured in
+ */
+#if 1
+#define LIBXML_TREE_ENABLED
+#endif
+
+/**
+ * LIBXML_OUTPUT_ENABLED:
+ *
+ * Whether the serialization/saving support is configured in
+ */
+#if 1
+#define LIBXML_OUTPUT_ENABLED
+#endif
+
+/**
+ * LIBXML_PUSH_ENABLED:
+ *
+ * Whether the push parsing interfaces are configured in
+ */
+#if 1
+#define LIBXML_PUSH_ENABLED
+#endif
+
+/**
+ * LIBXML_READER_ENABLED:
+ *
+ * Whether the xmlReader parsing interface is configured in
+ */
+#if 1
+#define LIBXML_READER_ENABLED
+#endif
+
+/**
+ * LIBXML_PATTERN_ENABLED:
+ *
+ * Whether the xmlPattern node selection interface is configured in
+ */
+#if 0
+#define LIBXML_PATTERN_ENABLED
+#endif
+
+/**
+ * LIBXML_WRITER_ENABLED:
+ *
+ * Whether the xmlWriter saving interface is configured in
+ */
+#if 1
+#define LIBXML_WRITER_ENABLED
+#endif
+
+/**
+ * LIBXML_SAX1_ENABLED:
+ *
+ * Whether the older SAX1 interface is configured in
+ */
+#if 1
+#define LIBXML_SAX1_ENABLED
+#endif
+
+/**
+ * LIBXML_FTP_ENABLED:
+ *
+ * Whether the FTP support is configured in
+ */
+#if 0
+#define LIBXML_FTP_ENABLED
+#endif
+
+/**
+ * LIBXML_HTTP_ENABLED:
+ *
+ * Whether the HTTP support is configured in
+ */
+#if 0
+#define LIBXML_HTTP_ENABLED
+#endif
+
+/**
+ * LIBXML_VALID_ENABLED:
+ *
+ * Whether the DTD validation support is configured in
+ */
+#if 0
+#define LIBXML_VALID_ENABLED
+#endif
+
+/**
+ * LIBXML_HTML_ENABLED:
+ *
+ * Whether the HTML support is configured in
+ */
+#if 1
+#define LIBXML_HTML_ENABLED
+#endif
+
+/**
+ * LIBXML_LEGACY_ENABLED:
+ *
+ * Whether the deprecated APIs are compiled in for compatibility
+ */
+#if 0
+#define LIBXML_LEGACY_ENABLED
+#endif
+
+/**
+ * LIBXML_C14N_ENABLED:
+ *
+ * Whether the Canonicalization support is configured in
+ */
+#if 0
+#define LIBXML_C14N_ENABLED
+#endif
+
+/**
+ * LIBXML_CATALOG_ENABLED:
+ *
+ * Whether the Catalog support is configured in
+ */
+#if 0
+#define LIBXML_CATALOG_ENABLED
+#endif
+
+/**
+ * LIBXML_DOCB_ENABLED:
+ *
+ * Whether the SGML Docbook support is configured in
+ */
+#if 0
+#define LIBXML_DOCB_ENABLED
+#endif
+
+/**
+ * LIBXML_XPATH_ENABLED:
+ *
+ * Whether XPath is configured in
+ */
+#if 1
+#define LIBXML_XPATH_ENABLED
+#endif
+
+/**
+ * LIBXML_XPTR_ENABLED:
+ *
+ * Whether XPointer is configured in
+ */
+#if 0
+#define LIBXML_XPTR_ENABLED
+#endif
+
+/**
+ * LIBXML_XINCLUDE_ENABLED:
+ *
+ * Whether XInclude is configured in
+ */
+#if 0
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+/**
+ * LIBXML_ICONV_ENABLED:
+ *
+ * Whether iconv support is available
+ */
+#if 0
+#define LIBXML_ICONV_ENABLED
+#endif
+
+/**
+ * LIBXML_ICU_ENABLED:
+ *
+ * Whether icu support is available
+ */
+#if 1
+#define LIBXML_ICU_ENABLED
+#endif
+
+/**
+ * LIBXML_ISO8859X_ENABLED:
+ *
+ * Whether ISO-8859-* support is made available in case iconv is not
+ */
+#if 0
+#define LIBXML_ISO8859X_ENABLED
+#endif
+
+/**
+ * LIBXML_DEBUG_ENABLED:
+ *
+ * Whether Debugging module is configured in
+ */
+#if 0
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/**
+ * DEBUG_MEMORY_LOCATION:
+ *
+ * Whether the memory debugging is configured in
+ */
+#if 0
+#define DEBUG_MEMORY_LOCATION
+#endif
+
+/**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if 0
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
+ * LIBXML_UNICODE_ENABLED:
+ *
+ * Whether the Unicode related interfaces are compiled in
+ */
+#if 0
+#define LIBXML_UNICODE_ENABLED
+#endif
+
+/**
+ * LIBXML_REGEXP_ENABLED:
+ *
+ * Whether the regular expressions interfaces are compiled in
+ */
+#if 0
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+/**
+ * LIBXML_AUTOMATA_ENABLED:
+ *
+ * Whether the automata interfaces are compiled in
+ */
+#if 0
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+/**
+ * LIBXML_EXPR_ENABLED:
+ *
+ * Whether the formal expressions interfaces are compiled in
+ */
+#if 0
+#define LIBXML_EXPR_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMAS_ENABLED:
+ *
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#if 0
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+/**
+ * LIBXML_SCHEMATRON_ENABLED:
+ *
+ * Whether the Schematron validation interfaces are compiled in
+ */
+#if 0
+#define LIBXML_SCHEMATRON_ENABLED
+#endif
+
+/**
+ * LIBXML_MODULES_ENABLED:
+ *
+ * Whether the module interfaces are compiled in
+ */
+#if 0
+#define LIBXML_MODULES_ENABLED
+/**
+ * LIBXML_MODULE_EXTENSION:
+ *
+ * the string suffix used by dynamic modules (usually shared libraries)
+ */
+#define LIBXML_MODULE_EXTENSION ".dll"
+#endif
+
+/**
+ * LIBXML_ZLIB_ENABLED:
+ *
+ * Whether the Zlib support is compiled in
+ */
+#if 0
+#define LIBXML_ZLIB_ENABLED
+#endif
+
+/**
+ * LIBXML_LZMA_ENABLED:
+ *
+ * Whether the Lzma support is compiled in
+ */
+#if 0
+#define LIBXML_LZMA_ENABLED
+#endif
+
+#ifdef __GNUC__
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+
+#ifndef ATTRIBUTE_UNUSED
+# if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))
+#  define ATTRIBUTE_UNUSED __attribute__((unused))
+# else
+#  define ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+
+#ifndef LIBXML_ATTR_ALLOC_SIZE
+# if (!defined(__clang__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))
+#  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+# else
+#  define LIBXML_ATTR_ALLOC_SIZE(x)
+# endif
+#else
+# define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+
+#ifndef LIBXML_ATTR_FORMAT
+# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
+#  define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+# else
+#  define LIBXML_ATTR_FORMAT(fmt,args)
+# endif
+#else
+# define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#else /* ! __GNUC__ */
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ */
+#define ATTRIBUTE_UNUSED
+/**
+ * LIBXML_ATTR_ALLOC_SIZE:
+ *
+ * Macro used to indicate to GCC this is an allocator function
+ */
+#define LIBXML_ATTR_ALLOC_SIZE(x)
+/**
+ * LIBXML_ATTR_FORMAT:
+ *
+ * Macro used to indicate to GCC the parameter are printf like
+ */
+#define LIBXML_ATTR_FORMAT(fmt,args)
+#endif /* __GNUC__ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
+
diff --git a/tools/accessibility/inspect/example-tree-filters.txt b/tools/accessibility/inspect/example-tree-filters.txt
index 06077ec..1a27b52 100644
--- a/tools/accessibility/inspect/example-tree-filters.txt
+++ b/tools/accessibility/inspect/example-tree-filters.txt
@@ -1,8 +1,8 @@
-# Sample filters to use with ax_dump_tree, e.g. with --filters=[path-to-filters.txt]

-@ALLOW:role*

-@ALLOW:name*

-@ALLOW:rowtext*

-@ALLOW:coltext*

-@ALLOW:font*

-@DENY:font-family*

-@DENY:font-size*

+# Sample filters to use with ax_dump_tree, e.g. with --filters=[path-to-filters.txt]
+@ALLOW:role*
+@ALLOW:name*
+@ALLOW:rowtext*
+@ALLOW:coltext*
+@ALLOW:font*
+@DENY:font-family*
+@DENY:font-size*
diff --git a/tools/chrome_proxy/webdriver/variations_combinations.py b/tools/chrome_proxy/webdriver/variations_combinations.py
index 20c565ac..eef876b 100644
--- a/tools/chrome_proxy/webdriver/variations_combinations.py
+++ b/tools/chrome_proxy/webdriver/variations_combinations.py
@@ -47,7 +47,7 @@
     my_platform = 'mac'
   else:
     raise Exception('unknown platform!')
-  return fieldtrial_util.GenerateArgs(config_path, my_platform)
+  return fieldtrial_util.GenerateArgs(config_path, [my_platform])
 
 def GenerateTestSuites():
   """A generator function that yields non-blacklisted tests to run.
diff --git a/tools/clang/scripts/run_tool.py b/tools/clang/scripts/run_tool.py
index 388f241..ad85dd3 100755
--- a/tools/clang/scripts/run_tool.py
+++ b/tools/clang/scripts/run_tool.py
@@ -82,6 +82,7 @@
   """
   if not git_files:
     return []
+  git_files.sort()
   pruned_list = []
   git_index = 0
   for path in sorted(paths):
@@ -215,6 +216,10 @@
       # passed to the tool twice - once directly and once via
       # the compile args.
       if a != compdb_entry.filename
+        # /showIncludes is used by Ninja to track header file dependencies on
+        # Windows. We don't need to do this here, and it results in lots of spam
+        # and a massive log file, so we strip it.
+        and a != '/showIncludes'
   ])
 
   # shlex.split escapes double qoutes in non-Posix mode, so we need to strip
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 226c398..03132fe 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -27,7 +27,7 @@
 # Do NOT CHANGE this if you don't know what you're doing -- see
 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
-CLANG_REVISION = '335864'
+CLANG_REVISION = '336424'
 
 use_head_revision = bool(os.environ.get('LLVM_FORCE_HEAD_REVISION', '0')
                          in ('1', 'YES'))
diff --git a/tools/clang/translation_unit/TranslationUnitGenerator.cpp b/tools/clang/translation_unit/TranslationUnitGenerator.cpp
index be61238..579e647 100644
--- a/tools/clang/translation_unit/TranslationUnitGenerator.cpp
+++ b/tools/clang/translation_unit/TranslationUnitGenerator.cpp
@@ -29,11 +29,15 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
 using clang::HeaderSearchOptions;
 using clang::tooling::CommonOptionsParser;
+using llvm::sys::fs::real_path;
+using llvm::SmallVector;
 using std::set;
 using std::stack;
 using std::string;
@@ -203,7 +207,13 @@
 void IncludeFinderPPCallbacks::EndOfMainFile() {
   const clang::FileEntry* main_file =
       source_manager_->getFileEntryForID(source_manager_->getMainFileID());
-  assert(*main_source_file_ == main_file->getName());
+
+  SmallVector<char, 100> main_source_file_real_path;
+  SmallVector<char, 100> main_file_name_real_path;
+  assert(!real_path(*main_source_file_, main_source_file_real_path));
+  assert(!real_path(main_file->getName(), main_file_name_real_path));
+  assert(main_source_file_real_path == main_file_name_real_path);
+
   AddFile(main_file->getName());
 }
 
diff --git a/tools/clang/translation_unit/test_files/compile_commands.json.template b/tools/clang/translation_unit/test_files/compile_commands.json.template
index f771087..9fef4cf 100644
--- a/tools/clang/translation_unit/test_files/compile_commands.json.template
+++ b/tools/clang/translation_unit/test_files/compile_commands.json.template
@@ -8,5 +8,10 @@
     "directory": "$test_files_dir",
     "command": "clang++ -fsyntax-only -std=c++11 --sysroot ./sysroot -c test_relative_sysroot.cc",
     "file": "test_relative_sysroot.cc"
+  },
+  {
+    "directory": "$test_files_dir",
+    "command": "clang++ -I.",
+    "file": "includes_self.cc"
   }
-]
\ No newline at end of file
+]
diff --git a/tools/clang/translation_unit/test_files/includes_self.cc b/tools/clang/translation_unit/test_files/includes_self.cc
new file mode 100644
index 0000000..fbacda4b
--- /dev/null
+++ b/tools/clang/translation_unit/test_files/includes_self.cc
@@ -0,0 +1,6 @@
+#ifndef GUARD
+#define GUARD
+
+#include "includes_self.cc"
+
+#endif
diff --git a/tools/clang/translation_unit/test_files/includes_self.cc.filepaths.expected b/tools/clang/translation_unit/test_files/includes_self.cc.filepaths.expected
new file mode 100644
index 0000000..4552786
--- /dev/null
+++ b/tools/clang/translation_unit/test_files/includes_self.cc.filepaths.expected
@@ -0,0 +1 @@
+includes_self.cc
diff --git a/tools/clang/translation_unit/test_files/test.cc.filepaths.expected b/tools/clang/translation_unit/test_files/test.cc.filepaths.expected
index adb9e651..90693537 100644
--- a/tools/clang/translation_unit/test_files/test.cc.filepaths.expected
+++ b/tools/clang/translation_unit/test_files/test.cc.filepaths.expected
@@ -1,4 +1,4 @@
-./binomial.h
-./test.h
 //bits/wchar.h
+binomial.h
 test.cc
+test.h
diff --git a/tools/clang/translation_unit/test_translation_unit.py b/tools/clang/translation_unit/test_translation_unit.py
index 0482a787..426aa7b65 100755
--- a/tools/clang/translation_unit/test_translation_unit.py
+++ b/tools/clang/translation_unit/test_translation_unit.py
@@ -47,7 +47,9 @@
 
   args = ['python',
           os.path.join(tools_clang_scripts_directory, 'run_tool.py'),
+          '--tool',
           'translation_unit',
+          '-p',
           test_directory_for_tool]
   args.extend(source_files)
   run_tool = subprocess.Popen(args, stdout=subprocess.PIPE)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 8a944cb..8696a1a 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -11813,7 +11813,7 @@
   <int value="3" label="SENT_START_WORKER"/>
   <int value="4" label="SCRIPT_DOWNLOADING"/>
   <int value="5" label="SCRIPT_LOADED"/>
-  <int value="6" label="SCRIPT_EVALUATED"/>
+  <int value="6" label="SCRIPT_EVALUATED (obsolete)"/>
   <int value="7" label="THREAD_STARTED"/>
   <int value="8" label="SCRIPT_READ_STARTED"/>
   <int value="9" label="SCRIPT_READ_FINISHED"/>
@@ -19294,6 +19294,7 @@
   <int value="2495" label="DocumentOpenTwoArgsWithReplace"/>
   <int value="2496" label="DocumentOpenThreeArgs"/>
   <int value="2497" label="V8FunctionTokenOffsetTooLongForToString"/>
+  <int value="2498" label="ServiceWorkerImportScriptNotInstalled"/>
 </enum>
 
 <enum name="FeedbackSource">
diff --git a/tools/perf/core/perf_benchmark.py b/tools/perf/core/perf_benchmark.py
index 52b3abfe..0dd91ac 100644
--- a/tools/perf/core/perf_benchmark.py
+++ b/tools/perf/core/perf_benchmark.py
@@ -118,7 +118,7 @@
 
     return fieldtrial_util.GenerateArgs(
         os.path.join(variations_dir, 'fieldtrial_testing_config.json'),
-        self._FixupTargetOS(possible_browser.target_os))
+        [self._FixupTargetOS(possible_browser.target_os)])
 
   def _GetOutDirectoryEstimate(self, options):
     finder_options = options.finder_options
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index a0558cc4..a7dbc301 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -107,7 +107,10 @@
 crbug.com/859597 [ Nexus_5X ] loading.mobile/TribunNews_3g [ Skip ]
 crbug.com/859597 [ Nexus5X_Webview ] loading.mobile/TribunNews_3g [ Skip ]
 crbug.com/859597 [ Android_One ] loading.mobile/Facebook_3g [ Skip ]
-
+crbug.com/859597 [ Nexus_5X ] loading.mobile/GoogleIndonesia_3g [ Skip ]
+crbug.com/859597 [ Nexus_5X ] loading.mobile/QQNews_3g [ Skip ]
+crbug.com/859597 [ Nexus_5X ] loading.mobile/Youtube_3g [ Skip ]
+crbug.com/859597 [ Nexus5X_Webview ] loading.mobile/GoogleBrazil_3g [ Skip ]
 
 # Benchmark: memory.long_running_idle_gmail_tbmv2
 crbug.com/611167 [ Android_Svelte ] memory.long_running_idle_gmail_tbmv2/* [ Skip ]
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py
index 0c5953a..a844c63 100755
--- a/tools/perf/process_perf_results.py
+++ b/tools/perf/process_perf_results.py
@@ -11,7 +11,6 @@
 import shutil
 import sys
 import tempfile
-import traceback
 import time
 import uuid
 
@@ -273,9 +272,14 @@
       benchmark_directory_map, test_results_list)
 
   if not smoke_test_mode:
-    return_code = _handle_perf_results(
-        benchmark_enabled_map, benchmark_directory_map,
-        configuration_name, build_properties, service_account_file, extra_links)
+    try:
+      return_code = _handle_perf_results(
+          benchmark_enabled_map, benchmark_directory_map,
+          configuration_name, build_properties, service_account_file,
+          extra_links)
+    except Exception:
+      logging.exception('Error handling perf results jsons')
+      return_code = 1
 
   # Finally, merge all test results json, add the extra links and write out to
   # output location
@@ -368,9 +372,9 @@
     return _upload_individual(*params)
   except Exception:
     benchmark_name = params[0]
-    print 'Error uploading perf result of %s' % benchmark_name
-    print traceback.format_exc()
-    return benchmark_name, False
+    upload_fail = True
+    logging.exception('Error uploading perf result of %s' % benchmark_name)
+    return benchmark_name, upload_fail
 
 
 def _handle_perf_results(
@@ -456,18 +460,24 @@
 def _write_perf_data_to_logfile(benchmark_name, output_file,
     configuration_name, build_properties,
     logdog_dict, is_ref, upload_failure):
+  viewer_url = None
   # logdog file to write perf results to
-  output_json_file = logdog_helper.open_text(benchmark_name)
-  with open(output_file) as f:
-    try:
-      results = json.load(f)
-      json.dump(results, output_json_file,
-              indent=4, separators=(',', ': '))
-    except ValueError:
-      print(
-        ('Error parsing perf results JSON for benchmark  %s' % benchmark_name))
+  if os.path.exists(output_file):
+    output_json_file = logdog_helper.open_text(benchmark_name)
+    with open(output_file) as f:
+      try:
+        results = json.load(f)
+        json.dump(results, output_json_file,
+                indent=4, separators=(',', ': '))
+      except ValueError:
+        print ('Error parsing perf results JSON for benchmark  %s' %
+               benchmark_name)
 
-  output_json_file.close()
+    output_json_file.close()
+    viewer_url = output_json_file.get_viewer_url()
+  else:
+    print ("Perf results JSON file doesn't exist for benchmark %s" %
+           benchmark_name)
 
   base_benchmark_name = benchmark_name.replace('.reference', '')
 
@@ -477,19 +487,17 @@
   # add links for the perf results and the dashboard url to
   # the logs section of buildbot
   if is_ref:
-    logdog_dict[base_benchmark_name]['perf_results_ref'] = (
-        output_json_file.get_viewer_url())
+    logdog_dict[base_benchmark_name]['perf_results_ref'] = viewer_url
     if upload_failure:
       logdog_dict[base_benchmark_name]['ref_upload_failed'] = 'True'
   else:
-    logdog_dict[base_benchmark_name]['dashboard_url'] = \
+    logdog_dict[base_benchmark_name]['dashboard_url'] = (
         upload_results_to_perf_dashboard.GetDashboardUrl(
             benchmark_name,
             configuration_name, RESULTS_URL,
             build_properties['got_revision_cp'],
-            _GetMachineGroup(build_properties))
-    logdog_dict[base_benchmark_name]['perf_results'] = \
-        output_json_file.get_viewer_url()
+            _GetMachineGroup(build_properties)))
+    logdog_dict[base_benchmark_name]['perf_results'] = viewer_url
     if upload_failure:
       logdog_dict[base_benchmark_name]['upload_failed'] = 'True'
 
diff --git a/tools/variations/fieldtrial_to_struct.py b/tools/variations/fieldtrial_to_struct.py
index 240160f..6023aa6 100755
--- a/tools/variations/fieldtrial_to_struct.py
+++ b/tools/variations/fieldtrial_to_struct.py
@@ -3,7 +3,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import itertools
 import json
 import os.path
 import sys
@@ -22,6 +21,26 @@
 finally:
   sys.path.pop(0)
 
+_platforms = [
+  'android',
+  'android_webview',
+  'chromeos',
+  'fuchsia',
+  'ios',
+  'linux',
+  'mac',
+  'win',
+]
+
+# Convert a platform argument to the matching Platform enum value in
+# components/variations/proto/study.proto.
+def _PlatformEnumValue(platform):
+  assert platform in _platforms
+  # TODO(crbug/707911): Remove the 'win' special case.
+  if platform == 'win':
+    return 'Study::PLATFORM_WINDOWS'
+  return 'Study::PLATFORM_' + platform.upper()
+
 def _Load(filename):
   """Loads a JSON file into a Python object and return this object.
   """
@@ -29,14 +48,17 @@
     result = json.loads(json_comment_eater.Nom(handle.read()))
   return result
 
-def _LoadFieldTrialConfig(filename, platform):
+def _LoadFieldTrialConfig(filename, platforms):
   """Loads a field trial config JSON and converts it into a format that can be
   used by json_to_struct.
   """
-  return _FieldTrialConfigToDescription(_Load(filename), platform)
+  return _FieldTrialConfigToDescription(_Load(filename), platforms)
 
-def _CreateExperiment(experiment_data):
-  experiment = {'name': experiment_data['name']}
+def _CreateExperiment(experiment_data, platforms):
+  experiment = {
+    'name': experiment_data['name'],
+    'platforms': [_PlatformEnumValue(p) for p in platforms],
+  }
   forcing_flags_data = experiment_data.get('forcing_flag')
   if forcing_flags_data:
     experiment['forcing_flag'] = forcing_flags_data
@@ -52,40 +74,40 @@
     experiment['disable_features'] = disable_features_data
   return experiment
 
-def _CreateTrial(study_name, experiment_configs, platform):
-  """Returns the applicable experiments for |study_name| and |platform|. This
+def _CreateTrial(study_name, experiment_configs, platforms):
+  """Returns the applicable experiments for |study_name| and |platforms|. This
   iterates through all of the experiment_configs for |study_name| and picks out
   the applicable experiments based off of the valid platforms.
   """
-  platform_experiment_lists = [
-      config['experiments'] for config in experiment_configs
-      if platform in config['platforms']]
-  platform_experiments = list(itertools.chain.from_iterable(
-      platform_experiment_lists))
+  experiments = []
+  for config in experiment_configs:
+    platform_intersection = [p for p in platforms if p in config['platforms']]
+    if platform_intersection:
+      experiments += [_CreateExperiment(e, platform_intersection)
+                      for e in config['experiments']]
   return {
     'name': study_name,
-    'experiments': [_CreateExperiment(experiment)
-                    for experiment in platform_experiments],
+    'experiments': experiments,
   }
 
-def _GenerateTrials(config, platform):
+def _GenerateTrials(config, platforms):
   for study_name in sorted(config.keys()):
-    study = _CreateTrial(study_name, config[study_name], platform)
+    study = _CreateTrial(study_name, config[study_name], platforms)
     # To avoid converting studies with empty experiments (e.g. the study doesn't
-    # apply to the target platform), this generator only yields studies that
+    # apply to the target platforms), this generator only yields studies that
     # have non-empty experiments.
     if study['experiments']:
       yield study
 
-def ConfigToStudies(config, platform):
-  """Returns the applicable studies from config for the platform."""
-  return [study for study in _GenerateTrials(config, platform)]
+def ConfigToStudies(config, platforms):
+  """Returns the applicable studies from config for the platforms."""
+  return [study for study in _GenerateTrials(config, platforms)]
 
-def _FieldTrialConfigToDescription(config, platform):
+def _FieldTrialConfigToDescription(config, platforms):
   return {
     'elements': {
       'kFieldTrialConfig': {
-        'studies': ConfigToStudies(config, platform)
+        'studies': ConfigToStudies(config, platforms)
       }
     }
   }
@@ -100,7 +122,7 @@
       help='directory to output generated files, relative to destbase.')
   parser.add_option('-n', '--namespace',
       help='C++ namespace for generated files. e.g search_providers.')
-  parser.add_option('-p', '--platform',
+  parser.add_option('-p', '--platform', action='append', choices=_platforms,
       help='target platform for the field trial, mandatory.')
   parser.add_option('-s', '--schema', help='path to the schema file, '
       'mandatory.')
@@ -114,13 +136,7 @@
     parser.error('You must specify a --schema.')
 
   if not opts.platform:
-    parser.error('You must specify a --platform.')
-
-  supported_platforms = ['android', 'chromeos', 'fuchsia', 'ios', 'linux',
-                         'mac', 'win']
-  if opts.platform not in supported_platforms:
-    parser.error('\'%s\' is an unknown platform. Supported platforms: %s' %
-        (opts.platform, supported_platforms))
+    parser.error('You must specify at least 1 --platform.')
 
   description_filename = os.path.normpath(args[0])
   shortroot = opts.output
diff --git a/tools/variations/fieldtrial_to_struct_unittest.py b/tools/variations/fieldtrial_to_struct_unittest.py
index b08f0245..7e5cded5 100644
--- a/tools/variations/fieldtrial_to_struct_unittest.py
+++ b/tools/variations/fieldtrial_to_struct_unittest.py
@@ -55,7 +55,8 @@
         }
       ]
     }
-    result = fieldtrial_to_struct._FieldTrialConfigToDescription(config, 'win')
+    result = fieldtrial_to_struct._FieldTrialConfigToDescription(config,
+                                                                 ['win'])
     expected = {
       'elements': {
         'kFieldTrialConfig': {
@@ -65,6 +66,7 @@
               'experiments': [
                 {
                   'name': 'Group1',
+                  'platforms': ['Study::PLATFORM_WINDOWS'],
                   'params': [
                     {'key': 'x', 'value': '1'},
                     {'key': 'y', 'value': '2'}
@@ -74,6 +76,7 @@
                 },
                 {
                   'name': 'Group2',
+                  'platforms': ['Study::PLATFORM_WINDOWS'],
                   'params': [
                     {'key': 'x', 'value': '3'},
                     {'key': 'y', 'value': '4'}
@@ -85,13 +88,19 @@
             },
             {
               'name': 'Trial2',
-              'experiments': [{'name': 'OtherGroup'}]
+              'experiments': [
+                {
+                  'name': 'OtherGroup',
+                  'platforms': ['Study::PLATFORM_WINDOWS'],
+                }
+              ]
             },
             {
               'name': 'TrialWithForcingFlag',
               'experiments': [
                   {
                     'name': 'ForcedGroup',
+                    'platforms': ['Study::PLATFORM_WINDOWS'],
                     'forcing_flag': "my-forcing-flag"
                   }
               ]
@@ -147,7 +156,7 @@
 
   def test_FieldTrialToDescriptionMultipleSinglePlatformMultipleTrial(self):
     result = fieldtrial_to_struct._FieldTrialConfigToDescription(
-        self._MULTIPLE_PLATFORM_CONFIG, 'ios')
+        self._MULTIPLE_PLATFORM_CONFIG, ['ios'])
     expected = {
       'elements': {
         'kFieldTrialConfig': {
@@ -157,6 +166,7 @@
               'experiments': [
                 {
                   'name': 'Group1',
+                  'platforms': ['Study::PLATFORM_IOS'],
                   'params': [
                     {'key': 'x', 'value': '1'},
                     {'key': 'y', 'value': '2'}
@@ -166,6 +176,7 @@
                 },
                 {
                   'name': 'Group2',
+                  'platforms': ['Study::PLATFORM_IOS'],
                   'params': [
                     {'key': 'x', 'value': '3'},
                     {'key': 'y', 'value': '4'}
@@ -174,7 +185,8 @@
                   'disable_features': ['F']
                 },
                 {
-                  'name': 'IOSOnly'
+                  'name': 'IOSOnly',
+                  'platforms': ['Study::PLATFORM_IOS'],
                 },
               ],
             },
@@ -187,7 +199,7 @@
 
   def test_FieldTrialToDescriptionMultipleSinglePlatformSingleTrial(self):
     result = fieldtrial_to_struct._FieldTrialConfigToDescription(
-        self._MULTIPLE_PLATFORM_CONFIG, 'mac')
+        self._MULTIPLE_PLATFORM_CONFIG, ['mac'])
     expected = {
       'elements': {
         'kFieldTrialConfig': {
@@ -197,6 +209,7 @@
               'experiments': [
                 {
                   'name': 'OtherGroup',
+                  'platforms': ['Study::PLATFORM_MAC'],
                 },
               ],
             },
diff --git a/tools/variations/fieldtrial_util.py b/tools/variations/fieldtrial_util.py
index 8fea8fb..11bfb3a 100644
--- a/tools/variations/fieldtrial_util.py
+++ b/tools/variations/fieldtrial_util.py
@@ -50,15 +50,15 @@
                     ', '.join(features_in_both))
 
 # Generate a list of command-line switches to enable field trials for the
-# provided config_path and platform.
-def GenerateArgs(config_path, platform):
+# provided config_path and platforms.
+def GenerateArgs(config_path, platforms):
   try:
     with open(config_path, 'r') as config_file:
       config = json.load(config_file)
   except (IOError, ValueError):
     return []
 
-  platform_studies = fieldtrial_to_struct.ConfigToStudies(config, platform)
+  platform_studies = fieldtrial_to_struct.ConfigToStudies(config, platforms)
 
   studies = []
   params = []
@@ -108,13 +108,14 @@
     exit(-1)
   print_shell_cmd = len(sys.argv) >= 4 and sys.argv[3] == 'shell_cmd'
 
-  supported_platforms = ['android', 'chromeos', 'ios', 'linux', 'mac', 'win']
+  supported_platforms = ['android', 'android_webview', 'chromeos', 'ios',
+                         'linux', 'mac', 'win']
   if sys.argv[2] not in supported_platforms:
     print ('\'%s\' is an unknown platform. Supported platforms: %s' %
         (sys.argv[2], supported_platforms))
     exit(-1)
 
-  generated_args = GenerateArgs(sys.argv[1], sys.argv[2])
+  generated_args = GenerateArgs(sys.argv[1], [sys.argv[2]])
   if print_shell_cmd:
     print " ".join(map((lambda arg: '"{0}"'.format(arg)), generated_args))
   else:
diff --git a/tools/variations/fieldtrial_util_unittest.py b/tools/variations/fieldtrial_util_unittest.py
index 1e0db3c..870ad76 100644
--- a/tools/variations/fieldtrial_util_unittest.py
+++ b/tools/variations/fieldtrial_util_unittest.py
@@ -17,13 +17,13 @@
       try:
         base_file.write(config)
         base_file.close()
-        result = fieldtrial_util.GenerateArgs(base_file.name, platform)
+        result = fieldtrial_util.GenerateArgs(base_file.name, [platform])
       finally:
         os.unlink(base_file.name)
     return result
 
   def test_GenArgsEmptyPaths(self):
-    args = fieldtrial_util.GenerateArgs('', 'linux')
+    args = fieldtrial_util.GenerateArgs('', ['linux'])
     self.assertEqual([], args)
 
   def test_GenArgsOneConfig(self):
diff --git a/tools/variations/unittest_data/DEPS b/tools/variations/unittest_data/DEPS
new file mode 100644
index 0000000..e6d615a
--- /dev/null
+++ b/tools/variations/unittest_data/DEPS
@@ -0,0 +1,3 @@
+specific_include_rules = {
+  "expected_output.h": ["+components/variations/proto/study.pb.h"]
+}
diff --git a/tools/variations/unittest_data/expected_output.cc b/tools/variations/unittest_data/expected_output.cc
index 6feaaba..f7cbab7 100644
--- a/tools/variations/unittest_data/expected_output.cc
+++ b/tools/variations/unittest_data/expected_output.cc
@@ -10,9 +10,14 @@
 #include "test_output.h"
 
 
+const Study::Platform array_kFieldTrialConfig_platforms_3[] = {
+      Study::PLATFORM_WINDOWS,
+};
 const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_2[] = {
     {
       "ForcedGroup",
+      array_kFieldTrialConfig_platforms_3,
+      1,
       NULL,
       0,
       NULL,
@@ -25,9 +30,14 @@
 const char* const array_kFieldTrialConfig_enable_features_1[] = {
       "X",
 };
+const Study::Platform array_kFieldTrialConfig_platforms_2[] = {
+      Study::PLATFORM_WINDOWS,
+};
 const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
     {
       "TestGroup3",
+      array_kFieldTrialConfig_platforms_2,
+      1,
       NULL,
       0,
       array_kFieldTrialConfig_enable_features_1,
@@ -54,6 +64,9 @@
         "4",
       },
 };
+const Study::Platform array_kFieldTrialConfig_platforms_1[] = {
+      Study::PLATFORM_WINDOWS,
+};
 const char* const array_kFieldTrialConfig_disable_features[] = {
       "C",
 };
@@ -71,9 +84,14 @@
         "2",
       },
 };
+const Study::Platform array_kFieldTrialConfig_platforms_0[] = {
+      Study::PLATFORM_WINDOWS,
+};
 const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
     {
       "TestGroup2",
+      array_kFieldTrialConfig_platforms_0,
+      1,
       array_kFieldTrialConfig_params,
       2,
       array_kFieldTrialConfig_enable_features,
@@ -84,6 +102,8 @@
     },
     {
       "TestGroup2-2",
+      array_kFieldTrialConfig_platforms_1,
+      1,
       array_kFieldTrialConfig_params_0,
       2,
       array_kFieldTrialConfig_enable_features_0,
@@ -93,9 +113,14 @@
       NULL,
     },
 };
+const Study::Platform array_kFieldTrialConfig_platforms[] = {
+      Study::PLATFORM_WINDOWS,
+};
 const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
     {
       "TestGroup1",
+      array_kFieldTrialConfig_platforms,
+      1,
       NULL,
       0,
       NULL,
diff --git a/tools/variations/unittest_data/expected_output.h b/tools/variations/unittest_data/expected_output.h
index 2d78e70..641ff31 100644
--- a/tools/variations/unittest_data/expected_output.h
+++ b/tools/variations/unittest_data/expected_output.h
@@ -12,6 +12,7 @@
 
 #include <cstddef>
 
+#include "components/variations/proto/study.pb.h"
 
 struct FieldTrialTestingExperimentParams {
   const char* const key;
@@ -20,6 +21,8 @@
 
 struct FieldTrialTestingExperiment {
   const char* const name;
+  const Study::Platform * platforms;
+  const size_t platforms_size;
   const FieldTrialTestingExperimentParams * params;
   const size_t params_size;
   const char* const * enable_features;
diff --git a/ui/android/event_forwarder.cc b/ui/android/event_forwarder.cc
index 74e29f4..aa6d68e 100644
--- a/ui/android/event_forwarder.cc
+++ b/ui/android/event_forwarder.cc
@@ -153,7 +153,8 @@
       ScalePoint(view_->GetLocationOnScreen(x, y), 1.f / dip_scale);
   return view_->OnGestureEvent(GestureEventAndroid(
       type, gfx::PointF(x / dip_scale, y / dip_scale), root_location, time_ms,
-      scale, 0, 0, 0, 0, false, false));
+      scale, 0, 0, 0, 0, /*target_viewport*/ false, /*synthetic_scroll*/ false,
+      /*prevent_boosting*/ false));
 }
 
 jboolean EventForwarder::OnGenericMotionEvent(
@@ -207,7 +208,8 @@
   float dip_scale = view_->GetDipScale();
   view_->OnGestureEvent(GestureEventAndroid(
       GESTURE_EVENT_TYPE_DOUBLE_TAP, gfx::PointF(x / dip_scale, y / dip_scale),
-      gfx::PointF(), time_ms, 0, 0, 0, 0, 0, true, false));
+      gfx::PointF(), time_ms, 0, 0, 0, 0, 0, /*target_viewport*/ true,
+      /*synthetic_scroll*/ false, /*prevent_boosting*/ false));
 }
 
 void EventForwarder::StartFling(JNIEnv* env,
@@ -215,25 +217,31 @@
                                 jlong time_ms,
                                 jfloat velocity_x,
                                 jfloat velocity_y,
-                                jboolean synthetic_scroll) {
-  CancelFling(env, jobj, time_ms);
+                                jboolean synthetic_scroll,
+                                jboolean prevent_boosting) {
+  CancelFling(env, jobj, time_ms, prevent_boosting);
+
   if (velocity_x == 0 && velocity_y == 0)
     return;
   // Use velocity as delta in scroll event.
   view_->OnGestureEvent(GestureEventAndroid(
       GESTURE_EVENT_TYPE_SCROLL_START, gfx::PointF(), gfx::PointF(), time_ms, 0,
-      velocity_x, velocity_y, 0, 0, true, synthetic_scroll));
+      velocity_x, velocity_y, 0, 0, /*target_viewport*/ true, synthetic_scroll,
+      /*prevent_boosting*/ false));
   view_->OnGestureEvent(GestureEventAndroid(
       GESTURE_EVENT_TYPE_FLING_START, gfx::PointF(), gfx::PointF(), time_ms, 0,
-      0, 0, velocity_x, velocity_y, true, synthetic_scroll));
+      0, 0, velocity_x, velocity_y, /*target_viewport*/ true, synthetic_scroll,
+      /*prevent_boosting*/ false));
 }
 
 void EventForwarder::CancelFling(JNIEnv* env,
                                  const JavaParamRef<jobject>& jobj,
-                                 jlong time_ms) {
-  view_->OnGestureEvent(
-      GestureEventAndroid(GESTURE_EVENT_TYPE_FLING_CANCEL, gfx::PointF(),
-                          gfx::PointF(), time_ms, 0, 0, 0, 0, 0, false, false));
+                                 jlong time_ms,
+                                 jboolean prevent_boosting) {
+  view_->OnGestureEvent(GestureEventAndroid(
+      GESTURE_EVENT_TYPE_FLING_CANCEL, gfx::PointF(), gfx::PointF(), time_ms, 0,
+      0, 0, 0, 0,
+      /*target_viewport*/ false, /*synthetic_scroll*/ false, prevent_boosting));
 }
 
 }  // namespace ui
diff --git a/ui/android/event_forwarder.h b/ui/android/event_forwarder.h
index 64295be..18b75e7 100644
--- a/ui/android/event_forwarder.h
+++ b/ui/android/event_forwarder.h
@@ -118,11 +118,13 @@
                   jlong time_ms,
                   jfloat velocity_x,
                   jfloat velocity_y,
-                  jboolean synthetic_scroll);
+                  jboolean synthetic_scroll,
+                  jboolean prevent_boosting);
 
   void CancelFling(JNIEnv* env,
                    const base::android::JavaParamRef<jobject>& jobj,
-                   jlong time_ms);
+                   jlong time_ms,
+                   jboolean prevent_boosting);
 
  private:
   friend class ViewAndroid;
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
index c83d46b..d8fcfc3 100644
--- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
+++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -428,11 +428,16 @@
      * @param timeMs the current time.
      * @param velocityX fling speed in x-axis.
      * @param velocityY fling speed in y-axis.
-     * @param fromGamepad true if generated by gamepad (which will make this fixed-velocity fling)
+     * @param syntheticScroll true if generated by gamepad (which will make this fixed-velocity
+     * fling)
+     * @param preventBoost if false, this fling may boost an existing fling. Otherwise, ends the
+     * current fling and starts a new one.
      */
-    public void startFling(long timeMs, float velocityX, float velocityY, boolean syntheticScroll) {
+    public void startFling(long timeMs, float velocityX, float velocityY, boolean syntheticScroll,
+            boolean preventBoosting) {
         if (mNativeEventForwarder == 0) return;
-        nativeStartFling(mNativeEventForwarder, timeMs, velocityX, velocityY, syntheticScroll);
+        nativeStartFling(mNativeEventForwarder, timeMs, velocityX, velocityY, syntheticScroll,
+                preventBoosting);
     }
 
     /**
@@ -441,7 +446,7 @@
      */
     public void cancelFling(long timeMs) {
         if (mNativeEventForwarder == 0) return;
-        nativeCancelFling(mNativeEventForwarder, timeMs);
+        nativeCancelFling(mNativeEventForwarder, timeMs, /*preventBoosting*/ true);
     }
 
     private native WindowAndroid nativeGetJavaWindowAndroid(long nativeEventForwarder);
@@ -468,6 +473,7 @@
     private native void nativeScrollTo(long nativeEventForwarder, float x, float y);
     private native void nativeDoubleTap(long nativeEventForwarder, long timeMs, int x, int y);
     private native void nativeStartFling(long nativeEventForwarder, long timeMs, float velocityX,
-            float velocityY, boolean syntheticScroll);
-    private native void nativeCancelFling(long nativeEventForwarder, long timeMs);
+            float velocityY, boolean syntheticScroll, boolean preventBoosting);
+    private native void nativeCancelFling(
+            long nativeEventForwarder, long timeMs, boolean preventBoosting);
 }
diff --git a/ui/events/android/gesture_event_android.cc b/ui/events/android/gesture_event_android.cc
index 277efb5..fcd298d 100644
--- a/ui/events/android/gesture_event_android.cc
+++ b/ui/events/android/gesture_event_android.cc
@@ -18,7 +18,8 @@
                                          float velocity_x,
                                          float velocity_y,
                                          bool target_viewport,
-                                         bool synthetic_scroll)
+                                         bool synthetic_scroll,
+                                         bool prevent_boosting)
     : type_(type),
       location_(location),
       screen_location_(screen_location),
@@ -29,7 +30,8 @@
       velocity_x_(velocity_x),
       velocity_y_(velocity_y),
       target_viewport_(target_viewport),
-      synthetic_scroll_(synthetic_scroll) {}
+      synthetic_scroll_(synthetic_scroll),
+      prevent_boosting_(prevent_boosting) {}
 
 GestureEventAndroid::~GestureEventAndroid() {}
 
@@ -39,7 +41,8 @@
   gfx::PointF new_screen_location = screen_location_ + offset;
   return std::unique_ptr<GestureEventAndroid>(new GestureEventAndroid(
       type_, new_location, new_screen_location, time_ms_, scale_, delta_x_,
-      delta_y_, velocity_x_, velocity_y_, target_viewport_, synthetic_scroll_));
+      delta_y_, velocity_x_, velocity_y_, target_viewport_, synthetic_scroll_,
+      prevent_boosting_));
 }
 
 }  // namespace ui
diff --git a/ui/events/android/gesture_event_android.h b/ui/events/android/gesture_event_android.h
index 2824847a..4cad55f7 100644
--- a/ui/events/android/gesture_event_android.h
+++ b/ui/events/android/gesture_event_android.h
@@ -27,7 +27,8 @@
                       float velocity_x,
                       float velocity_y,
                       bool target_viewport,
-                      bool synthetic_scroll);
+                      bool synthetic_scroll,
+                      bool prevent_boosting);
 
   ~GestureEventAndroid();
 
@@ -42,6 +43,7 @@
   float velocity_y() const { return velocity_y_; }
   bool target_viewport() const { return target_viewport_; }
   bool synthetic_scroll() const { return synthetic_scroll_; }
+  bool prevent_boosting() const { return prevent_boosting_; }
 
   // Creates a new GestureEventAndroid instance different from |this| only by
   // its location.
@@ -62,6 +64,10 @@
   bool target_viewport_;
   bool synthetic_scroll_;
 
+  // Used by fling cancel. If true, this gesture will never attempt to boost an
+  // existing fling. It will immediately cancel an existing fling.
+  bool prevent_boosting_;
+
   DISALLOW_COPY_AND_ASSIGN(GestureEventAndroid);
 };
 
diff --git a/ui/events/blink/blink_event_util.cc b/ui/events/blink/blink_event_util.cc
index 93b03bbd..62536444 100644
--- a/ui/events/blink/blink_event_util.cc
+++ b/ui/events/blink/blink_event_util.cc
@@ -1244,7 +1244,7 @@
     web_event->data.fling_start.velocity_y = event.velocity_y();
     web_event->data.fling_start.target_viewport = event.target_viewport();
   } else if (event_type == WebInputEvent::kGestureFlingCancel) {
-    web_event->data.fling_cancel.prevent_boosting = true;
+    web_event->data.fling_cancel.prevent_boosting = event.prevent_boosting();
     if (event.synthetic_scroll())
       web_event->data.fling_cancel.target_viewport = true;
   } else if (event_type == WebInputEvent::kGestureDoubleTap) {
diff --git a/ui/file_manager/file_manager/background/js/drive_sync_handler.js b/ui/file_manager/file_manager/background/js/drive_sync_handler.js
index 423ab07..4269437 100644
--- a/ui/file_manager/file_manager/background/js/drive_sync_handler.js
+++ b/ui/file_manager/file_manager/background/js/drive_sync_handler.js
@@ -162,22 +162,30 @@
  */
 DriveSyncHandler.prototype.updateItem_ = function(status) {
   this.queue_.run(function(callback) {
-    this.item_.state = ProgressItemState.PROGRESSING;
-    this.item_.type = ProgressItemType.SYNC;
-    this.item_.quiet = true;
-    this.syncing_ = true;
-    if (status.num_total_jobs > 1) {
-      this.item_.message = strf('SYNC_FILE_NUMBER', status.num_total_jobs);
-    } else {
-      this.item_.message = strf(
-          'SYNC_FILE_NAME',
-          status.fileUrl.substr(status.fileUrl.lastIndexOf('/') + 1));
-    }
-    this.item_.cancelCallback = this.requestCancel_.bind(this);
-    this.item_.progressValue = status.processed || 0;
-    this.item_.progressMax = status.total || 0;
-    this.progressCenter_.updateItem(this.item_);
-    callback();
+    window.webkitResolveLocalFileSystemURL(
+        status.fileUrl,
+        function(entry) {
+          this.item_.state = ProgressItemState.PROGRESSING;
+          this.item_.type = ProgressItemType.SYNC;
+          this.item_.quiet = true;
+          this.syncing_ = true;
+          if (status.num_total_jobs > 1) {
+            this.item_.message =
+                strf('SYNC_FILE_NUMBER', status.num_total_jobs);
+          } else {
+            this.item_.message = strf('SYNC_FILE_NAME', entry.name);
+          }
+          this.item_.cancelCallback = this.requestCancel_.bind(this);
+          this.item_.progressValue = status.processed || 0;
+          this.item_.progressMax = status.total || 0;
+          this.progressCenter_.updateItem(this.item_);
+          callback();
+        }.bind(this),
+        function(error) {
+          console.warn(
+              'Resolving URL ' + status.fileUrl + ' is failed: ', error);
+          callback();
+        });
   }.bind(this));
 };
 
diff --git a/ui/file_manager/file_manager/background/js/mock_volume_manager.js b/ui/file_manager/file_manager/background/js/mock_volume_manager.js
index f4283bd..4cd4736 100644
--- a/ui/file_manager/file_manager/background/js/mock_volume_manager.js
+++ b/ui/file_manager/file_manager/background/js/mock_volume_manager.js
@@ -293,6 +293,9 @@
 MockVolumeManagerWrapper.createMockVolumeInfo =
     function(type, volumeId, label) {
   var fileSystem = new MockFileSystem(volumeId, 'filesystem:' + volumeId);
+
+  // If there's no label set it to volumeId to make shorter to write tests.
+  var label = label || volumeId;
   var volumeInfo = new VolumeInfoImpl(
       type, volumeId, fileSystem,
       '',                                          // error
diff --git a/ui/file_manager/file_manager/background/js/test_util.js b/ui/file_manager/file_manager/background/js/test_util.js
index 1962b0a37..bfec093 100644
--- a/ui/file_manager/file_manager/background/js/test_util.js
+++ b/ui/file_manager/file_manager/background/js/test_util.js
@@ -253,6 +253,31 @@
 };
 
 /**
+ * Fakes pressing the down arrow until the given |folderName| is selected in the
+ * navigation tree.
+ *
+ * @param {Window} contentWindow Window to be tested.
+ * @param {string} folderName Name of the folder to be selected.
+ * @return {boolean} True if file got selected, false otherwise.
+ */
+test.util.sync.selectTeamDrive = function(contentWindow, teamDriveName) {
+  // Select the 'Team Drives' root.
+  if (!test.util.sync.selectFolderInTree(contentWindow, 'Team Drives'))
+    return false;
+
+  // Expand the 'Team Drives' root.
+  if (!test.util.sync.expandSelectedFolderInTree(contentWindow))
+    return false;
+
+  // Select the team drive.
+  if (!test.util.sync.selectFolderInTree(contentWindow, teamDriveName))
+    return false;
+
+  return true;
+};
+
+
+/**
  * Obtains visible tree items.
  *
  * @param {Window} contentWindow Window to be tested.
diff --git a/ui/file_manager/file_manager/foreground/css/tree.css b/ui/file_manager/file_manager/foreground/css/tree.css
index a096307..e0f82eaa 100644
--- a/ui/file_manager/file_manager/foreground/css/tree.css
+++ b/ui/file_manager/file_manager/foreground/css/tree.css
@@ -36,6 +36,10 @@
       url(../images/files/ui/2x/expand_more_active.png) 2x);
 }
 
+div[section-start].tree-item {
+    border-top: 1px solid rgba(0, 0, 0, 0.10);
+}
+
 html[dir=rtl] .tree-row > .expand-icon {
   transform: rotate(90deg);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index 3894f6f..49e98d1 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -288,6 +288,28 @@
 };
 
 /**
+ * Returns whether all of the given entries have the given capability.
+ *
+ * @param {!Array<Entry>} entries List of entries to check capabilities for.
+ * @param {!string} capability Name of the capability to check for.
+ */
+CommandUtil.hasCapability = function(entries, capability) {
+  if (entries.length == 0) {
+    return false;
+  }
+
+  // Check if the capability is true or undefined, but not false. A capability
+  // can be undefined if the metadata is not fetched from the server yet (e.g.
+  // if we create a new file in offline mode), or if there is a problem with the
+  // cache and we don't have data yet. For this reason, we need to allow the
+  // functionality even if it's not set.
+  // TODO(crbug.com/849999): Store restrictions instead of capabilities.
+  var metadata = fileManager.metadataModel.getCache(entries, [capability]);
+  return metadata.length === entries.length &&
+      metadata.every(item => item[capability] !== false);
+};
+
+/**
  * Handle of the command events.
  * @param {!CommandHandlerDeps} fileManager Classes |CommandHalder| depends.
  * @param {!FileSelectionHandler} selectionHandler
@@ -695,14 +717,17 @@
       }
 
       var locationInfo = fileManager.volumeManager.getLocationInfo(entry);
-      event.canExecute = locationInfo && !locationInfo.isReadOnly;
+      event.canExecute = locationInfo && !locationInfo.isReadOnly &&
+          CommandUtil.hasCapability([entry], 'canAddChildren');
       event.command.setHidden(
           CommandUtil.isRootEntry(fileManager.volumeManager, entry));
     } else {
       var directoryModel = fileManager.directoryModel;
+      var directoryEntry = fileManager.getCurrentDirectoryEntry();
       event.canExecute = !fileManager.directoryModel.isReadOnly() &&
           !fileManager.namingController.isRenamingInProgress() &&
-          !directoryModel.isSearching() && !directoryModel.isScanning();
+          !directoryModel.isSearching() && !directoryModel.isScanning() &&
+          CommandUtil.hasCapability([directoryEntry], 'canAddChildren');
       event.command.setHidden(false);
     }
   };
@@ -930,19 +955,10 @@
         return;
       }
 
-      // Check if canDelete is true or undefined, but not false. canDelete can
-      // be undefined if the metadata is not fetched from the server yet (e.g.
-      // if we create a new file in offline mode), or if there is a problem with
-      // the cache and we don't have data on canDelete. For this reason, we need
-      // to allow deletion functionality even if it's not set.
-      // TODO(sashab): Re-work the capabilities model to store restrictions
-      // instead, see https://crbug.com/849999.
-      var metadata =
-          fileManager.metadataModel_.getCache(entries, ['canDelete']);
       event.canExecute = entries.length > 0 &&
           !this.containsReadOnlyEntry_(entries, fileManager) &&
           !fileManager.directoryModel.isReadOnly() &&
-          metadata.every(item => item.canDelete !== false);
+          CommandUtil.hasCapability(entries, 'canDelete');
       event.command.setHidden(false);
     },
 
@@ -1190,11 +1206,8 @@
     var locationInfo = parentEntry ?
         fileManager.volumeManager.getLocationInfo(parentEntry) : null;
     const volumeIsNotReadOnly = !!locationInfo && !locationInfo.isReadOnly;
-    // Check if canRename is true or undefined, but not false.
-    var metadata = fileManager.metadataModel_.getCache(entries, ['canRename']);
-    const canRenameAllItems = metadata.every(item => item.canRename !== false);
-    event.canExecute =
-        entries.length === 1 && volumeIsNotReadOnly && canRenameAllItems;
+    event.canExecute = entries.length === 1 && volumeIsNotReadOnly &&
+        CommandUtil.hasCapability(entries, 'canRename');
     event.command.setHidden(false);
   }
 });
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
index e4f8f74..53f2130 100644
--- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -703,7 +703,34 @@
       this.preparePaste(clipboardData, opt_destinationEntry, opt_effect);
 
   return util.URLsToEntries(pastePlan.sourceURLs).then(function(entriesResult) {
-    var sourceEntries = entriesResult.entries;
+    const sourceEntries = entriesResult.entries;
+    const destinationEntry = pastePlan.destinationEntry;
+    const destinationLocationInfo =
+        this.volumeManager_.getLocationInfo(destinationEntry);
+
+    const destinationIsOutsideOfDrive =
+        VolumeManagerCommon.getVolumeTypeFromRootType(
+            destinationLocationInfo.rootType) !==
+        VolumeManagerCommon.VolumeType.DRIVE;
+
+    // Disallow transferring hosted files from Team Drives to outside of Drive.
+    // This is because hosted files aren't 'real' files, so it doesn't make
+    // sense to allow a 'local' copy (e.g. in Downloads, or on a USB), where the
+    // file can't be accessed offline (or necessarily accessed at all) by the
+    // person who tries to open it.
+    // In future, block this for all hosted files, regardless of their source.
+    // For now, to maintain backwards-compatibility, just block this for hosted
+    // files stored in a Team Drive.
+    if (sourceEntries.some(
+            entry =>
+                util.isTeamDriveEntry(entry) && FileType.isHosted(entry)) &&
+        destinationIsOutsideOfDrive) {
+      // For now, just don't execute the paste.
+      // TODO(sashab): Display a warning message, and disallow drag-drop
+      // operations.
+      return null;
+    }
+
     if (sourceEntries.length == 0) {
       // This can happen when copied files were deleted before pasting them.
       // We execute the plan as-is, so as to share the post-copy logic.
@@ -1364,6 +1391,11 @@
       return false;
     }
 
+    // Cut is unavailable on Team Drive roots.
+    if (util.isTeamDriveRoot(selectedItem.entry)) {
+      return false;
+    }
+
     var metadata = this.metadataModel_.getCache(
         [selectedItem.entry], ['canCopy', 'canDelete']);
     assert(metadata.length === 1);
@@ -1441,7 +1473,7 @@
     return;
   }
   event.preventDefault();
-  this.paste(assert(event.clipboardData), destination).then(function(effect) {
+  this.paste(assert(event.clipboardData), destination).then(effect => {
     // On cut, we clear the clipboard after the file is pasted/moved so we don't
     // try to move/delete the original file again.
     if (effect === 'move') {
@@ -1450,7 +1482,7 @@
         event.clipboardData.setData('fs/clear', '');
       });
     }
-  }.bind(this));
+  });
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js
index 768591f..16379fe 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/file_system_metadata_provider.js
@@ -38,8 +38,7 @@
       item.present = true;
       item.availableOffline = true;
       return item;
-    }, function(error) {
-      console.error(error);
+    }, function() {
       return new MetadataItem();
     });
   }));
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.js
index 4fea770..89a1d37 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.js
@@ -12,9 +12,9 @@
 var ImageTransformation;
 
 /**
- * Metadata of a file.
+ * Metadata of a file. Doesn't have @struct to allow for '[]' computed property
+ * access.
  * @constructor
- * @struct
  */
 function MetadataItem() {
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
index e8abfba8..5eafa67 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
@@ -15,6 +15,24 @@
 };
 
 /**
+ * Navigation List sections. A section is just a visual grouping of some items.
+ *
+ * Sections:
+ *      - TOP: Recents, Shortcuts.
+ *      - MY_FILES: My Files (which includes Downloads, Crostini and Arc++ as
+ *                  its children).
+ *      - REMOVABLE: Archives, MTPs, Media Views and Removables.
+ *      - CLOUD: Drive and FSPs.
+ * @enum {string}
+ */
+var NavigationSection = {
+  TOP: 'top',
+  MY_FILES: 'my_files',
+  REMOVABLE: 'removable',
+  CLOUD: 'cloud',
+};
+
+/**
  * Base item of NavigationListModel. Should not be created directly.
  * @param {string} label
  * @param {NavigationModelItemType} type
@@ -24,11 +42,40 @@
 function NavigationModelItem(label, type) {
   this.label_ = label;
   this.type_ = type;
+
+  /**
+   * @type {NavigationSection} section which this item belongs to.
+   */
+  this.section_ = NavigationSection.TOP;
+
+  /** @type {number} original order when returned from VolumeManager. */
+  this.originalOrder_ = -1;
 }
 
 NavigationModelItem.prototype = /** @struct */ {
-  get label() { return this.label_; },
-  get type() { return this.type_; }
+  get label() {
+    return this.label_;
+  },
+  get type() {
+    return this.type_;
+  },
+
+  /** @type {NavigationSection} */
+  get section() {
+    return this.section_;
+  },
+  /** @param {NavigationSection} section */
+  set section(section) {
+    this.section_ = section;
+  },
+
+  /** @type {number} */
+  get originalOrder() {
+    return this.originalOrder_;
+  },
+  set originalOrder(order) {
+    this.originalOrder_ = order;
+  },
 };
 
 /**
@@ -431,6 +478,7 @@
   // of indexes, otherwise saves the index as int directly.
   for (let i = 0; i < volumeList.length; i++) {
     const volumeType = volumeList[i].volumeInfo.volumeType;
+    volumeList[i].originalOrder = i;
     switch (volumeType) {
       case VolumeManagerCommon.VolumeType.CROSTINI:
       case VolumeManagerCommon.VolumeType.DOWNLOADS:
@@ -492,6 +540,7 @@
     myFilesEntry.addEntry(new VolumeEntry(downloadsVolume.volumeInfo));
 
   this.navigationItems_.push(myFilesModel);
+  myFilesModel.section = NavigationSection.MY_FILES;
 
   const androidVolume =
       getSingleVolume(VolumeManagerCommon.VolumeType.ANDROID_FILES);
@@ -508,22 +557,32 @@
     myFilesEntry.addEntry(this.linuxFilesItem_.entry);
   }
 
-  // Join MEDIA_VIEW, MTP, ARCHIVE and REMOVABLE.
-  // TODO(lucmult) sort based on the index number to preserve original order.
-  const otherVolumes = [].concat(
-      getVolumes(VolumeManagerCommon.VolumeType.MEDIA_VIEW),
-      getVolumes(VolumeManagerCommon.VolumeType.REMOVABLE),
-      getVolumes(VolumeManagerCommon.VolumeType.ARCHIVE),
-      getVolumes(VolumeManagerCommon.VolumeType.MTP));
+  // Join MEDIA_VIEW, MTP, ARCHIVE and REMOVABLE. These types belong to same
+  // section.
+  const otherVolumes =
+      [].concat(
+            getVolumes(VolumeManagerCommon.VolumeType.MEDIA_VIEW),
+            getVolumes(VolumeManagerCommon.VolumeType.REMOVABLE),
+            getVolumes(VolumeManagerCommon.VolumeType.ARCHIVE),
+            getVolumes(VolumeManagerCommon.VolumeType.MTP))
+          .sort((volume1, volume2) => {
+            return volume1.originalOrder - volume2.originalOrder;
+          });
 
-  for (const volume of otherVolumes)
+  for (const volume of otherVolumes) {
     this.navigationItems_.push(volume);
+    volume.section = NavigationSection.REMOVABLE;
+  }
 
-  for (const driveItem of getVolumes(VolumeManagerCommon.VolumeType.DRIVE))
+  for (const driveItem of getVolumes(VolumeManagerCommon.VolumeType.DRIVE)) {
     this.navigationItems_.push(driveItem);
+    driveItem.section = NavigationSection.CLOUD;
+  }
 
-  for (const provided of getVolumes(VolumeManagerCommon.VolumeType.PROVIDED))
+  for (const provided of getVolumes(VolumeManagerCommon.VolumeType.PROVIDED)) {
     this.navigationItems_.push(provided);
+    provided.section = NavigationSection.CLOUD;
+  }
 
   if (this.addNewServicesItem_)
     this.navigationItems_.push(this.addNewServicesItem_);
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.html b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.html
index e0e191c89..9210e75 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.html
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.html
@@ -13,6 +13,7 @@
 <script src="../../../../../ui/webui/resources/js/cr/ui/array_data_model.js"></script>
 <script src="../../../../../ui/webui/resources/js/load_time_data.js"></script>
 
+<script src="../../common/js/files_app_entry_types.js"></script>
 <script src="../../common/js/volume_manager_common.js"></script>
 <script src="../../background/js/mock_volume_manager.js"></script>
 <script src="../../background/js/volume_info_impl.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
index 647f7cf..84d2b73 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model_unittest.js
@@ -158,3 +158,104 @@
   assertEquals('/root/shortcut', model.item(4).entry.fullPath);
   assertEquals('/shortcut2', model.item(5).entry.fullPath);
 }
+
+/**
+ * Checks that orderAndNestItems_ function does the following:
+ * 1. produces the expected order of volumes.
+ * 2. manages NavigationSection for the relevant volumes.
+ * 3. keeps MTP/Archive/Removable volumes on the original order.
+ */
+function testOrderAndNestItems() {
+  const volumeManager = new MockVolumeManagerWrapper();
+  const shortcutListModel = new MockFolderShortcutDataModel([
+    new MockFileEntry(drive, '/root/shortcut'),
+    new MockFileEntry(drive, '/root/shortcut2')
+  ]);
+  const recentItem = new NavigationModelFakeItem(
+      'recent-label', NavigationModelItemType.RECENT,
+      {toURL: () => 'fake-entry://recent'});
+  const addNewServicesItem = null;
+
+  // Create different volumes.
+  volumeManager.volumeInfoList.push(
+      MockVolumeManagerWrapper.createMockVolumeInfo(
+          VolumeManagerCommon.VolumeType.REMOVABLE, 'removable:hoge'));
+  volumeManager.volumeInfoList.push(
+      MockVolumeManagerWrapper.createMockVolumeInfo(
+          VolumeManagerCommon.VolumeType.PROVIDED, 'provided:prov1'));
+  volumeManager.volumeInfoList.push(
+      MockVolumeManagerWrapper.createMockVolumeInfo(
+          VolumeManagerCommon.VolumeType.ARCHIVE, 'archive:a-zip'));
+  volumeManager.volumeInfoList.push(
+      MockVolumeManagerWrapper.createMockVolumeInfo(
+          VolumeManagerCommon.VolumeType.REMOVABLE, 'removable:fuga'));
+  volumeManager.volumeInfoList.push(
+      MockVolumeManagerWrapper.createMockVolumeInfo(
+          VolumeManagerCommon.VolumeType.MTP, 'mtp:a-phone'));
+  volumeManager.volumeInfoList.push(
+      MockVolumeManagerWrapper.createMockVolumeInfo(
+          VolumeManagerCommon.VolumeType.PROVIDED, 'provided:prov2'));
+
+  // Navigation items built above:
+  //  1.  fake-entry://recent
+  //  2.  /root/shortcut
+  //  3.  /root/shortcut2
+  //  4.  My-Files
+  //        -> Downloads
+  //        -> Linux Files
+  //  5.  removable:hoge
+  //  6.  archive:a-zip
+  //  7.  removable:fuga
+  //  8.  mtp:a-phone
+  //  9.  Drive  - from setup()
+  // 10.  provided:prov1
+  // 11.  provided:prov2
+
+  // Constructor already calls orderAndNestItems_.
+  const model = new NavigationListModel(
+      volumeManager, shortcutListModel, recentItem, addNewServicesItem, true);
+
+  // Check items order and that MTP/Archive/Removable respect the original
+  // order.
+  assertEquals(11, model.length);
+  assertEquals('recent-label', model.item(0).label);
+  assertEquals('shortcut', model.item(1).label);
+  assertEquals('shortcut2', model.item(2).label);
+  assertEquals('My Files', model.item(3).label);
+  assertEquals('removable:hoge', model.item(4).label);
+  assertEquals('archive:a-zip', model.item(5).label);
+  assertEquals('removable:fuga', model.item(6).label);
+  assertEquals('mtp:a-phone', model.item(7).label);
+  assertEquals('My Drive', model.item(8).label);
+  assertEquals('provided:prov1', model.item(9).label);
+  assertEquals('provided:prov2', model.item(10).label);
+
+  // Check NavigationSection, which defaults to TOP.
+  // recent-label.
+  assertEquals(NavigationSection.TOP, model.item(0).section);
+  // shortcut.
+  assertEquals(NavigationSection.TOP, model.item(1).section);
+  // shortcut2.
+  assertEquals(NavigationSection.TOP, model.item(2).section);
+
+  // My Files.
+  assertEquals(NavigationSection.MY_FILES, model.item(3).section);
+
+  // MTP/Archive/Removable are grouped together.
+  // removable:hoge.
+  assertEquals(NavigationSection.REMOVABLE, model.item(4).section);
+  // archive:a-zip.
+  assertEquals(NavigationSection.REMOVABLE, model.item(5).section);
+  // removable:fuga.
+  assertEquals(NavigationSection.REMOVABLE, model.item(6).section);
+  // mtp:a-phone.
+  assertEquals(NavigationSection.REMOVABLE, model.item(7).section);
+
+  // Drive and FSP are grouped together.
+  // My Drive.
+  assertEquals(NavigationSection.CLOUD, model.item(8).section);
+  // provided:prov1.
+  assertEquals(NavigationSection.CLOUD, model.item(9).section);
+  // provided:prov2.
+  assertEquals(NavigationSection.CLOUD, model.item(10).section);
+}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
index 0f77164..3c169d1 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -1569,17 +1569,27 @@
   // Next, insert items which is in dataModel but not in current items.
   var modelIndex = 0;
   var itemIndex = 0;
+  // Starts with TOP_SECTION so first section doesn't get the separator line.
+  var previousSection = NavigationSection.TOP;
   while (modelIndex < this.dataModel.length) {
     if (itemIndex < this.items.length &&
         this.items[itemIndex].modelItem === this.dataModel.item(modelIndex)) {
+      var modelItem = this.items[itemIndex].modelItem;
+      if (previousSection !== modelItem.section)
+        this.items[itemIndex].setAttribute('section-start', previousSection);
+      previousSection = modelItem.section;
       if (recursive && this.items[itemIndex] instanceof VolumeItem)
         this.items[itemIndex].updateSubDirectories(true);
     } else {
       var modelItem = this.dataModel.item(modelIndex);
       if (modelItem) {
         var item = DirectoryTree.createDirectoryItem(modelItem, this);
-        if (item)
+        if (item) {
           this.addAt(item, itemIndex);
+          if (previousSection !== modelItem.section)
+            item.setAttribute('section-start', previousSection);
+        }
+        previousSection = modelItem.section;
       }
     }
     itemIndex++;
diff --git a/ui/file_manager/integration_tests/file_manager/background.js b/ui/file_manager/integration_tests/file_manager/background.js
index dc80bbe..0527f82 100644
--- a/ui/file_manager/integration_tests/file_manager/background.js
+++ b/ui/file_manager/integration_tests/file_manager/background.js
@@ -251,6 +251,7 @@
   ENTRIES.hello,
   ENTRIES.teamDriveA,
   ENTRIES.teamDriveAFile,
+  ENTRIES.teamDriveAHostedFile,
   ENTRIES.teamDriveB,
   ENTRIES.teamDriveBFile,
 ];
diff --git a/ui/file_manager/integration_tests/file_manager/context_menu.js b/ui/file_manager/integration_tests/file_manager/context_menu.js
index 0ff19db..f9719d1e 100644
--- a/ui/file_manager/integration_tests/file_manager/context_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/context_menu.js
@@ -330,6 +330,22 @@
 };
 
 /**
+ * Tests that the New Folder menu item is enabled if a read-write folder is
+ * selected.
+ */
+testcase.checkNewFolderEnabledForReadWriteFolder = function() {
+  checkContextMenu('new-folder', 'photos', true);
+};
+
+/**
+ * Tests that the New Folder menu item is disabled if a read-only folder is
+ * selected.
+ */
+testcase.checkNewFolderDisabledForReadOnlyFolder = function() {
+  checkContextMenu('new-folder', 'Read-Only Folder', false);
+};
+
+/**
  * Tests that text selection context menus are disabled in tablet mode.
  */
 testcase.checkContextMenusForInputElements = function() {
@@ -470,6 +486,22 @@
 }
 
 /**
+ * Tests that the New Folder menu item is enabled inside a folder that has
+ * read-write permissions.
+ */
+testcase.checkNewFolderEnabledInsideReadWriteFolder = function() {
+  checkContextMenuInDriveFolder('new-folder', 'photos', true);
+};
+
+/**
+ * Tests that the New Folder menu item is enabled inside a folder that has
+ * read-write permissions.
+ */
+testcase.checkNewFolderDisabledInsideReadOnlyFolder = function() {
+  checkContextMenuInDriveFolder('new-folder', 'Read-Only Folder', false);
+};
+
+/**
  * Tests that the Paste menu item is enabled inside a folder that has read-write
  * permissions.
  * TODO(sashab): Make this test only open one window, instead of two.
@@ -745,7 +777,7 @@
 testcase.checkContextMenuForTeamDriveRoot = function() {
   checkTeamDriveContextMenuInTree('Team Drive A', {
     'cut': false,
-    'copy': true,
+    'copy': false,
     'rename': false,
     'delete': false,
     'new-folder': true
diff --git a/ui/file_manager/integration_tests/file_manager/transfer.js b/ui/file_manager/integration_tests/file_manager/transfer.js
index ad3a46d..b699ee33 100644
--- a/ui/file_manager/integration_tests/file_manager/transfer.js
+++ b/ui/file_manager/integration_tests/file_manager/transfer.js
@@ -5,35 +5,107 @@
 'use strict';
 
 /**
+ * Info for the source or destination of a transfer.
+ * @struct
+ */
+class TransferLocationInfo {
+  /*
+   * Create a new TransferLocationInfo.
+   *
+   * @param{{
+         volumeName: !string,
+         isTeamDrive: boolean,
+         initialEntries: !Array<TestEntryInfo>
+     }} opts Options for creating TransferLocationInfo.
+   */
+  constructor(opts) {
+    /**
+     * The volume type (e.g. downloads, drive, drive_recent,
+     * drive_shared_with_me, drive_offline) or team drive name. This is used to
+     * select the volume with selectVolume() or the team drive with
+     * selectTeamDrive().
+     * @type {string}
+     */
+    this.volumeName = opts.volumeName;
+
+    /**
+     * Whether this transfer location is a team drive. Defaults to false.
+     * @type {boolean}
+     */
+    this.isTeamDrive = opts.isTeamDrive || false;
+
+    /**
+     * Expected initial contents in the volume.
+     * @type {Array<TestEntryInfo>}
+     */
+    this.initialEntries = opts.initialEntries;
+
+    /**
+     * Whether the test is expected to fail, i.e. transferring to a folder
+     * without correct permissions.
+     */
+    this.expectFailure = opts.expectFailure || false;
+  }
+}
+
+/**
  * Test function to copy from the specified source to the specified destination.
  * @param {TestEntryInfo} targetFile TestEntryInfo of target file to be copied.
- * @param {string} srcName Type of source volume. e.g. downloads, drive,
- *     drive_recent, drive_shared_with_me, drive_offline.
- * @param {Array<TestEntryInfo>} srcEntries Expected initial contents in the
- *     source volume.
- * @param {string} dstName Type of destination volume.
- * @param {Array<TestEntryInfo>} dstEntries Expected initial contents in the
- *     destination volume.
+ * @param {TransferLocationInfo} src The source of the transfer.
+ * @param {TransferLocationInfo} dst The destination of the transfer.
+ * @param {string|undefined} opt_dstExpectedDialogText The expected content of
+ *     the transfer dialog (including any buttons), or undefined if no dialog is
+ *     expected.
  */
-function copyBetweenVolumes(targetFile,
-                            srcName,
-                            srcEntries,
-                            dstName,
-                            dstEntries) {
-  var srcContents = TestEntryInfo.getExpectedRows(srcEntries).sort();
-  var dstContents = TestEntryInfo.getExpectedRows(dstEntries).sort();
+function copyBetweenVolumes(targetFile, src, dst, opt_dstExpectedDialogText) {
+  let appId;
 
-  var appId;
+  const localFiles = BASIC_LOCAL_ENTRY_SET;
+  const driveFiles = (src.isTeamDrive || dst.isTeamDrive) ?
+      TEAM_DRIVE_ENTRY_SET :
+      BASIC_DRIVE_ENTRY_SET;
+  let srcContents;
+  if (src.isTeamDrive) {
+    srcContents = TestEntryInfo
+                      .getExpectedRows(src.initialEntries.filter(
+                          entry => entry.type !== EntryType.TEAM_DRIVE &&
+                              entry.teamDriveName === src.volumeName))
+                      .sort();
+  } else {
+    srcContents = TestEntryInfo
+                      .getExpectedRows(src.initialEntries.filter(
+                          entry => entry.type !== EntryType.TEAM_DRIVE &&
+                              entry.teamDriveName === ''))
+                      .sort();
+  }
+
+  let dstContents;
+  if (dst.isTeamDrive) {
+    dstContents = TestEntryInfo
+                      .getExpectedRows(dst.initialEntries.filter(
+                          entry => entry.type !== EntryType.TEAM_DRIVE &&
+                              entry.teamDriveName === dst.volumeName))
+                      .sort();
+  } else {
+    dstContents = TestEntryInfo
+                      .getExpectedRows(dst.initialEntries.filter(
+                          entry => entry.type !== EntryType.TEAM_DRIVE &&
+                              entry.teamDriveName === ''))
+                      .sort();
+  }
+
   StepsRunner.run([
     // Set up File Manager.
     function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
+      setupAndWaitUntilReady(
+          null, RootPath.DOWNLOADS, this.next, localFiles, driveFiles);
     },
     // Select the source volume.
     function(results) {
       appId = results.windowId;
       remoteCall.callRemoteTestUtil(
-          'selectVolume', appId, [srcName], this.next);
+          src.isTeamDrive ? 'selectTeamDrive' : 'selectVolume', appId,
+          [src.volumeName], this.next);
     },
     // Wait for the expected files to appear in the file list.
     function(result) {
@@ -59,7 +131,8 @@
     function(result) {
       chrome.test.assertTrue(result);
       remoteCall.callRemoteTestUtil(
-          'selectVolume', appId, [dstName], this.next);
+          dst.isTeamDrive ? 'selectTeamDrive' : 'selectVolume', appId,
+          [dst.volumeName], this.next);
     },
     // Wait for the expected files to appear in the file list.
     function(result) {
@@ -70,25 +143,57 @@
     function() {
       remoteCall.callRemoteTestUtil('execCommand', appId, ['paste'], this.next);
     },
-    // Wait for the file list to change.
-    function(result) {
-      chrome.test.assertTrue(result);
-      var ignoreFileSize =
-          srcName == 'drive_shared_with_me' ||
-          srcName == 'drive_offline' ||
-          dstName == 'drive_shared_with_me' ||
-          dstName == 'drive_offline';
-      var dstContentsAfterPaste = dstContents.slice();
-      var pasteFile = targetFile.getExpectedRow();
-      for (var i = 0; i < dstContentsAfterPaste.length; i++) {
-        if (dstContentsAfterPaste[i][0] === pasteFile[0]) {
-          // Replace the last '.' in filename with ' (1).'.
-          // e.g. 'my.note.txt' -> 'my.note (1).txt'
-          pasteFile[0] = pasteFile[0].replace(/\.(?=[^\.]+$)/, ' (1).');
-          break;
-        }
+    // Wait for a dialog if one is expected, or just continue.
+    function() {
+      // If we're expecting a confirmation dialog, confirm that it is shown.
+      if (opt_dstExpectedDialogText !== undefined) {
+        return remoteCall.waitForElement(appId, '.cr-dialog-container.shown')
+            .then(this.next);
+      } else {
+        setTimeout(this.next, 0);
       }
-      dstContentsAfterPaste.push(pasteFile);
+    },
+    // Click OK if the dialog appears.
+    function(element) {
+      if (opt_dstExpectedDialogText !== undefined) {
+        chrome.test.assertEq(opt_dstExpectedDialogText, element.text);
+        // Press OK button.
+        remoteCall
+            .callRemoteTestUtil(
+                'fakeMouseClick', appId, ['button.cr-dialog-ok'])
+            .then(this.next);
+      } else {
+        setTimeout(this.next, 0);
+      }
+    },
+    // Wait for the file list to change, if the test is expected to pass.
+    function(result) {
+      if (opt_dstExpectedDialogText !== undefined) {
+        chrome.test.assertTrue(result);
+      }
+
+      const dstContentsAfterPaste = dstContents.slice();
+      var ignoreFileSize = src.volumeName == 'drive_shared_with_me' ||
+          src.volumeName == 'drive_offline' ||
+          dst.volumeName == 'drive_shared_with_me' ||
+          dst.volumeName == 'drive_offline';
+
+      // If we expected the transfer to succeed, add the pasted file to the list
+      // of expected rows.
+      if (!dst.expectFailure) {
+        var pasteFile = targetFile.getExpectedRow();
+        // Check if we need to add (1) to the filename, in the case of a
+        // duplicate file.
+        for (var i = 0; i < dstContentsAfterPaste.length; i++) {
+          if (dstContentsAfterPaste[i][0] === pasteFile[0]) {
+            // Replace the last '.' in filename with ' (1).'.
+            // e.g. 'my.note.txt' -> 'my.note (1).txt'
+            pasteFile[0] = pasteFile[0].replace(/\.(?=[^\.]+$)/, ' (1).');
+            break;
+          }
+        }
+        dstContentsAfterPaste.push(pasteFile);
+      }
       remoteCall.waitForFiles(appId, dstContentsAfterPaste, {
         ignoreFileSize: ignoreFileSize,
         ignoreLastModifiedTime: true
@@ -107,10 +212,10 @@
 testcase.transferFromDriveToDownloads = function() {
   copyBetweenVolumes(
       ENTRIES.hello,
-      'drive',
-      BASIC_DRIVE_ENTRY_SET,
-      'downloads',
-      BASIC_LOCAL_ENTRY_SET);
+      new TransferLocationInfo(
+          {volumeName: 'drive', initialEntries: BASIC_DRIVE_ENTRY_SET}),
+      new TransferLocationInfo(
+          {volumeName: 'downloads', initialEntries: BASIC_LOCAL_ENTRY_SET}));
 };
 
 /**
@@ -119,10 +224,10 @@
 testcase.transferFromDownloadsToDrive = function() {
   copyBetweenVolumes(
       ENTRIES.hello,
-      'downloads',
-      BASIC_LOCAL_ENTRY_SET,
-      'drive',
-      BASIC_DRIVE_ENTRY_SET);
+      new TransferLocationInfo(
+          {volumeName: 'downloads', initialEntries: BASIC_LOCAL_ENTRY_SET}),
+      new TransferLocationInfo(
+          {volumeName: 'drive', initialEntries: BASIC_DRIVE_ENTRY_SET}));
 };
 
 /**
@@ -130,11 +235,12 @@
  */
 testcase.transferFromSharedToDownloads = function() {
   copyBetweenVolumes(
-      ENTRIES.testSharedDocument,
-      'drive_shared_with_me',
-      SHARED_WITH_ME_ENTRY_SET,
-      'downloads',
-      BASIC_LOCAL_ENTRY_SET);
+      ENTRIES.testSharedDocument, new TransferLocationInfo({
+        volumeName: 'drive_shared_with_me',
+        initialEntries: SHARED_WITH_ME_ENTRY_SET
+      }),
+      new TransferLocationInfo(
+          {volumeName: 'downloads', initialEntries: BASIC_LOCAL_ENTRY_SET}));
 };
 
 /**
@@ -142,11 +248,12 @@
  */
 testcase.transferFromSharedToDrive = function() {
   copyBetweenVolumes(
-      ENTRIES.testSharedDocument,
-      'drive_shared_with_me',
-      SHARED_WITH_ME_ENTRY_SET,
-      'drive',
-      BASIC_DRIVE_ENTRY_SET);
+      ENTRIES.testSharedDocument, new TransferLocationInfo({
+        volumeName: 'drive_shared_with_me',
+        initialEntries: SHARED_WITH_ME_ENTRY_SET
+      }),
+      new TransferLocationInfo(
+          {volumeName: 'drive', initialEntries: BASIC_DRIVE_ENTRY_SET}));
 };
 
 /**
@@ -155,10 +262,10 @@
 testcase.transferFromOfflineToDownloads = function() {
   copyBetweenVolumes(
       ENTRIES.testDocument,
-      'drive_offline',
-      OFFLINE_ENTRY_SET,
-      'downloads',
-      BASIC_LOCAL_ENTRY_SET);
+      new TransferLocationInfo(
+          {volumeName: 'drive_offline', initialEntries: OFFLINE_ENTRY_SET}),
+      new TransferLocationInfo(
+          {volumeName: 'downloads', initialEntries: BASIC_LOCAL_ENTRY_SET}));
 };
 
 /**
@@ -167,8 +274,107 @@
 testcase.transferFromOfflineToDrive = function() {
   copyBetweenVolumes(
       ENTRIES.testDocument,
-      'drive_offline',
-      OFFLINE_ENTRY_SET,
-      'drive',
-      BASIC_DRIVE_ENTRY_SET);
+      new TransferLocationInfo(
+          {volumeName: 'drive_offline', initialEntries: OFFLINE_ENTRY_SET}),
+      new TransferLocationInfo(
+          {volumeName: 'drive', initialEntries: BASIC_DRIVE_ENTRY_SET}));
+};
+
+/**
+ * Tests copying from a Team Drive to Drive.
+ */
+testcase.transferFromTeamDriveToDrive = function() {
+  copyBetweenVolumes(
+      ENTRIES.teamDriveAFile, new TransferLocationInfo({
+        volumeName: 'Team Drive A',
+        isTeamDrive: true,
+        initialEntries: TEAM_DRIVE_ENTRY_SET
+      }),
+      new TransferLocationInfo(
+          {volumeName: 'drive', initialEntries: TEAM_DRIVE_ENTRY_SET}));
+};
+
+/**
+ * Tests copying from Drive to a Team Drive.
+ */
+testcase.transferFromDriveToTeamDrive = function() {
+  copyBetweenVolumes(
+      ENTRIES.hello,
+      new TransferLocationInfo(
+          {volumeName: 'drive', initialEntries: TEAM_DRIVE_ENTRY_SET}),
+      new TransferLocationInfo({
+        volumeName: 'Team Drive A',
+        isTeamDrive: true,
+        initialEntries: TEAM_DRIVE_ENTRY_SET
+      }),
+      'Members of \'Team Drive A\' will gain access to the copy of these ' +
+          'items.CopyCancel');
+};
+
+/**
+ * Tests copying from a Team Drive to Downloads.
+ */
+testcase.transferFromTeamDriveToDownloads = function() {
+  copyBetweenVolumes(
+      ENTRIES.teamDriveAFile, new TransferLocationInfo({
+        volumeName: 'Team Drive A',
+        isTeamDrive: true,
+        initialEntries: TEAM_DRIVE_ENTRY_SET
+      }),
+      new TransferLocationInfo(
+          {volumeName: 'downloads', initialEntries: BASIC_LOCAL_ENTRY_SET}));
+};
+
+/**
+ * Tests that a gdoc file cannot be transferred from a Team Drive to a local
+ * drive (e.g. Downloads).
+ */
+testcase.transferHostedFileFromTeamDriveToDownloads = function() {
+  copyBetweenVolumes(
+      ENTRIES.teamDriveAHostedFile, new TransferLocationInfo({
+        volumeName: 'Team Drive A',
+        isTeamDrive: true,
+        initialEntries: TEAM_DRIVE_ENTRY_SET
+      }),
+      new TransferLocationInfo({
+        volumeName: 'downloads',
+        initialEntries: BASIC_LOCAL_ENTRY_SET,
+        expectFailure: true
+      }));
+};
+
+/**
+ * Tests copying from Downloads to a Team Drive.
+ */
+testcase.transferFromDownloadsToTeamDrive = function() {
+  copyBetweenVolumes(
+      ENTRIES.hello,
+      new TransferLocationInfo(
+          {volumeName: 'downloads', initialEntries: BASIC_LOCAL_ENTRY_SET}),
+      new TransferLocationInfo({
+        volumeName: 'Team Drive A',
+        isTeamDrive: true,
+        initialEntries: TEAM_DRIVE_ENTRY_SET
+      }),
+      'Members of \'Team Drive A\' will gain access to the copy of these ' +
+          'items.CopyCancel');
+};
+
+/**
+ * Tests copying between two Team Drives.
+ */
+testcase.transferBetweenTeamDrives = function() {
+  copyBetweenVolumes(
+      ENTRIES.teamDriveBFile, new TransferLocationInfo({
+        volumeName: 'Team Drive B',
+        isTeamDrive: true,
+        initialEntries: TEAM_DRIVE_ENTRY_SET
+      }),
+      new TransferLocationInfo({
+        volumeName: 'Team Drive A',
+        isTeamDrive: true,
+        initialEntries: TEAM_DRIVE_ENTRY_SET
+      }),
+      'Members of \'Team Drive A\' will gain access to the copy of these ' +
+          'items.CopyCancel');
 };
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js
index 8ca94bd..a5d6a0e 100644
--- a/ui/file_manager/integration_tests/test_util.js
+++ b/ui/file_manager/integration_tests/test_util.js
@@ -560,6 +560,13 @@
   teamDriveA: new TestEntryInfo({
     type: EntryType.TEAM_DRIVE,
     teamDriveName: 'Team Drive A',
+    capabilities: {
+      canCopy: true,
+      canDelete: true,
+      canRename: true,
+      canAddChildren: true,
+      canShare: true,
+    },
   }),
 
   teamDriveAFile: new TestEntryInfo({
@@ -581,9 +588,27 @@
     },
   }),
 
+  teamDriveAHostedFile: new TestEntryInfo({
+    type: EntryType.FILE,
+    targetPath: 'teamDriveAHostedDoc',
+    mimeType: 'application/vnd.google-apps.document',
+    lastModifiedTime: 'Apr 10, 2013, 4:20 PM',
+    nameText: 'teamDriveAHostedDoc.gdoc',
+    sizeText: '--',
+    typeText: 'Google document',
+    teamDriveName: 'Team Drive A',
+  }),
+
   teamDriveB: new TestEntryInfo({
     type: EntryType.TEAM_DRIVE,
     teamDriveName: 'Team Drive B',
+    capabilities: {
+      canCopy: true,
+      canDelete: false,
+      canRename: false,
+      canAddChildren: false,
+      canShare: true,
+    },
   }),
 
   teamDriveBFile: new TestEntryInfo({
diff --git a/ui/views/mus/desktop_window_tree_host_mus.h b/ui/views/mus/desktop_window_tree_host_mus.h
index 81d5d7b..92d4e46 100644
--- a/ui/views/mus/desktop_window_tree_host_mus.h
+++ b/ui/views/mus/desktop_window_tree_host_mus.h
@@ -114,7 +114,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override {}
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 2958c9b..efc672b 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -870,7 +870,7 @@
     desktop_window_tree_host_->SetOpacity(opacity);
 }
 
-void DesktopNativeWidgetAura::SetAspectRatio(const gfx::Size& aspect_ratio) {
+void DesktopNativeWidgetAura::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
   if (content_window_)
     desktop_window_tree_host_->SetAspectRatio(aspect_ratio);
 }
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index c86f287b..40d5b1bf 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -164,7 +164,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::Size& aspect_ratio) override;
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
   void FlashFrame(bool flash_frame) override;
   void RunShellDrag(View* view,
                     const ui::OSExchangeData& data,
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host.h b/ui/views/widget/desktop_aura/desktop_window_tree_host.h
index 1dc3fcef..a6e2eca 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host.h
@@ -141,7 +141,7 @@
 
   virtual void SetOpacity(float opacity) = 0;
 
-  virtual void SetAspectRatio(const gfx::Size& aspect_ratio) = 0;
+  virtual void SetAspectRatio(const gfx::SizeF& aspect_ratio) = 0;
 
   virtual void SetWindowIcons(const gfx::ImageSkia& window_icon,
                               const gfx::ImageSkia& app_icon) = 0;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
index 085f24c3..cac4832 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
@@ -77,7 +77,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override {}
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 429e340..41c2ff3 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -447,7 +447,7 @@
   content_window()->layer()->SetOpacity(opacity);
 }
 
-void DesktopWindowTreeHostWin::SetAspectRatio(const gfx::Size& aspect_ratio) {
+void DesktopWindowTreeHostWin::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
   // TODO(apacible): Implement for Windows. https://crbug.com/853276.
 }
 
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 1eb03f1..022de40 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -110,7 +110,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::Size& aspect_ratio) override;
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 438e5968..fb9bfab 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -1070,7 +1070,7 @@
   }
 }
 
-void DesktopWindowTreeHostX11::SetAspectRatio(const gfx::Size& aspect_ratio) {
+void DesktopWindowTreeHostX11::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
   XSizeHints size_hints;
   size_hints.flags = 0;
   long supplied_return;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index 492c896..c5e6df7c 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -146,7 +146,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::Size& aspect_ratio) override;
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
   void SetWindowIcons(const gfx::ImageSkia& window_icon,
                       const gfx::ImageSkia& app_icon) override;
   void InitModalType(ui::ModalType modal_type) override;
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h
index 9472bea..9c97452 100644
--- a/ui/views/widget/native_widget_aura.h
+++ b/ui/views/widget/native_widget_aura.h
@@ -123,7 +123,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override {}
   void FlashFrame(bool flash_frame) override;
   void RunShellDrag(View* view,
                     const ui::OSExchangeData& data,
diff --git a/ui/views/widget/native_widget_mac.h b/ui/views/widget/native_widget_mac.h
index 7471cc4e..d515251a 100644
--- a/ui/views/widget/native_widget_mac.h
+++ b/ui/views/widget/native_widget_mac.h
@@ -116,7 +116,7 @@
   void SetFullscreen(bool fullscreen) override;
   bool IsFullscreen() const override;
   void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::Size& aspect_ratio) override {}
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
   void FlashFrame(bool flash_frame) override;
   void RunShellDrag(View* view,
                     const ui::OSExchangeData& data,
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm
index 611b53b62..fa90f8b 100644
--- a/ui/views/widget/native_widget_mac.mm
+++ b/ui/views/widget/native_widget_mac.mm
@@ -563,6 +563,11 @@
   [GetNativeWindow() setAlphaValue:opacity];
 }
 
+void NativeWidgetMac::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
+  [GetNativeWindow() setContentAspectRatio:NSMakeSize(aspect_ratio.width(),
+                                                      aspect_ratio.height())];
+}
+
 void NativeWidgetMac::FlashFrame(bool flash_frame) {
   NOTIMPLEMENTED();
 }
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h
index c12e7de..53c60d77 100644
--- a/ui/views/widget/native_widget_private.h
+++ b/ui/views/widget/native_widget_private.h
@@ -206,7 +206,7 @@
   virtual void SetFullscreen(bool fullscreen) = 0;
   virtual bool IsFullscreen() const = 0;
   virtual void SetOpacity(float opacity) = 0;
-  virtual void SetAspectRatio(const gfx::Size& aspect_ratio) = 0;
+  virtual void SetAspectRatio(const gfx::SizeF& aspect_ratio) = 0;
   virtual void FlashFrame(bool flash) = 0;
   virtual void RunShellDrag(View* view,
                             const ui::OSExchangeData& data,
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index adb90b9d..e4e7fc6 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -718,7 +718,7 @@
   native_widget_->SetOpacity(opacity);
 }
 
-void Widget::SetAspectRatio(const gfx::Size& aspect_ratio) {
+void Widget::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
   native_widget_->SetAspectRatio(aspect_ratio);
 }
 
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 07a095f..482ab92 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -544,9 +544,11 @@
   // underlying windowing system.
   void SetOpacity(float opacity);
 
-  // Sets the aspect ratio of the widget, which will be maintained during
-  // resizing.
-  void SetAspectRatio(const gfx::Size& aspect_ratio);
+  // Sets the aspect ratio of the widget's content, which will be maintained
+  // during interactive resizing. This size disregards title bar and borders.
+  // Once set, some platforms ensure the content will only size to integer
+  // multiples of |aspect_ratio|.
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio);
 
   // Flashes the frame of the window to draw attention to it. Currently only
   // implemented on Windows for non-Aura.